1
\$\begingroup\$

Question

I'm working on a side-scrolling game that has a 2D grid for rendering to the screen. I'm using OpenGL, and I've optimized my game so that nothing invisible is attempted to be drawn.

As of now, I create a grid based off of my game's window size. Each tile in the grid takes up 32x32 pixels. This grid is made up of square primitives, and each is drawn using an individual vertex buffer object. When the window is resized, the grid changes as well.

My games updating thread will constantly feed images into this grid, and this is what creates my game's scenery.

I've implemented a mechanism for user input to move this grid around (simulating character movement); however, I notice a visual artifacts of slightly slanted horizontal lines that flicker across the screen. They are about 20 pixels in height.

Example of the artifact:

Horizontal line artifact

In the image above, you can see the black line that crosses the entire image. This is the artifact I'm receiving.

I'm curious what are the possible causes for this type of visual artifact. My grid is constantly moving back and forth and reapplying the textures to each square during each iteration of my game loop (update thread). However, I see no reason why something like this would appear.

  • Does anyone have an idea what could be happening here?

  • Does anyone know how to minimize graphical artifacts in general?

I am using the fixed-function pipeline right now, so I bet that there would be a huge improvement after moving to using shaders. However, I'm not convinced that this alone will solve my problem.


Code Snippets

Originally I didn't want to share code, but I'll give some snippets of where all the interesting stuff is happening. For each snippet, I'll explain where it is used and how it connects to other snippets.

Grid Movement
The grid is moved by passing the movement amount to this function. The algorithm in here simply forces the grid location to wrap around a box that has the corners (-1, -1) and (0, 0). That way, emptiness is never seen around the grids border. I send the user input to this function. This function is called on my game's updating thread.

@Override
public void move(double x, double y) {
    //First, obtain only the integer parts of each coordinate.
    double moveX = (x%1);
    double moveY = (y%1);

    //Determine new location for the grid.
    double endX = (location.x + moveX);
    if(moveX >= 0) //Moving right
    {   if(endX >= 0) endX--; }
    else //Moving left
    {   if(endX < -1) endX++; }

    double endY = (location.y + moveY);
    if(moveY >= 0) //Moving right
    {   if(endY >= 0) endY--; }
    else //Moving left
    {   if(endY < -1) endY++; }

    location.x = endX;  //location stores the new coordinate for the grid (bottom-left)
    location.y = endY;
}

Grid Rendering
This function renders the grid by iterating through each square VBO that is inside of it. It applies the correct texture, translates the square, then draws it. This function is called on my games's rendering thread.

public void render(GL2 gl){
    for(int yIndex = 0; yIndex < NUM_BLOCKS_Y; yIndex++) {
        for(int xIndex = 0; xIndex < NUM_BLOCKS_X; xIndex++) {
            Square tmpSquare = squares.get(yIndex * NUM_BLOCKS_X + xIndex);
            tmpSquare.setTexture(blockIDs[xIndex][yIndex]);
            tmpSquare.moveTo(location.x + xIndex, location.y + yIndex);
            tmpSquare.render(gl);
        }
    }
}


Debug Notes

I also went ahead and did a couple test runs to see if I could find anything interesting. Here's what I learned:

  • First of all, the reason the line in the picture above is black is because that is what my glClearColor is set to. I changed the clear color, and that changed the artifact's color too.

  • Also, my rendering thread is separate from my updating thread. And the updating thread is fixed at a desired FPS. When I set to 50 FPS, in other words, 50 updates per second, and when I change the movement speed to be 50, 25, 12.5, or 6.25, the grid does not shift back and forth because it catches the edge of the box mentioned above. When I set the updater to 30 FPS, and the movement speed to 60, 30, 15, 7.5, or 3.75, the grid still does not change. Since the grid isn't bouncing back and forth, I don't receive the gap that appears in between the rows as before. NOTE: The jaggedness reappears when setting to half of 6.25 @ 50FPS, or half of 3.75 @ 50FPS; and the jaggedness appears when not moving by a 2^x * FPS.

It seems to me that when the movement speed is set so that the grid moves back and forth, not all of the square positions are moving fast enough.

\$\endgroup\$
  • \$\begingroup\$ this looks like some input parameters are incorrect or some easy miss some where. Could you show some of your render code? \$\endgroup\$ – Tordin Mar 20 '14 at 8:10
  • \$\begingroup\$ Hi, I added 2 code snippets (1 of updating, 1 of rendering) for the grid. I also ran some more tests and came up with some peculiar results. \$\endgroup\$ – Nick Miller Mar 20 '14 at 22:35
1
\$\begingroup\$

Solution

Well, the problem is that neither or the code snippets are synchronized. As mentioned before, I have two threads interacting with my grid: the updating/rendering threads. What appears to be the issue is that my rendering thread draws part of the grid (starting from the bottom-left). And then, the updater moves the grid while the grid is being drawn. After the grid is modified in the rendering thread completes the drawing, but at the new location. This causes the horizontal split to occur in the grid.

Corrected Functions

@Override
public synchronized void move(double x, double y) {
    //...
}

public synchronized void render(GL2 gl){
    //...
}

It makes sense that the movement of the grid never broke when using a movement speed of 2^x * FPS. This is because the grid location never ends up in the middle of the box with the corners (-1, -1) and (0, 0). While although the image is still not synchronized, it does not contain the horizontal line artifact.

\$\endgroup\$
0
\$\begingroup\$

Well with so few information on your computations, I'd say your polygon are badly shifted because you're not moving the viewport, but changing the coordinates at every view translation, which is painful. But do you ?

You need to debug here, to see the actual X,Y(,Z,W)coodinates of your vertices before rendering and then if they are wrong, to seek down the incriminating code and fix it.

\$\endgroup\$
  • \$\begingroup\$ I'm not moving the viewport at all, keeping it to always be (0, 0, window_width, window_height). My game will not be able to support viewport movement since the coordinates in the game are relative and never exceed +/-500 more or less. Sorry if I came out as if I hadn't already debugged haha ;), I guess I needed to learn more about my issue. PS: I've updated the original post to include code snippets and debug information. \$\endgroup\$ – Nick Miller Mar 20 '14 at 22:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.