c++openglgtkgdk

Same opngl texture2d become all black in GTK but works in glut


I have a program using OpenGL + GLUT that caputre image from camera and use it as a 2D texture. Then display a pointcloud with that texture in the window. It works fine when in GLUT window. But when I change to GTK opengl area. The pointcloud (or vertices) shows but it become all black. With only changing the window related code, What can possibly goes wrong?

The following is the code. I only post the code about texture because the whole code does work in GLUT. So I believe the code is correct. Maybe GTK need some additional setting?

Generate texture

  glGenTextures(1, &TEXTURE);
  glBindTexture(GL_TEXTURE_2D, TEXTURE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

Update texture content

    glBindTexture(GL_TEXTURE_2D, TEXTURE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, frame.get_width(), frame.get_height(), 0, GL_RGB, GL_UNSIGNED_BYTE, frame.get_data());

Update the vertice and it's texture coordinate

for (int i = 0; i < points.size(); i++)
{
    if (rsVertices[i].z)
    {
        vertices[count * 3] = rsVertices[i].x * 0.5f;
        vertices[count * 3 + 1] = rsVertices[i].y * -0.5f;
        vertices[count * 3 + 2] = rsVertices[i].z - 1.5f;
        textureCoord[count * 2] = rsTextureCoord[i].u;
        textureCoord[count * 2 + 1] = rsTextureCoord[i].v;
        count++;
    }
}
glBindBuffer(GL_ARRAY_BUFFER, VBO_VERTEX);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * count * 3, vertices, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);

glBindTexture(GL_TEXTURE_2D, TEXTURE);
glBindBuffer(GL_ARRAY_BUFFER, VBO_TEX);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * count * 2, textureCoord, GL_DYNAMIC_DRAW);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)0);

Vertex shader

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 2) in vec2 aTexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
out vec2 TexCoord;
void main()
{
    gl_Position = proj * view * model * vec4(aPos.x, aPos.y, aPos.z, 1.0);
    TexCoord = aTexCoord;
};

Fragment Shader

#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D ourTexture;
void main(){
    FragColor = texture(ourTexture, TexCoord);
}

Solution

  • Problem Solved. I update the texture in a different thread. So, every time before update texture buffer. gdk_gl_context_make_current() should be called. (Because GTK window is control by thirdparty's code. Maybe it change context somehow)

    gdk_gl_context_make_current(gdkContext);
    glBindTexture(GL_TEXTURE_2D, TEXTURE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, frame.get_width(), frame.get_height(), 0, GL_RGB, GL_UNSIGNED_BYTE, frame.get_data());