EDIT: SOLVED
I have a very simple app that simply loads in a B&W 24-bit bitmap into a texture. It’s a black grid with 1px white grid lines. However, the output image lines are grey (198,198,198), not white. Only the verticies are white.
Here is a zoomed in sample of the source:
[ATTACH=CONFIG]1256[/ATTACH]
From what I understand is that I should be sampling the texel centers by offsetting the UV mapping by half a pixel for both U and V for all 4 coordinates (using 1 Quad). If the window is 800x600, using a 800x600 source image, we should get the exact same image. What we actually see is grey lines:
[ATTACH=CONFIG]1257[/ATTACH]
I’d expect to see the exact same as the input image. I can post the full source, but here is the releavnt code:
...
window = glfwCreateWindow( 800, 600, "Demo", NULL, NULL );
...
glTexImage2D( GL_TEXTURE_2D, 0, GL_SRGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, ( GLvoid* )data ); // using FreeImage
...
int initializeScene( GLuint& vao )
{
int retVal = 1;
GLuint shaderProgram = 0;
GLuint vbo; // Vertex Buffer Object
GLuint eab; // Element Array Buffer
GLuint texture; // Texture we will display
// sampling is done at the center of a pixel, so shift the UV mapping by 1/2 pixel in X and Y to get correct
// pixel colors
GLfloat offset = 0.5f;
GLfloat pixelOffsetX = offset / 800;
GLfloat pixelOffsetY = offset / 600;
// 2 triangles representing a square, one top left one bottom right, sharing the -1,-1 and 1,1 vertices
GLfloat vertices_position[8] = {
-1.0f,-1.0f,
1.0f,-1.0f,
1.0f, 1.0f,
-1.0f, 1.0f,
};
GLfloat texture_coord[8] = {
0.0f + pixelOffsetX, 0.0f + pixelOffsetY,
1.0f + pixelOffsetX, 0.0f + pixelOffsetY,
1.0f + pixelOffsetX, 1.0f + pixelOffsetY,
0.0f + pixelOffsetX, 1.0f + pixelOffsetY,
};
// Index array so we don't repeat indicies, although currently we only use 1 quad
GLuint indices[6] = {
0, 1, 2,
0, 2, 3
};
glEnable( GL_FRAMEBUFFER_SRGB );
// Create a Vector Buffer Object that will store the vertices on video memory
glGenBuffers(1, &vbo);
// Buffer has vertex positions first, then texture coordinates
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices_position ) + sizeof( texture_coord ), NULL, GL_STATIC_DRAW );
// Transfer the vertex positions
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof( vertices_position ), vertices_position );
// Transfer the texture coordinates, which will sit in the VBO at the index after the last vertex position { i0, i1, ..., i8, t1, ..., t8 }
glBufferSubData( GL_ARRAY_BUFFER, sizeof( vertices_position ), sizeof( texture_coord ), texture_coord );
// Create an Element Array Buffer to store the array of indicies in
glGenBuffers( 1, &eab );
// Transfer the data from indices to eab
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, eab );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW );
// Create a texture
glGenTextures( 1, &texture );
// Specify that we work with a 2D texture
glBindTexture( GL_TEXTURE_2D, texture );
// load the texture
if( load_texture( "c:\\grid_800_600.bmp" ) == 0 )
{
// Create the shader program
shaderProgram = create_shaders("shaders/vertex.shader", "shaders/fragment.shader");
if( shaderProgram > 0 )
{
retVal = 0;
}
else
{
printf("Failed to create shaders
");
}
}
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// Did we create the shaders successfully?
if( retVal == 0 )
{
// Position attribute for the shader
GLint position_attribute = glGetAttribLocation( shaderProgram, "position" );
glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(position_attribute);
// Texture co-ordinate attribute for the shader
GLint texture_coord_attribute = glGetAttribLocation( shaderProgram, "texture_coord" );
glVertexAttribPointer( texture_coord_attribute, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid *)sizeof( vertices_position ) );
glEnableVertexAttribArray( texture_coord_attribute );
}
return retVal;
}
void displayScene( GLuint& vao )
{
glClear( GL_COLOR_BUFFER_BIT );
glBindVertexArray( vao );
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
Fragment Shader:
#version 150
in vec2 texture_coord_from_vshader;
out vec4 out_colour;
uniform sampler2D texture_sampler;
void main()
{
out_colour = texture( texture_sampler, texture_coord_from_vshader );
}
Vertex Shader:
#version 150
in vec4 position;
in vec2 texture_coord;
out vec2 texture_coord_from_vshader;
void main()
{
gl_Position = position;
texture_coord_from_vshader = texture_coord;
}