2012-06-05 145 views
0

我在OpenGL中遇到了一些麻煩,使渲染紋理示例工作。在初始化時,我生成了隨機值爲綠色和黑色的紋理「randtex」。如果我直接渲染這個紋理到窗口(映射到一個四邊形),它工作得很好。 這樣的: displaying texture directlyopengl渲染紋理只是看到一個黑色區域

但是,如果我使「randtex」到被連接到一個幀緩衝區對象,然後呈現在屏幕上的「特」只是給了我對FBO的藍色背景中的黑色圖像另一個紋理「TEX」並從我知道它應該給我在藍色背景的原始紋理。換句話說,這就是我正在得到的 black region should be the green and black texture

vertex shader for display only(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的錯誤之後:無效價值「,所以這實際上讓我更加困惑。

+1

爲什麼你設置你的投影和模型視圖矩陣,然後忽略它們在你的頂點着色器? – genpfault

+0

@genpfault是的我實際上錯過了矩陣操作,現在我已經添加了它們。儘管如此,問題仍然存在,我添加了截圖以獲得更好的解釋。 – labotsirc

回答

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

您不能給出紋理的ID,而是將紋理綁定到的槽。所以在你的情況下,這應該是

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

這是問題,那一行,真的非常感謝! :), – labotsirc