Texture data not used in fragment shader - OpenGL

I use textures in OpenGL, applying a simple texture defined as white colors per square. The code compiles and works fine, but the color of the square is just black, not white, as I indicated.

I think this is due to the fact that my fragment shader does not make the right choice, it, like the data that it returns from the texture function, is zero, so the texture of the square becomes black. The reason I suspect is that when I run the program, I can make a clear white color and move one of the vertices to a square to see the background (since it usually fills the entire surface). Then I can clearly see a white background with a black square on top. Thus, some output color is created from the fragment shader, it is simply incorrect, since the small pixel array that I provided has only white color. The problem is that I don’t know exactly why this will lead to incorrect results from the code that I have. I am trying to follow in a book that uses or less of the same code. I also tried to find it in different textbooks, but they all seem to use the same approach, so I'm stuck.

[EDIT]

I tracked some issues. By doing some error tracking with glGetError (), I realized that this line of my code:

glTexStorage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 4); 

returns error code 1282 (Invalid operation), due to the second level of the parameter being 0. If I set this value to 1, the error will disappear. Then the problem will be as follows:

 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_R, GL_FLOAT, myTexture); 

Which returns the same error, although it is not fixed by changing the level parameter.

This is the fragment and vertex shader that I use:

Fragment shader

 // FRAGMENT SHADER #version 330 uniform sampler2D tex; in vec2 vs_tex_coord; layout (location = 0) out vec4 outputColor; void main(void) { outputColor = texture(tex, vs_tex_coord); } 

Vertex Shader

 // VERTEX SHADER #version 330 layout(location = 0) in vec4 position; layout(location = 1) in vec2 in_tex_coord; uniform vec2 offset; out vec2 vs_tex_coord; void main(void) { vec4 finalOffset = vec4(offset.x, offset.y, 0.0, 0.0); gl_Position = position + finalOffset; vs_tex_coord = in_tex_coord; } 

The code I use to create and store texture objects is pretty simple:

 glGenTextures(1, &textureHandle); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureHandle); glTexStorage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 4); const GLubyte myTexture[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGB, GL_UNSIGNED_BYTE, myTexture); 

myTexture simply contains a 4x4 texture in internal RGB format with each component having 4 bits. I set them all to white.

Then I just generate a default sampler, for example:

 glGenSamplers(1, &mySampler); glBindSampler(0, mySampler); 

And finally, the render:

 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(theProgram); GLuint samplerLoc = glGetUniformLocation(theProgram, "tex"); if (samplerLoc == -1) printf("Location name could not be found...\n"); glUniform1i(samplerLoc, 0); glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(16 * sizeof(float))); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 

The array that I load in VBO:

 const float vertexPositions[] = { // Vertex position -0.8f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, // Texture coordinates 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; 

Is it because I am using sampler objects incorrectly? Do I need to set any settings before I can get it to work correctly? Skip any intermediate step?

For anyone interested, the visual result is as follows: enter image description here

You can see the white cleared background, with me purposefully moved one of the vertex positions so that you can see a black square on a white background.

+4
source share
1 answer

Ok, so after some bug tracking, I finally found a problem! :) For those who get into this problem in the future, here is a (very simple ... doh!) Solution.

First of all, this line is right here:

 glTexStorage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 4); 

The OpenGL error is returned in 1281 (Invalid Operation), because the second level of the parameters must be at least 1 in order to store enough memory for the base image, regardless of whether you want to use mipmaps or not (which I thought should be 0). Thus, changing it from 0 to 1 fixed it.

Secondly, this line:

 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_R, GL_FLOAT, myTexture); 

There was a problem with the format parameter, where it says GL_R in the above snippet. It was simply wrong. Looking at the official documentation for the function, she states this:

format Defines the format of the pixel data. The following symbolic values ​​are accepted: GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_DEPTH_COMPONENT and GL_STENCIL_INDEX.

The previous type specified in glTextStorage2D uses GL_RGB8, which has the basic internal format GL_RGB, this is the correct version:

 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGB, GL_UNSIGNED_BYTE, myTexture); 

Solving these two problems caused the appearance of a textured result :)

+4
source

Source: https://habr.com/ru/post/1496207/


All Articles