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:
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:
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
}
}