开发者

iPhone OGLES Game Of Life Plotting

开发者 https://www.devze.com 2023-01-07 02:45 出处:网络
I\'m developing an OpenGL-ES game of life program for the iPhone and I have an array that contains the boolean values of the entire grid, what I did for the array of the grid was:

I'm developing an OpenGL-ES game of life program for the iPhone and I have an array that contains the boolean values of the entire grid, what I did for the array of the grid was:

grid = (BOOL *)malloc(2*XSize*YSize*sizeof(BOOL));

and I want to know what would be a good way of plotting this linear array to the screen.

I've tried to create the Vertices array and then plot via glDrawArray but I can't seem to get it right so I was wondering if anyone else could help me. This is the method I'm trying right now that when rendered creates artifacts for some reason:

- (void)GridToVertices {
    int current = 0;

    for(int y=-backingHeight/2;y<backingHeight/2;y++) {
        for(int x=-backingWidth/2;x<backingWidth/2;x++) {
            Vertices[current] = x;
            Vertices[current+1] = y;
            current+=2;
        }
    }
}

And then rendering it like so:

- (void)render {
    [self GridToVertices];
    [self GridToColors];

    [EAGLContext setCurrentContext:context];

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    float Left = -backingWidth/2;
    float Right = backingWidth/2;
    float Up = -backingHeight/2;
    float Down = backingHeight/2;
    glOrthof(Left,开发者_JS百科 Right, Up, Down, -1.0f, 1.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glVertexPointer(2, GL_FLOAT, 0, Vertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, Colors);
    glEnableClientState(GL_COLOR_ARRAY);

    glDrawArrays(GL_POINTS, 0, [grid resolution]);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}


Actually, the correct fix in your case is either to change your call to glOrthof to:

glOrthof(Left-0.5f, Right-0.5f, Up-0.5f, Down-0.5f, -1.0f, 1.0f);

or leave your call to glOrthof in its original form and add a translation when you’re setting up your modelview matrix:

glTranslatef(0.5f, 0.5f, 0.0f);

The reason for this comes from the OpenGL ES rules for point rasterization, as described in section 3.3.1 of the specification, which states:

In the default state, a point is rasterized by truncating its xw and yw coordinates (recall that the subscripts indicate that these are x and y window coordinates) to integers. This (x, y) address, along with data derived from the data associated with the vertex corresponding to the point, is sent as a single fragment to the per-fragment stage of the GL.

The important thing to note is that the window coordinate of a point is the result of applying the modelview and projection matrices to the point’s position, then scaling by your viewport. In your case, this winds up multiplying your points’ x and y coordinates by the reciprocal of backingWidth and backingHeight, then by backingWidth and backingHeight again, which isn’t guaranteed to leave them exactly integral, because of floating-point rounding at various stages in the calculations.

To minimize any occurrences of rounding/truncation putting your points where you don’t expect, you want your point’s final window coordinates to land right on the center of a pixel. Remember that the pixel (x, y) in the framebuffer actually corresponds to a rectangle spanning (x, y) to (x+1, y+1), so you want to shift them by 0.5 in both x and y. Both snippets I posted do that, but in different ways. (You need only do one of them.)


I figured out what I did wrong...

glOrthof(Left, Right-1, Up, Down-1, -1.0f, 1.0f);

0

精彩评论

暂无评论...
验证码 换一张
取 消