tags:

views:

114

answers:

3

Hello!

At university we have introduction to OpenGL and it's first time I'm working with it. So far I have implemented simple thing like Sierpinski carpet and I noticed that most of (both fixed and floating point) calculations are performed on CPU. Does OpenGL provide some API, which can "forward" these calculations to GPU?

I know, that there are frameworks like OpenCL or CUDA but I wonder if OpenGL can use GPU for typical graphic calculations, like calculating coordinates.

+1  A: 

If you did this per pixel you would have to send the coordinates across the bus to the GPU, calculate the new coordinate, then send it back, then call the OpenGL commands to plot the point, etc.

With shaders you might be able to do the Sierpinski carpet but that fractal is very sequential (at least the typical way it's computed with averaging points after point). In other words, you would lose the parallel advantage that makes GPUs compelling.

Jared Updike
Don't you think the shader implementation I gave takes advantage of the parallelism of the GPU? Sure, some operations are done redundantly, but overall it seems like you could get a lot of parallel leverage out of it.
LarsH
@LarsH: great answer.
Jared Updike
@Jared: Thanks!
LarsH
+7  A: 

Does OpenGL provide some API, which can "forward" these calculations to GPU?

I would look at GLSL, OpenGL Shading Language.

Despite what @Jared said, I would think you could program the GPU to compute a Sierpinski carpet in parallel, at least up to a defined number of iterations. (It would be a fun project to try in WebGL.)

Edit: Here's a GPU implementation of a Sierpinski carpet, using WebGL, which is based on OpenGL ES 2.0 and uses GLSL for shader programming. An OpenGL implementation would be very similar if not identical.

#ifdef GL_ES
precision highp float;
#endif

uniform vec2 resolution;
uniform float time;
uniform sampler2D tex0;

// Sierpinski carpet
void main(void)
{
    ivec2 sectors;
    vec2 coordOrig = gl_FragCoord.xy / resolution.xy;
    int lim = 5;

    /* If you want it to spin, just to prove that it is redrawing
    the carpet every frame: */
    vec2 center = vec2(0.5, 0.5);
    mat2 rotation = mat2(
        vec2( cos(time), sin(time)),
        vec2(-sin(time), cos(time))
    );
    vec2 coordRot = rotation * (coordOrig - center) + center;
    vec2 coordIter = coordRot;

    for (int i=0; i < lim; i++) {
        sectors = ivec2(floor(coordIter.xy * 3.0));
        if (sectors.x == 1 && sectors.y == 1 ||
            // rotation can put us out of bounds
            sectors.x < 0 || sectors.x > 2 ||
            sectors.y < 0 || sectors.y > 2) {
            // make a hole
            gl_FragColor = vec4(texture2D(tex0, coordOrig).xyz, 1.0);

            return;
        } else {
            // map current sector to whole carpet
            coordIter.xy = coordIter.xy * 3.0 - vec2(sectors.xy);
        }
    }

    gl_FragColor = vec4(coordRot.x, 0.5, coordRot.y, 1.0);

}

To test this, go to Shader Toy using a WebGL-enabled browser, and paste the above code into the "Source" window. Hit Alt+Enter: Presto! On my laptop, which is no great shakes but does have a graphics accelerator card, it runs at 45-60 fps.

To get the background texture shown in the screenshot, I used this texture for Unit 0 under Inputs: http://www.iquilezles.org/apps/shadertoy/presets/tex3.jpg

As you can see, I set the lim (number of levels of iteration) to 5... at the resolution I was testing with, that was approaching sub-pixel precision.

Serpinski carpet

So the answer to your question, "I wonder if OpenGL can use GPU for typical graphic calculations, like calculating coordinates," is definitely yes. Technically, the above uses a pixel shader, which calculates color in order to produce the Sierpinski carpet. If you actually need to adjust coordinates of vertices, you would use a vertex shader. The process is similar.

LarsH
A: 

As other said, you need to use a shader. Beside GLSL, you can also use Cg.

VJo