1

I'm trying to render a checkerboard in OpenGL but I get and incorrect output. [checkerboard] http://s9.postimg.org/g3wk1py4f/large_checkerboard.png "large checkerboard"

I tried to narrow down the problem and I notices that when I try to draw a 11 by 11 grid i get only 10 pixels in vertical direction [small checkerboard] http://s12.postimg.org/olu7575jd/small_checkerboard.png "small checkerboard"

The texture itself is OK. I suspect problem is with vertex coordinates. Here's the code:

texture creation:

const int size = 11;

unsigned char buffer[size * size * 4];

for (size_t i = 0; i < size; i++)
{
    for (size_t j = 0; j < size; j++)
    {
        unsigned char rgb = i % 2 == 1 || j % 2 == 1 ? 255 : 0;
        int index = (i * size + j) * 4;
        buffer[index] = rgb;
        buffer[index + 1] = rgb;
        buffer[index + 2] = rgb;
        buffer[index + 3] = 255;
    }
}

texture parameters:

glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

vertices: (screen size is 1024 * 768, I'm drawing without any transformations at top right quarter)

float w = size / 512.0f;
float h = size / 384.0f;

GLfloat vertices[] =
{
     0.0f,    h, 0.0f, 1.0f,
     0.0f, 0.0f, 0.0f, 0.0f,
     w,       h, 1.0f, 1.0f,
     w,    0.0f, 1.0f, 0.0f
};

int positionLocation = glGetAttribLocation(program.getId(), "a_position");
int textureLocation = glGetAttribLocation(program.getId(), "a_texCoord");

glEnableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), vertices);

glEnableVertexAttribArray(textureLocation);
glVertexAttribPointer(textureLocation, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), vertices + 2);

glUniform1i(textureLocation, 0);

drawing:

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

and the shaders:

const char* VertexShaderCode =
    "attribute vec4 a_position; \n"
    "attribute vec2 a_texCoord; \n"
    "varying vec2 v_texCoord; \n"
    "void main() \n"
    "{ \n"
    " gl_Position = a_position; \n"
    " v_texCoord = a_texCoord; \n"
    "}";

const char* FragmentShaderCode =
    "uniform sampler2D s_texture; \n"
    "varying vec2 v_texCoord; \n"
    "void main() \n"
    "{ \n"
    " gl_FragColor = texture2D(s_texture, v_texCoord); \n"
    "}";
  • Also, you pass a `vec2` to `a_position` but it's declared as a `vec4` in the shader. Also, shouldn't a checker-pattern be `(i % 2 != j % 2 ) ? 255 : 0;`? – PeterT Jul 27 '13 at 10:24
  • It probably shouldn't be called checkerboard then. I'm just using this pattern to verify texture mapping. – James Rollinson Jul 27 '13 at 10:34
  • possible duplicate of [Perfect (3D) texture mapping in opengl](http://stackoverflow.com/questions/17422689/perfect-3d-texture-mapping-in-opengl) – Nicol Bolas Jul 27 '13 at 11:19
  • @NicolBolas It's not, his problem is not the tiling, it appears wrong but the problem he is trying to solve is that he's mapping a 11x11 texture and only getting a 11x10 texture displayed in the full UV range – PeterT Jul 27 '13 at 12:21

2 Answers2

1

This is a FAQ. It's been answered countless times (also by me) on StackOverflow. Here's one of those answers https://stackoverflow.com/a/17422950/524368

Essentially you're running into a fenceposting problem.

Community
  • 1
  • 1
datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Can you please elaborate? I saw similar posts but not quite sure how to relate texture mapping and vertex coordinate calculation. I cant figure out where to fix the issue. – James Rollinson Jul 27 '13 at 12:02
  • @JamesRollinson the error is not in the code you posted, I copied your code and added the usual boilerplate code. It looks just fine: [here](http://i.imgur.com/1FQqNjq.png) – PeterT Jul 27 '13 at 12:20
  • Indeed, the issue is with 11*10 size - please see comment from @NicolBolas – James Rollinson Jul 27 '13 at 12:28
  • @JamesRollinson [here](http://pastebin.com/JpLeDTcp) is your code with some boilerplate SFML but I'm sure you can easily replace it with whatever you use. – PeterT Jul 27 '13 at 13:03
  • I was able to narrow down the problem. Your code creates a window of 600*600 and draws a big rectangle. That's why probably you can't see the issue. I want to have a rectangle which is 11*11 pixels on screen. That's why i attempt to set float w = size / 512.0f; like this. But in addition I run my code without texturing and it has the same issue - I get only 11*10 rectangle! So the problem I suppose is because of resolution is 1024*768 and vertex coordinate is for some reason incorrect – James Rollinson Jul 27 '13 at 14:08
  • nope - making a 1024*1024 still produces only 10 vertical pixels. Just drawing a rectangle - no texturing. – James Rollinson Jul 27 '13 at 14:15
  • @JamesRollinson nope, that's not the problem, I set `w = size/width/2.0` and `h` respectively in my program and [this image](http://i.imgur.com/TS2wWNI.png) is the result. Pixel perfectly correct. It even works when I set the resolution to 1024x768 and adjust `h` and `w` respectively. Are you sure you set `glViewport(0,0,1024,768);`? – PeterT Jul 27 '13 at 14:48
  • Indeed, that was a Viewport problem! Thanks a lot! – James Rollinson Jul 27 '13 at 15:17
0

This was a bug in my code. Not related to OpenGL. I was passing width and height into CreateWindow instead of adjustedWidth and adjustedHeight. (which I calculated to take into account borders and menu bar)