Create and use floating point texture in OpenGL
c++, floating-point, opengl, textures
Solution
You are only allocating enough storage for 1/4 of your texture.
You need to use `float data[16][16][4]` and then assign each component of the texture a value of `0.5f`:
int width, height;
width = 16;
height = 16;
float data[16][16][4];
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
data[i][j][0] = 0.5f;
data[i][j][1] = 0.5f;
data[i][j][2] = 0.5f;
data[i][j][3] = 0.5f;
}
}
You are actually lucky that doing what you originally tried did not crash your software. You are/were forcing GL to overrun your allocated storage when it reads the texture image data.
Problem
I am trying to create floating point texture in OpenGL. I have 4 vertexes (2 polygons) forming square: ``` ------- |\ | | \ | | \| ------- ``` Now I want to create texture with float values, each value of texture to represent basic color intensity of each pixel. I want to calculate pixel color in fragment shader like this: ``` color = texture2D(texture, coordinates).r * vec4(0.4, 1.0, 0.8, 1.0); ``` vec4(0.4, 1.0, 0.8, 1.0) is just basic color I use When I prepare data like this: ``` int width, height; width = 16; height = 16; float data[16][16]; for(int i = 0; i < width; i++){ for(int j = 0; j < height; j++){ data[i][j] = 0.5f; } } GLuint n_tex_surface; glGenTextures(1, &n_tex_surface); glBindTexture(GL_TEXTURE_2D, n_tex_surface); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data); glGenerateMipmap(GL_TEXTURE_2D); ``` Edit: INIT ``` vertices[] = { 0, 1, -1, -1, 1, /**/1, 1, 1, -1, 1,/**/ 1, 0, 1, 1, 1,/**/ 0, 0, -1, 1, 1}; indices[] = { 0, 1, 2, 0, 2, 3}; glGenBuffers(1, &n_vertex_buffer_object); glBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer_object); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glGenBuffers(1, &n_index_buffer_object); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, n_index_buffer_object); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glGenVertexArrays(1, &n_vertex_array_object); glBindVertexArray(n_vertex_array_object); { glBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer_object); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), p_OffsetInVBO(0)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), p_OffsetInVBO(2 * sizeof(float))); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, n_index_buffer_object); } glBindVertexArray(0); ``` DRAW ``` glBindVertexArray(n_vertex_array_object); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, p_OffsetInVBO(0)); glBindVertexArray(0); ``` My result looks like this: instead of square with just one color intensity I got this mess. It seems like texture is too small and does not fit square. What size texture should be? And how do I found out? Am I creating texture the right way? With dimensions 128x128: With 64x64 I got this column, this is what I want, but why isnt it covering whole square? This is in OpenGL 3.3 on my computer. Could you help me? EDIT: When I replace my texture creation code with example from Addison Wesley OpenGL Programming Guide it works great, why not my code does not? ``` GLuint n_tex_surface; GLubyte checkImage[dataheight][datawidth][4]; int i, j, c; for (i = 0; i < dataheight; i++) { for (j = 0; j < datawidth; j++) { c = (((i&0x8)==0)^((j&0x8))==0)*255; checkImage[i][j][0] = (GLubyte) c; checkImage[i][j][1] = (GLubyte) c; checkImage[i][j][2] = (GLubyte) c; checkImage[i][j][3] = (GLubyte) 255; } } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, &n_tex_surface); glBindTexture(GL_TEXTURE_2D, n_tex_surface); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, datawidth, dataheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); ``` Edit: vertex shader ``` #version 330 in vec2 v_tex; in vec3 v_pos; uniform mat4 t_modelview_projection_matrix; out vec2 v_texcoord; void main() { gl_Position = t_modelview_projection_matrix * vec4(v_pos, 1.0); v_texcoord = v_tex; } ``` fragment shader ``` #version 330 in vec2 v_texcoord; out vec4 color; uniform sampler2D n_box_tex; void main() { frag_color = texture2D(n_box_tex, v_texcoord).r * vec4(0.4, 1.0, 0.8, 1.0); } ```