2

我很难获得要显示的屏幕外渲染纹理。我已经检查了网络和其他问题,显然遗漏了一些东西。

我是 OpenGL 的新手,所以很可能会犯一些幼稚的错误。这是使用着色器添加后期处理以将 firestor/secondlife viewer 项目修改为 equifisheye 投影的例程的一部分。我的测试代码基于使用 OpenGL 1.3 的 GLEW 和 GLUT 框架,因为查看器旨在在旧平台上运行。

方法是:

  1. 设置并初始化 FBO、渲染缓冲区和要绘制的纹理。
  2. 为绘制 glutCube 和 glutTeapot 初始化各种默认设置 :)
  3. 显示功能a)使用默认帧缓冲区绘制一个旋转立方体(工作正常)b)然后将纹理绘制到输出:全黑而不是旋转立方体。

我的代码是:

GLuint buffer_fbo;
GLuint bufferColtexture;
GLuint depthBuffer_rb;

typedef struct {
    int width;
int height;
char* title;

float field_of_view_angle;
float z_near;
float z_far;
} glutWindow;

glutWindow win;

// 

void ShutDown(void)
{
glDeleteFramebuffersEXT(1, &buffer_fbo);
glDeleteRenderbuffersEXT(1, &depthBuffer_rb);
glDeleteTextures(1,&bufferColtexture);
}

float g_potrotation = 0;
float g_potrotation_speed = 0.2f;

float xrot =0;
float yrot = 0;
float zrot = 0;


GLenum g_Drawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT };


void setupFBO(void)
{
// *********** set up scene FBO including dept buffers and their textures ****************

glGenFramebuffersEXT(1, &buffer_fbo);

// set up render buffers for depth info
glGenRenderbuffersEXT(1, &depthBuffer_rb);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer_rb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, win.width, win.height);


// Genrate texture to render to
glGenTextures(1, &bufferColtexture);
glBindTexture(GL_TEXTURE_2D, bufferColtexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  win.width, win.height, 0, GL_RGBA,   GL_UNSIGNED_BYTE, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);


// attach texture to render to to fbo 
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buffer_fbo); 
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, bufferColtexture, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer_rb);

GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // check frame buffer

if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
{
    printf("FRAMEBUFFER status error %i \n",status);
    exit(1);
}

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // bind back to default

}   

void initialise() 
{

setupFBO();

    // select projection matrix
    glMatrixMode(GL_PROJECTION);                                                

// set the viewport
glViewport(0, 0, win.width,  win.height);                                   

// set matrix mode
 glMatrixMode(GL_PROJECTION);                                               

// reset projection matrix
  glLoadIdentity();                                                         
GLfloat aspect = (GLfloat) win.width / win.height;

// set up a perspective projection matrix
gluPerspective(win.field_of_view_angle, aspect, win.z_near, win.z_far);     

// specify which matrix is the current matrix
     glMatrixMode(GL_MODELVIEW);                                                    
glShadeModel( GL_SMOOTH );

// specify the clear value for the depth buffer
glClearDepth( 1.0f );                                                       
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );

// specify implementation-specific hints
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );                        

GLfloat amb_light[] = { 0.1, 0.1, 0.1, 1.0 };
GLfloat diffuse[] = { 0.6, 0.6, 0.6, 1 };
GLfloat specular[] = { 0.7, 0.7, 0.3, 1 };
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, amb_light );
glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
glEnable( GL_LIGHT0 );
glEnable( GL_COLOR_MATERIAL );
glShadeModel( GL_SMOOTH );
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
glDepthFunc( GL_LEQUAL );
glEnable( GL_DEPTH_TEST );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0); 
glClearColor(0.5, 0.5, 0.5, 1.0);   

}


void drawquad(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The   Depth Buffer
 glDisable(GL_LIGHTING); // This was the cause of the problem, disable lighting worked!

glLoadIdentity();                                   // Reset The View
glTranslatef(0.0f,0.0f,-5.0f);
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);

glBindTexture(GL_TEXTURE_2D, bufferColtexture);

glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
glEnd();

xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;

glEnable(GL_LIGHTING); // now reenabling the lighting. after adding to fix code.


}

void display(void)
{

// set red background
// draw to fbo
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); 
// Clear Screen and Depth Buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);          
glEnable(GL_TEXTURE_2D);


// set drawing a rotating cube as per default
glLoadIdentity();

// Define a viewing transformation
gluLookAt( 3,1,0, 0,0,0, 0,1,0);                      

// Push and pop the current matrix stack. 
// This causes that translations and rotations on this matrix wont influence others.

glPushMatrix();                                     
glColor3f(0,1,0);
glTranslatef(0,0,0);                            
glRotatef(g_potrotation,0,1,0);
glRotatef(90,0,1,0);

// Draw the solid cube
glutSolidCube(1);
glPopMatrix();          


// draw teapot to fbo
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buffer_fbo);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,depthBuffer_rb);
// Clear Screen and Depth Buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);          
glLoadIdentity();

// Define a viewing transformation
gluLookAt( 4,2,0, 0,0,0, 0,1,0);                      


// Push and pop the current matrix stack. 
// This causes that translations and rotations on this matrix wont influence others.

glPushMatrix();                                     
glColor3f(1,0,0);
glTranslatef(0,0,0);                            
glRotatef(g_potrotation,0,1,0);
glRotatef(90,0,1,0);

// Draw the teapot
glutSolidTeapot(1);
glPopMatrix();                                        


g_potrotation += g_potrotation_speed;


glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); // reset to default Frame and Render buffer
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,0);

drawquad();


glutSwapBuffers();  


}


// informs OpenGL that window size has changed.
void reshape(int width, int height)
{

}

void idle(void)
{
    glutPostRedisplay();
}


int checkglewOK()
{
if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)
    printf("Ready for GLSL\n");
else {
    printf("Not totally ready :(  \n");
    exit(1);
};
}

void keyboard (unsigned char key, int mousePositionX, int mousePositionY)
{
switch (key)
{
    case KEY_ESCAPE:
        exit (0);
        break;

    default:
        break;
}
}

int main(int argc, char** argv)
{

// set window values
win.width = 640;
win.height = 480;
win.title = "Shader Test";
win.field_of_view_angle = 45;
win.z_near = 1.0f;
win.z_far = 500.0f;


////////////////////////////////////////////////////////
// Initialise and Create Window
////////////////////////////////////////////////////////
 glutInit(&argc, argv); 
 // set modes RGB-Alpha, doble bufferedd (prevent flickering)
 // has a depth buffer to ensure that 3D object overlp OK
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); // set display mode
 // define window size
 glutInitWindowSize(win.width, win.height);
 glutCreateWindow(win.title); // create the window
 glewInit(); // Glew Init occurs after Create Window !!!
 checkglewOK();
 glutDisplayFunc(display); // register display function
 //glutReshapeFunc(reshape); // register resize function
 glutIdleFunc(idle); // register idel function
 glutKeyboardFunc(keyboard);
 initialise();


glutMainLoop(); // run glut main loop

ShutDown();

return EXIT_SUCCESS;
}
4

0 回答 0