OpenGL / GLSL - Writing a Smart Texture Shader

Say my texture has a size of 256x256 pixels. It contains 16 sub-textures of 64x64 pixels. Sub-textures should be displayed in quads. To increase performance, I want to transfer discrete values ​​to a shader that encodes according to the coordinates of the vertex texture. For example, the values ​​0, 1, 2, 3 should correspond to (0.64), (64.64), (64.0), (0.0) by the coordinates of the vertex texture, etc.

Here is what I still have.

I load and bind the mipmap texture:

glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D,3,TextureImage[0]->w,TextureImage[0]->h,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->pixels); 

Then I upload my data:

 glGenVertexArrays(1, &VecArrObj); glBindVertexArray(VecArrObj); glGenBuffers(1, &VertexBO); glBindBuffer(GL_ARRAY_BUFFER, VertexBO); glBufferData(GL_ARRAY_BUFFER, sizeof(VertAndTex), VertAndTex, GL_STREAM_DRAW); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 3, GL_SHORT, GL_FALSE, 0, 0); glVertexAttribPointer(1, 1, GL_SHORT, GL_FALSE, 0, (void*)TexOffset); glGenBuffers(1, &IndexBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indx), Indx, GL_STREAM_DRAW); 

Here the attributes are pre-assigned to myProgram using glBindAttribLocation. This is how I show my squares:

 glUseProgram(myProgram); glBindVertexArray(VecArrObj); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_SHORT, 0); glBindVertexArray(0); glUseProgram(0); 

Now that the mipmap texture is constantly connected, it should be accessible from shaders. So far, my shaders looked like this.

Vertex shader:

 #version 130 in vec4 posit; //attr=0 in short textu; //attr=1 uniform mat4 trafoMat; void main() { gl_Position = trafoMat * posit; gl_TexCoord[0] = gl_MultiTexCoord0; } 

Fragment Shader:

 #version 130 uniform sampler2D tex; out vec4 outColor; void main() { outColor = texture2D(tex,gl_TexCoord[0].st); } 

If tex is set to zero. These shaders do not even acquire the entire texture, but only whole quatrains up to one color from the texture (I think this is the upper left corner of the pixel). Obviously, I don’t have much experience working with shaders. Basically, my question is: how do I change my shaders for the purposes described at the beginning? Please note: my equipment does not support glGenSamplers ()).

+4
source share
1 answer

First of all, if you are not using simple matching (i.e. f (x) β†’ (u, v), where f is some simple function), you must create an indirectness texture that performs the matching. In your case, it will be a 1D texture and will have 16 (two-component) records.

Secondly, you need to specify the pattern in the texture of indirection to find out where to get the pattern from the actual texture. Assuming your squares have 0..1 UV coordinates, the resulting shader will look something like this:

 // gl_TexCoord[0].st is 0..1, per quad void main () { gl_Position = trafoMat * posit; // 0..1 UV coordinate gl_TexCoord[0] = gl_MultiTexCoord0; // Rescale into sub-tile gl_TexCoord[0] *= (1/4.0); // Add the offset, if your hardware does not support // texture fetches in the vertex shader, move this into the // fragment shader. // gl_MultiTexCoord1 is the 1D offset into the indirection // texture gl_TexCoord[0] += texture2D(offsetTexture,gl_MultiTexCoord1); } // This is the fragment shader! void main () { outColor = texture2D(tex,gl_TexCoord[0]); } 

The tex texture should most likely be linearly filtered, and the offsetTexture point offsetTexture needed - you can set them manually without using samplers using glTexParameter .

+3
source

All Articles