opengl:渲染到纹理出错了

时间:2013-09-21 10:02:33

标签: opengl textures framebuffer fbo

我编写了一个用于测试使用帧缓冲渲染纹理的程序。在函数render_texture()中,我想在纹理上渲染一个三角形,但是当我在显示函数中显示渲染的纹理时,我只得到一个简单的黄色正方形。

#include "GL/glew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"

#include <cstdio>

uint16_t tex_width = 75;
uint16_t tex_height = 24;

GLuint texture;


int w1;
int h1;

void orthogonalStart (int w, int h) {
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0, w, 0, h);
    glScalef(1, -1, 1);
    glTranslatef(0, -h1, 0);
    glMatrixMode(GL_MODELVIEW);
}

void orthogonalEnd (void) {
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    orthogonalStart(w1, h1);

    glBegin(GL_QUADS);
    glTexCoord2f(0, 0); glVertex2f(125, 125);
    glTexCoord2f(0, 1); glVertex2f(125, 125+tex_height);
    glTexCoord2f(1, 1); glVertex2f(125+tex_width, 125+tex_height);
    glTexCoord2f(1, 0); glVertex2f(125+tex_width, 125);
    glEnd();

    orthogonalEnd();

    glutSwapBuffers();
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 1000.0);
    w1 = w;
    h1 = h;
    glMatrixMode (GL_MODELVIEW);
}

void render_texture()
{
   GLuint framebuffer = 0;

   glGenFramebuffers(1, &framebuffer);
   glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

   glGenTextures(1, &texture);

   glBindTexture(GL_TEXTURE_2D, texture);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA,
                GL_UNSIGNED_BYTE, 0);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
   GLenum draw_buffers[1] = {GL_COLOR_ATTACHMENT0};
   glDrawBuffers(1, draw_buffers);

   if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   {  
      fprintf(stderr, "[render_texture] Fehler im Framebuffer\n");
      exit(1);
   }

   glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
   glViewport(0, 0, tex_width, tex_height);

   glClearColor (0.0,0.0,0.0,1.0);

   orthogonalStart(tex_width, tex_height);

   glColor4f(1, 1, 0, 0);

   glBegin(GL_TRIANGLES);
   glVertex2f(0.f,0.f);
   glVertex2f(tex_width, 0.0f);
   glVertex2f(tex_width, (GLfloat)tex_height/2.f);
   //glVertex2f(tex_width-(GLfloat)tex_height/2.f, tex_height);
   //glVertex2f(0, tex_height);
   glEnd();

   orthogonalEnd();

   glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

int main (int argc, char **argv) {
   glutInit (&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
   glutInitWindowSize (500, 500);
   glutInitWindowPosition (100, 100);
   glutCreateWindow ("");
   glutDisplayFunc (display);
   glutIdleFunc (display);
   glutReshapeFunc (reshape);

   glewExperimental=true;
   GLenum err=glewInit();
   if(err!=GLEW_OK)
   {
      //Problem: glewInit failed, something is seriously wrong.
      fprintf(stderr, "glewInit failed, aborting.\n");
   }

   render_texture();

   glutMainLoop ();
   return 0;
}

编辑1:我已经更新了代码,现在我只有一个空白的黑屏

#include "GL/glew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"

#include <cstdio>

uint16_t tex_width = 75;
uint16_t tex_height = 24;

GLuint texture;

void orthogonalStart (int w, int h) {
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0, w, 0, h);
    glScalef(1, -1, 1);
    glTranslatef(0, -glutGet(GLUT_WINDOW_HEIGHT), 0);
    glMatrixMode(GL_MODELVIEW);
}

void orthogonalEnd (void) {
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT);
    glLoadIdentity();

    orthogonalStart(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));

    glColor3f(1,1,1);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);

    glBegin(GL_QUADS);
    glTexCoord2f(0, 0); glVertex2f(125, 125);
    glTexCoord2f(0, 1); glVertex2f(125, 125+tex_height);
    glTexCoord2f(1, 1); glVertex2f(125+tex_width, 125+tex_height);
    glTexCoord2f(1, 0); glVertex2f(125+tex_width, 125);
    glEnd();

    glDisable(GL_TEXTURE_2D);

    orthogonalEnd();

    glutSwapBuffers();
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 1000.0);
    glMatrixMode (GL_MODELVIEW);
}

void render_texture()
{
   GLuint framebuffer = 0;

   glGenFramebuffers(1, &framebuffer);
   glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

   glGenTextures(1, &texture);

   glBindTexture(GL_TEXTURE_2D, texture);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA,
                GL_UNSIGNED_BYTE, 0);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
   GLenum draw_buffers[1] = {GL_COLOR_ATTACHMENT0};
   glDrawBuffers(1, draw_buffers);

   if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   {  
      fprintf(stderr, "[render_texture] Fehler im Framebuffer\n");
      exit(1);
   }

   glViewport(0, 0, tex_width, tex_height);
   glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

   orthogonalStart(tex_width, tex_height);

   glColor4f(1, 1, 0, 0);

   glBegin(GL_TRIANGLES);
   glVertex2f(0.f,0.f);
   glVertex2f(tex_width, 0.0f);
   glVertex2f(tex_width, (GLfloat)tex_height/2.f);
   //glVertex2f(tex_width-(GLfloat)tex_height/2.f, tex_height);
   //glVertex2f(0, tex_height);
   glEnd();

   orthogonalEnd();

   glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

int main (int argc, char **argv) {
   glutInit (&argc, argv);
   glutInitContextVersion(3, 1);
   glutInitContextProfile(GLUT_CORE_PROFILE);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
   glutInitWindowSize (500, 500);
   glutCreateWindow ("");
   glutDisplayFunc (display);
   glutIdleFunc (display);
   glutReshapeFunc (reshape);

   glewExperimental=true;
   GLenum err=glewInit();
   if(err!=GLEW_OK)
   {
      //Problem: glewInit failed, something is seriously wrong.
      fprintf(stderr, "glewInit failed, aborting.\n");
   }

   //glEnable(GL_TEXTURE_2D);

   render_texture();

   glutMainLoop ();
   return 0;
}

1 个答案:

答案 0 :(得分:0)

您在设置投影矩阵时显然做错了什么。 我不确定你为什么要调用glScalef()和glTranslatef(),如果你在orthogonalStart()函数中注释掉这些行,你就会得到你的三角形。

void orthogonalStart (int w, int h) {
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0, w, 0, h);
    //glScalef(1, -1, 1);
    //glTranslatef(0, -glutGet(GLUT_WINDOW_HEIGHT), 0);
    glMatrixMode(GL_MODELVIEW);
}

在旁注中,不需要在render_texture()函数调用中第二次调用glBindFramebuffer(GL_FRAMEBUFFER,framebuffer)。

另外,我建议你开始学习顶点缓冲区来绘制你的对象,这些更精细here