c - opengl渲染到纹理只看到一个黑色区域

标签 c opengl glsl shader

我在 OpenGL 中遇到了一些麻烦,使渲染到纹理示例工作正常。在初始化时,我生成了一个带有随机值的绿色和黑色的纹理“randtex”。如果我将这个纹理直接渲染到窗口(映射到四边形),它就可以正常工作。 像这样: displaying texture directly

但是如果我将“randtex”渲染到附加到帧缓冲区对象的另一个纹理“tex”中,那么在屏幕上渲染“tex”只会给我 fbo 的蓝色背景上的黑色图像,据我所知它应该给我蓝色背景上的原始纹理。换句话说,这就是我得到的 black region should be the green and black texture

仅用于显示的顶点着色器 (display_shaderp)。

#version 420
in vec4 pos;
in vec2 tex_coord;
out vec2 vtex_coord;
uniform mat4 projection;
uniform mat4 modelview;
void main(){
gl_Position = projection * modelview * pos;
    vtex_coord = tex_coord;
}

仅用于显示的片段着色器 (display_shaderp)

#version 420
in vec2 vtex_coord;
uniform sampler2D tex;
out vec4 color;
void main(){
    color = texture2D(tex, vtex_coord);
    //color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}

着色器程序编译和链接正常,我没有出现 gl 错误,帧缓冲区也已完成且没有错误。 这是渲染代码:

glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, win_width, win_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (GLfloat)win_width / (GLfloat) win_height, 0.1f, 50.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslate3f(0.0f, 0.0f, -3.0f)

// render to texture
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0,0, win_width, win_height);
glClearColor(0.0, 0.0, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(fbo_shaderp);
GLfloat m_matrix[16], p_matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, m_matrix); 
glGetFloatv(GL_PROJECTION_MATRIX, p_matrix);
glUniformMatrix4fv(glGetUniformLocation(fbo_shaderp, "modelview"),1,GL_FALSE,m_matrix);
glUniformMatrix4fv(glGetUniformLocation(fbo_shaderp, "projection"),1,GL_FALSE,p_matrix);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, randtex);
glUniform1i(glGetUniformLocation(fbo_shaderp, "tex"), randtex);
GLuint _p = glGetAttribLocation(fbo_shaderp, "pos");
GLuint _t = glGetAttribLocation(fbo_shaderp, "tex_coord");
glVertexAttribPointer(_p, 3, GL_FLOAT,  GL_FALSE, 5 * sizeof(GLfloat), 0);
glVertexAttribPointer(_t, 2, GL_FLOAT,  GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(sizeof(float)*3));
glEnableVertexAttribArray(_p);
glEnableVertexAttribArray(_t);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
glUseProgram(0);    
glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // render to the window
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0,0, win_width, win_height);
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(display_shaderp);
glUniformMatrix4fv(glGetUniformLocation(display_shaderp,"modelview"),1,GL_FALSE,m_matrix);
glUniformMatrix4fv(glGetUniformLocation(display_shaderp,"projection"),1,GL_FALSE,p_matrix);
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, tex); 
glUniform1i(glGetUniformLocation(display_shaderp, "tex"), 0);
GLuint _p = glGetAttribLocation(display_shaderp, "pos");
GLuint _t = glGetAttribLocation(display_shaderp, "tex_coord");
glVertexAttribPointer ( _p, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0 );
glVertexAttribPointer ( _t, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*) (sizeof(float) * 3) );
glEnableVertexAttribArray(_p);
glEnableVertexAttribArray(_t);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
glUseProgram(0);

以及创建纹理和帧缓冲区的代码

int i = 0;
// create a random texture 'randtex'
glGenTextures(1, &randtex);
glBindTexture(GL_TEXTURE_2D, randtex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// random data
GLubyte* data = (GLubyte *) malloc(width*height*4*sizeof(GLubyte));
GLubyte val;
for (i = 0; i < width * height * 4; i+=4){
    if ((double)rand()/(double)RAND_MAX > 0.8)
        val = 255;
    else
        val = 0;
    data[i]   = 0;
    data[i+1] = val;
    data[i+2] = 0;
    data[i+3] = 255;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,GL_UNSIGNED_BYTE, data);
// create an empty texture 'tex'
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,GL_UNSIGNED_BYTE, 0);
// create framebuffer and attach 'tex'
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, tex, 0);
GLenum status;
if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE)
    fprintf(stderr, "glCheckFramebufferStatus: error %p", status);

渲染到纹理的着色器 (fbo_shaderp)

渲染到纹理顶点着色器

in vec4 pos;
in vec2 tex_coord;
out vec2 vtex_coord;
uniform mat4 projection;
uniform mat4 modelview;
void main(){
    gl_Position = projection * modelview * pos;
    vtex_coord = tex_coord;
}

渲染到纹理片段着色器

#version 420
in vec2 vtex_coord;
layout(location = 0) out vec4 color;
uniform sampler2D tex;

void main(){
color = texture2D(tex, vtex_coord);
//color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}

在最后一个着色器中,如果我使用注释行来绘制所有白色并注释掉 纹理一,我确实得到了一个白色图像,但在渲染到纹理“OpenGL 错误:无效值”后立即出现了 OpenGL 错误,所以这实际上让我更加困惑。

最佳答案

glUniform1i(glGetUniformLocation(fbo_shaderp, "tex"), randtex);

您不能提供纹理的 ID,而是您绑定(bind)纹理的插槽。所以在你的情况下,应该是

glUniform1i(glGetUniformLocation(fbo_shaderp, "tex"), 0);

关于c - opengl渲染到纹理只看到一个黑色区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10899623/

相关文章:

C 最低标准要求

c++ - 将数据从 std::vector 传递到 glsl 中的统一数组

c++ - GLSL 着色 : The entire screen is colored instead of just a quad

opengl旋转看不到背面

c++ - 全局变量的顺序会改变 C++/OpenGL 中的性能

java - OpenGL Z 索引问题?

c++ - 在可变大小的四边形上包装纹理坐标?

c - 读取报告 Bad File Descriptor 尽管 getc 成功使用相同的 fd 读取 char

c - 如何通过串口将整数发送到arduino?

c malloc 结构数组