2

I'm trying to process a 2D array in a fragment shader - so to learn that, I started building my array:

int const _s = 512;
std::array<GLubyte,_s*_s*4> hitmap;
for(unsigned j = 0; j < _s; j++) {
  for(unsigned i = 0; i < _s; i+=4) {
   hitmap[i+j*_s] = j%256;                  //R     
   if(j>33 && j < 45) hitmap[i+j*_s] = 0;   //R
   hitmap[i+j*_s+1] = i%256;                //G
   if(i>33 && i < 45) hitmap[i+j*_s+1] = 0; //G
   hitmap[i+j*_s+2] = 0;                    //B
   hitmap[i+j*_s+3] = 255;                  //A
  }
}

And as a first step, just push that as a texture and display that on a surface.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _s, _s, 0, GL_RGBA, GL_UNSIGNED_BYTE, hitmap.data());

I'm drawing two triangles with following coordinates to get a square:

    // positions           // texture coords
     1.f,  1.f, 0.0f,      1.0f, 1.0f, // top right
     1.f, -1.f, 0.0f,      1.0f, 0.0f, // bottom right
    -1.f, -1.f, 0.0f,      0.0f, 0.0f, // bottom left
    -1.f,  1.f, 0.0f,      0.0f, 1.0f  // top left 

And my fragment shader is pretty stupid:

#version 150 core
uniform sampler2D ourTexture;
out vec4 FragColor;
in vec2 TexCoord;
void main()
{
FragColor = texture(ourTexture, TexCoord);
};

(yes, I'm using a pretty old version here :/)

The result I get is the following:

Result

There is some weird stuff right at the top, and the texture seems to repeat (although, not mirrored). I seriously can't figure out what I'm doing wrong - it looks like I don't provide enough data. I expect to get a 2x2 square pattern, given I'm mapping 512 px into the range of 256 via mod divisions.

Edit: Like this:

Expected pattern

1 Answer 1

1

You've misunderstood the concept of GL_MIRRORED_REPEAT. See OpenGL wiki glTexParameter

GL_MIRRORED_REPEAT causes the s coordinate to be set to the fractional part of the texture coordinate if the integer part of s is even; if the integer part of s is odd, then the s texture coordinate is set to 1−frac(s), where frac(s) represents the fractional part of s.

This means that the texture is mirrored if the texture coordinates are in the range [1.0, 2.0], [3.0, 4.0], ...; If the texture coordinates are in range [0.0, 1.0], [2.0, 3.0], ... it will not be mirrored.
Since all of your texture coordinates are in the range [0.0, 1.0], nothing is mirrored at all.

Scale the the texture coordinates in the fragment shader to see the concept of GL_MIRRORED_REPEAT:

void main()
{
    FragColor = texture(ourTexture, TexCoord * 2.0);
};

There is also a mistake in the condition statement of the inner for-loop. The inner loop must run from 0 to _s*4 rather than form 0 to _s:

for(unsigned i = 0; i < _s; i+=4) {

for(unsigned i = 0; i < _s*4; i+=4) {

The size of a line in bytes is _s*4 and not _s:

int const _s = 512;
std::array<GLubyte,_s*_s*4> hitmap;
for(unsigned j = 0; j < _s; j++) {
    for(unsigned i = 0; i < _s*4; i+=4) {
        hitmap[i + j*_s*4] = j%256;                    //R     
        if(j>33 && j < 45) hitmap[i + j*_s*4] = 0;     //R
        hitmap[i + j*_s*4 + 1] = i%256;                //G
        if(i>33 && i < 45) hitmap[i + j*_s*4 + 1] = 0; //G
        hitmap[i + j*_s*4 + 2] = 0;                    //B
        hitmap[i + j*_s*4 + 3] = 255;                  //A
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for that clarification - but I'm still puzzled by the result I'm getting. I would expect to get a 2x2 "square" pattern, extending fully over the surface - w/o any repetition at all. But I do get a repeating pattern.
If I multiply the TexCoord*2.0 I get the texture mirrored in both directions - exactly what I would expect. I don't expect any mirroring in my initial example - the point which I don't understand is why my texture looks the way it looks. I'm building a 512x512 texture - and to scale that into a byte is just %256 (+a feature line). And I'm projecting that exactly once onto the whole surface. So why do I have this huge black area? (put a picture of what I'd expect as an edit into the post)
@user3895986 The size of a line in bytes is _s*4 and not _s. See the answer.
Thank you, yes, it was that indexing ... I feel very stupid now :)
@user3895986 I think you are not the first to make such a mistake (me too, for sure more than once). Thank you. You're welcome.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.