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

lab*_*irc 1 c opengl shader glsl

我在OpenGL中遇到了一些麻烦,使渲染到纹理示例工作.在初始化时,我生成一个纹理'randtex',其随机值为绿色和黑色.如果我将这个纹理直接渲染到窗口(映射到四边形),它可以很好地工作.像这样: 直接显示纹理

但是如果我将'randtex'渲染到附加到帧缓冲对象的另一个纹理'tex'中,那么在屏幕上渲染'tex'就会在fbo的蓝色背景上给我一个黑色图像,据我知道它应该给我在蓝色背景的原始纹理.换句话说,这就是我所得到的 黑色区域应该是绿色和黑色的纹理

顶点着色器仅用于显示(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;
}
Run Code Online (Sandbox Code Playgroud)

片段着色器仅供显示(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);
}
Run Code Online (Sandbox Code Playgroud)

着色器程序编译和链接确定,我没有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);
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

用于渲染到纹理的着色器(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;
}
Run Code Online (Sandbox Code Playgroud)

渲染到纹理片段着色器

#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);
}
Run Code Online (Sandbox Code Playgroud)

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

小智 6

glUniform1i(glGetUniformLocation(fbo_shaderp, "tex"), randtex);
Run Code Online (Sandbox Code Playgroud)

您不能提供纹理的ID,而是将纹理绑定到的槽.所以在你的情况下,那应该是

glUniform1i(glGetUniformLocation(fbo_shaderp, "tex"), 0);
Run Code Online (Sandbox Code Playgroud)