2011-09-06 9 views
5

Macでは、フレームバッファとテクスチャ作業などからうまく機能しているOpenGLセットアップがあります。私はフレームバッファを作成しようとするまで、すべてがうまく動作します。OpenGLフレームバッファ:それをクリアすることはできますが、描画することはできません

glGenFramebuffers、glBindFramebuffer、およびglFramebufferTexture2Dでフレームバッファを作成し、glCheckFramebufferStatusがGL_FRAMEBUFFER_COMPLETEを返しています。 glClearを呼び出してglGetTexImageを呼び出すと、返されたデータはglClearがフレームバッファにバインドされたテクスチャに作用したことを示します。私はglClearColorを必要なものに設定することができ、glClearはテクスチャデータを正しく設定します。

しかし、これは良いニュースが止まるところです。 VBOやglBegin/glEndのどちらを使っても、フレームバッファには何も描画できません。フレームバッファにバインドされたテクスチャからのテクスチャデータは、ドローコールによって変更されません(ただし、glClearの結果は引き続き表示されます)。 glGetTexImage呼び出しの前にglFlushとglFinishを呼び出す場合でも、これはすべて真です。また、glGetErrorは自分の呼び出しのエラーを返さない。

私は、この問題に取り組むために、プログラムの関連箇所に追加したサンプルコードをいくつか掲載しました。 (これにはglClearコールは含まれていませんが、別のテストでも同じことが分かります)。

glGenFramebuffers(1, &fb); 
glBindFramebuffer(GL_FRAMEBUFFER, fb); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbTexID, 0); 
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
if(status != GL_FRAMEBUFFER_COMPLETE) 
    Debugger(); 

glEnable(GL_TEXTURE_2D); 
glCullFace(GL_NONE); 
glGenTextures(1,(GLuint*)&tex); 
glBindTexture(GL_TEXTURE_2D,tex); 
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,1024,1024,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrtho(0, 1024, 1024, 0, -5000, 5000); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glViewport(0, 0, 1024, 1024); 
glColor4f(1,1,1,1); 
glBegin(GL_TRIANGLES); 
    glTexCoord2f(0, 0); 
    glVertex2f(0, 0); 
    glTexCoord2f(1, 0); 
    glVertex2f(1024, 0); 
    glTexCoord2f(0, 1); 
    glVertex2f(0, 1024); 
glEnd(); 
glFlush(); 
glFinish(); 
unsigned char *dd = new unsigned char[1024*1024*4]; 
glBindTexture(GL_TEXTURE_2D, fbTexID); //I've tried calling glBindFramebuffer(GL_FRAMEBUFFER,0) before this bind - makes no difference 
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, dd); 
delete dd; 
+0

'fbTexID'はどこで作成しますか? 'tex'はどこで使うのですか? – genpfault

+0

fbTexIDとtexの両方は、前に定義したGLuintsに過ぎません。 (私の実際のコードでは、それらはもっと大きな構造体のメンバーです;ここで私のポストでは単純さと明快さのために、より単純な名前に置き換えました)ありがとう – RedMarbleGames

+0

将来の読者のためだけであり、問題もある。 –

答えて

5

OK、自分の質問に答えました。の後に、フレームバッファが描画するサーフェスとして生成するテクスチャがに生成されている必要があります。

glGenFramebuffers... 
glBindFramebuffer... 
glGenTextures... 
glBindTexture... 
glTexParameterf etc. 
glFramebufferTexture2D... 

をが、これはしません::だから、これは動作します

glGenTextures... 
glBindTexture... 
glGenFramebuffers 
glBindFramebuffer... 
glFramebufferTexture2D... 

私は、これはどこにも対処表示されていない、それは意外なようだが、私のコードを移動することにより、単に作業に取り組んでいないから行ってきましたテクスチャの生成

1

これは私がいくつかの時間前に書いたFBOテストです:

#include <GL/glew.h> 
#include <GL/glut.h> 

#include <cmath> 
#include <iostream> 

using namespace std; 

namespace render 
{ 
    int width, height; 
    float aspect; 

    void init(); 
    void reshape(int width, int height); 
    void display(); 

    int const fbo_width = 512; 
    int const fbo_height = 512; 

    GLuint fb, color, depth; 
}; 

void idle(); 

int main(int argc, char *argv[]) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); 

    glutCreateWindow("FBO test"); 
    glutDisplayFunc(render::display); 
    glutReshapeFunc(render::reshape); 
    glutIdleFunc(idle); 

    glewInit(); 

    render::init(); 
    glutMainLoop(); 

    return 0; 
} 

void idle() 
{ 
    glutPostRedisplay(); 
} 

void CHECK_FRAMEBUFFER_STATUS() 
{               
    GLenum status; 
    status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); 
    switch(status) { 
    case GL_FRAMEBUFFER_COMPLETE: 
     break; 

    case GL_FRAMEBUFFER_UNSUPPORTED: 
    /* choose different formats */ 
     break; 

    default: 
     /* programming error; will fail on all hardware */ 
     throw "Framebuffer Error"; 
    } 
} 

namespace render 
{ 
    float const light_dir[]={1,1,1,0}; 
    float const light_color[]={1,0.95,0.9,1}; 

    void init() 
    { 
     glGenFramebuffers(1, &fb); 
     glGenTextures(1, &color); 
     glGenRenderbuffers(1, &depth); 

     glBindFramebuffer(GL_FRAMEBUFFER, fb); 

     glBindTexture(GL_TEXTURE_2D, color); 
     glTexImage2D( GL_TEXTURE_2D, 
       0, 
       GL_RGBA, 
       fbo_width, fbo_height, 
       0, 
       GL_RGBA, 
       GL_UNSIGNED_BYTE, 
       NULL); 

     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0); 

     glBindRenderbuffer(GL_RENDERBUFFER, depth); 
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbo_width, fbo_height); 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth); 

     CHECK_FRAMEBUFFER_STATUS(); 
    } 

    void reshape(int width, int height) 
    { 
     render::width=width; 
     render::height=height; 
     aspect=float(width)/float(height); 
     glutPostRedisplay(); 
    } 

    void prepare() 
    { 
     static float a=0, b=0, c=0; 

     glBindTexture(GL_TEXTURE_2D, 0); 
     glEnable(GL_TEXTURE_2D); 
     glBindFramebuffer(GL_FRAMEBUFFER, fb); 

     glViewport(0,0,fbo_width, fbo_height); 

     glClearColor(1,1,1,0); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     gluPerspective(45, 1, 1, 10); 

     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 

     glEnable(GL_LIGHT0); 
     glEnable(GL_LIGHTING); 

     glEnable(GL_DEPTH_TEST); 
     glDisable(GL_CULL_FACE); 

     glLightfv(GL_LIGHT0, GL_POSITION, light_dir); 
     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color); 

     glTranslatef(0,0,-5); 

     glRotatef(a, 1, 0, 0); 
     glRotatef(b, 0, 1, 0); 
     glRotatef(c, 0, 0, 1); 

     glutSolidTeapot(0.75); 

     a=fmod(a+0.1, 360.); 
     b=fmod(b+0.5, 360.); 
     c=fmod(c+0.25, 360.); 
    } 

    void final() 
    { 
     static float a=0, b=0, c=0; 

     glBindFramebuffer(GL_FRAMEBUFFER, 0); 

     glViewport(0,0, width, height); 

     glClearColor(1.,1.,1.,0.); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     gluPerspective(45, aspect, 1, 10); 

     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 
     glTranslatef(0,0,-5); 

     glRotatef(b, 0, 1, 0); 

     b=fmod(b+0.5, 360.); 

     glEnable(GL_TEXTURE_2D); 
     glBindTexture(GL_TEXTURE_2D, color); 

     glEnable(GL_DEPTH_TEST); 
     glEnable(GL_CULL_FACE); 

     glEnable(GL_BLEND); 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

     glDisable(GL_LIGHTING); 

     float cube[][5]= 
     { 
      {-1, -1, -1, 0, 0}, 
      { 1, -1, -1, 1, 0}, 
      { 1, 1, -1, 1, 1}, 
      {-1, 1, -1, 0, 1}, 

      {-1, -1, 1, -1, 0}, 
      { 1, -1, 1, 0, 0}, 
      { 1, 1, 1, 0, 1}, 
      {-1, 1, 1, -1, 1}, 
     }; 
     unsigned int faces[]= 
     { 
      0, 1, 2, 3, 
      1, 5, 6, 2, 
      5, 4, 7, 6, 
      4, 0, 3, 7, 
      3, 2, 6, 7, 
      4, 5, 1, 0 
     }; 

     glEnableClientState(GL_VERTEX_ARRAY); 
     glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

     glVertexPointer(3, GL_FLOAT, 5*sizeof(float), &cube[0][0]); 
     glTexCoordPointer(2, GL_FLOAT, 5*sizeof(float), &cube[0][3]); 

     glCullFace(GL_BACK); 
     glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, faces); 

     glCullFace(GL_FRONT); 
     glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, faces); 

     glDisableClientState(GL_VERTEX_ARRAY); 
     glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    } 

    void display() 
    { 
     prepare(); 
     final(); 

     glutSwapBuffers(); 
    } 
} 

を多分このリファレンスは

0

は、ここで私はwhile agoを書いたFBO "ベンチマーク" だのに役立ちます。 set_fbo_size()には、Works For Me(TM)の作成シーケンスがあります。

///////////////////////////////////////////////////////////////////////////// 
// INCLUDES ///////////////////////////////////////////////////////////////// 

#include <GL/glew.h> 
#include <GL/glut.h> 

#include <iostream> 
#include <iomanip> 
#include <sstream> 

using namespace std; 


///////////////////////////////////////////////////////////////////////////// 
// CLASSES ////////////////////////////////////////////////////////////////// 

// http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average 
class ExpAvg 
{ 
public: 
    ExpAvg(float initial, unsigned int time_periods) : avg(initial), alpha(2.0f/(time_periods + 1)) {} 
    void Update(float nextval) { avg = alpha*nextval + (1.0f-alpha)*avg; } 
    float Get() { return avg; } 
private: 
    float avg; 
    float alpha; 
}; 

class gl2D 
{ 
public: 
    gl2D() { 
     int viewport[4]; 
     glGetIntegerv(GL_VIEWPORT, viewport); 
     glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); 
     gluOrtho2D(0, viewport[2], 0, viewport[3]); 
     glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); 
    } 
    ~gl2D() { 
     glMatrixMode(GL_PROJECTION); glPopMatrix(); 
     glMatrixMode(GL_MODELVIEW); glPopMatrix(); 
    } 
}; 


///////////////////////////////////////////////////////////////////////////// 
// GLOBALS ////////////////////////////////////////////////////////////////// 

int screen_width = 1024; 
int screen_height = 768; 
int mouse_x, mouse_y; 
bool mouse_left, mouse_right; 
float camera_angle_x = 45; 
float camera_angle_y = 45; 
float camera_distance = 0; 

int texture_width, texture_height; 
GLuint tex, fbo, rbo; // object IDs 


///////////////////////////////////////////////////////////////////////////// 
// UTILITIES //////////////////////////////////////////////////////////////// 

bool get_fbo_status() 
{ 
    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 
    switch(status) { 
    case GL_FRAMEBUFFER_COMPLETE_EXT: 
     cout << "Framebuffer complete." << endl; return true; 
    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: 
     cerr << "[ERROR] Attachment is NOT complete." << endl; return false; 
    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: 
     cerr << "[ERROR] No image is attached to FBO." << endl; return false; 
    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: 
     cerr << "[ERROR] Attached images have different dimensions." << endl; return false; 
    case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: 
     cerr << "[ERROR] Color attached images have different internal formats." << endl; return false; 
    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: 
     cerr << "[ERROR] Draw buffer." << endl; return false; 
    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: 
     cerr << "[ERROR] Read buffer." << endl; return false; 
    case GL_FRAMEBUFFER_UNSUPPORTED_EXT: 
     cerr << "[ERROR] Unsupported by FBO implementation." << endl; return false; 
    default: 
     cerr << "[ERROR] Unknow error." << endl; return false; 
    } 
} 

void gl_print(const char *str, int x, int y, void *font) 
{ 
    glPushAttrib(GL_ENABLE_BIT); 
    glDisable(GL_LIGHTING);  // need to disable lighting for proper text color 
    glDisable(GL_TEXTURE_2D); 
    glRasterPos2i(x, y);  // place text position 
    while(*str) glutBitmapCharacter(font, *str++); 
    glPopAttrib(); 
} 

void textured_cube() 
{ 
    glBegin(GL_QUADS); 
    glColor4f(1, 1, 1, 1); 

    // face v0-v1-v2-v3 
    glNormal3f(0,0,1); 
    glTexCoord2f(1, 1); glVertex3f(1,1,1); 
    glTexCoord2f(0, 1); glVertex3f(-1,1,1); 
    glTexCoord2f(0, 0); glVertex3f(-1,-1,1); 
    glTexCoord2f(1, 0); glVertex3f(1,-1,1); 

    // face v0-v3-v4-v5 
    glNormal3f(1,0,0); 
    glTexCoord2f(0, 1); glVertex3f(1,1,1); 
    glTexCoord2f(0, 0); glVertex3f(1,-1,1); 
    glTexCoord2f(1, 0); glVertex3f(1,-1,-1); 
    glTexCoord2f(1, 1); glVertex3f(1,1,-1); 

    // face v0-v5-v6-v1 
    glNormal3f(0,1,0); 
    glTexCoord2f(1, 0); glVertex3f(1,1,1); 
    glTexCoord2f(1, 1); glVertex3f(1,1,-1); 
    glTexCoord2f(0, 1); glVertex3f(-1,1,-1); 
    glTexCoord2f(0, 0); glVertex3f(-1,1,1); 

    // face v1-v6-v7-v2 
    glNormal3f(-1,0,0); 
    glTexCoord2f(1, 1); glVertex3f(-1,1,1); 
    glTexCoord2f(0, 1); glVertex3f(-1,1,-1); 
    glTexCoord2f(0, 0); glVertex3f(-1,-1,-1); 
    glTexCoord2f(1, 0); glVertex3f(-1,-1,1); 

    // face v7-v4-v3-v2 
    glNormal3f(0,-1,0); 
    glTexCoord2f(0, 0); glVertex3f(-1,-1,-1); 
    glTexCoord2f(1, 0); glVertex3f(1,-1,-1); 
    glTexCoord2f(1, 1); glVertex3f(1,-1,1); 
    glTexCoord2f(0, 1); glVertex3f(-1,-1,1); 

    // face v4-v7-v6-v5 
    glNormal3f(0,0,-1); 
    glTexCoord2f(0, 0); glVertex3f(1,-1,-1); 
    glTexCoord2f(1, 0); glVertex3f(-1,-1,-1); 
    glTexCoord2f(1, 1); glVertex3f(-1,1,-1); 
    glTexCoord2f(0, 1); glVertex3f(1,1,-1); 
    glEnd(); 
} 

bool set_fbo_size(int width, int height) 
{ 
    int max_size; 
    glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size); 
    if(width > max_size) return false; 
    if(height > max_size) return false; 

    texture_width = width; texture_height = height; 

    // create FBO 
    if(fbo) glDeleteFramebuffersEXT(1, &fbo); 
    glGenFramebuffersEXT(1, &fbo); 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);  

    // create and attach a new texture as the FBO's color buffer 
    if(tex) glDeleteTextures(1, &tex); 
    glGenTextures(1, &tex); 
    glBindTexture(GL_TEXTURE_2D, tex); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0); 

    // create and attach a new depth buffer to currently bound FBO 
    if(rbo) glDeleteRenderbuffersEXT(1, &rbo); 
    glGenRenderbuffersEXT(1, &rbo); 
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo); 
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); 
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo); 

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // unbind fbo 
    if(!get_fbo_status()) exit(1); 
    return true; 
} 


///////////////////////////////////////////////////////////////////////////// 
// GLUT CALLBACKS /////////////////////////////////////////////////////////// 

void CB_Idle() 
{ 
    glutPostRedisplay(); 
} 

void CB_Reshape(int width, int height) 
{ 
    screen_width = width; 
    screen_height = height; 
    glViewport(0, 0, (GLsizei)width, (GLsizei)height); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(60.0f, (float)(width)/height, 1.0f, 1000.0f); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

void CB_Mouse(int button, int state, int x, int y) 
{ 
    mouse_x = x; mouse_y = y; 
    if(button == GLUT_LEFT_BUTTON) 
     mouse_left = (state == GLUT_DOWN); 
    else if(button == GLUT_RIGHT_BUTTON) 
     mouse_right = (state == GLUT_DOWN); 
} 

void CB_Motion(int x, int y) 
{ 
    if(mouse_left) { 
     camera_angle_y += (x - mouse_x); 
     camera_angle_x += (y - mouse_y); 
     mouse_x = x; mouse_y = y; 
    } 
    if(mouse_right) { 
     camera_distance += (y - mouse_y) * 0.2f; 
     mouse_y = y; 
    } 
} 

void CB_Keyboard(unsigned char key, int x, int y) 
{ 
    static int drawMode = 0; 
    static int tex_size = 0; 
    bool ret = false; 

    switch(key) { 
    case 27: // ESCAPE 
     exit(0); 
     break; 
    case ' ': 
     while(!ret) { 
      tex_size = (tex_size+1) % 7; 
      switch(tex_size) { 
       case 0: ret = set_fbo_size(128,128); break; 
       case 1: ret = set_fbo_size(256,256); break; 
       case 2: ret = set_fbo_size(512,512); break; 
       case 3: ret = set_fbo_size(1024,1024); break; 
       case 4: ret = set_fbo_size(2048,2048); break; 
       case 5: ret = set_fbo_size(4096,4096); break; 
       case 6: ret = set_fbo_size(8192,8192); break; 
       default: ; break; 
      } 
     } 
     break; 
    default: 
     break; 
    } 
    glutPostRedisplay(); 
} 

void CB_Init() 
{ 
    GLenum err = glewInit(); 
    if(GLEW_OK != err) { 
     cerr << "Error: " << glewGetErrorString(err) << endl; 
     exit(1); 
    } 

    if(!GLEW_EXT_framebuffer_object) { 
     cerr << "Requires EXT_framebuffer_object" << endl; 
     exit(1); 
    } 

    tex = fbo = rbo = 0; 

    glShadeModel(GL_SMOOTH); 
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 
    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_LIGHTING); 
    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_CULL_FACE); 

    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); 
    glEnable(GL_COLOR_MATERIAL); 
    glClearColor(0, 0, 0, 0); 

    GLfloat lightKa[] = {.2f, .2f, .2f, 1.0f}; // ambient light 
    GLfloat lightKd[] = {.7f, .7f, .7f, 1.0f}; // diffuse light 
    GLfloat lightKs[] = {1, 1, 1, 1};   // specular light 
    glLightfv(GL_LIGHT0, GL_AMBIENT, lightKa); 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightKd); 
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightKs); 
    float lightPos[4] = {0, 0, 20, 1};   // positional light 
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos); 
    glEnable(GL_LIGHT0); 

    set_fbo_size(128, 128); 
} 

void CB_Exit() 
{ 
    glDeleteTextures(1, &tex); 
    glDeleteFramebuffersEXT(1, &fbo); 
    glDeleteRenderbuffersEXT(1, &rbo); 
} 

void CB_Display() 
{ 
    static ExpAvg ft_fbo(0, 19); 
    static ExpAvg ft_overall(0, 19); 

    int before = glutGet(GLUT_ELAPSED_TIME); 

    // compute rotation angle 
    const float ANGLE_SPEED = 90; // degree/s 
    float angle = ANGLE_SPEED * (glutGet(GLUT_ELAPSED_TIME)/1000.0f); 

    // render using fbo ///////////////////////////////////////////// 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // bind fbo 

    // adjust viewport and projection matrix to texture dimension 
    glViewport(0, 0, texture_width, texture_height); 
    glMatrixMode(GL_PROJECTION); glLoadIdentity(); 
    gluPerspective(60.0f, (float)(texture_width)/texture_height, 1.0f, 100.0f); 
    glMatrixMode(GL_MODELVIEW); glLoadIdentity(); 

    // clear buffer 
    glClearColor(1, 1, 1, 0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glTranslatef(0,0,-3); 
    glPushMatrix(); 
    glRotatef(angle*0.5f, 1, 0, 0); 
    glRotatef(angle, 0, 1, 0); 
    glRotatef(angle*0.7f, 0, 0, 1); 

    // set up teapot colors 
    float shininess = 15.0f; 
    float diffuseColor[3] = {0.929524f, 0.796542f, 0.178823f}; 
    float specularColor[4] = {1.00000f, 0.980392f, 0.549020f, 1.0f}; 
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess); // range 0 ~ 128 
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularColor); 
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); 
    glColor3fv(diffuseColor); 

    glBindTexture(GL_TEXTURE_2D, 0); 
    glFrontFace(GL_CW); 
    glutSolidTeapot(1.0); 
    glFrontFace(GL_CCW); 
    glPopMatrix(); 

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // unbind fbo 
    glFinish(); 

    ft_fbo.Update((float)(glutGet(GLUT_ELAPSED_TIME) - before)); 

    // normal rendering /////////////////////////////////// 

    // back to normal viewport and projection matrix 
    glViewport(0, 0, screen_width, screen_height); 
    glMatrixMode(GL_PROJECTION); glLoadIdentity(); 
    gluPerspective(60.0f, (float)(screen_width)/screen_height, 1.0f, 100.0f); 
    glMatrixMode(GL_MODELVIEW); glLoadIdentity(); 

    glClearColor(0, 0, 0, 0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glTranslatef(0,0,-4); 
    glPushMatrix(); 
    glTranslatef(0, 0, camera_distance); 
    glRotatef(camera_angle_x, 1, 0, 0); 
    glRotatef(camera_angle_y, 0, 1, 0); 

    // draw a cube with the dynamic texture 
    glBindTexture(GL_TEXTURE_2D, tex); 
    textured_cube();  
    glPopMatrix(); 

    { 
     gl2D two_dee; // set 2D mode 
     glDisable(GL_DEPTH_TEST); 
     stringstream ss; 
     glColor3f(1,1,0); 
     ss << fixed << setprecision(3); 
     int pos = 1; 

     ss.str(""); ss << "Texture size: " << texture_width << "x" << texture_height; 
     gl_print(ss.str().c_str(), 10, screen_height - (pos++ * 20), GLUT_BITMAP_8_BY_13); 
     ss.str(""); ss << "Overall frame time: " << ft_overall.Get() << " ms"; 
     gl_print(ss.str().c_str(), 10, screen_height - (pos++ * 20), GLUT_BITMAP_8_BY_13); 
     ss.str(""); ss << " FBO frame time: " << ft_fbo.Get() << " ms"; 
     gl_print(ss.str().c_str(), 10, screen_height - (pos++ * 20), GLUT_BITMAP_8_BY_13); 
     ss.str(""); ss << "Press space to change texture size; mouse moves/zooms cube"; 
     gl_print(ss.str().c_str(), 10, 10, GLUT_BITMAP_8_BY_13); 
     glEnable(GL_DEPTH_TEST); 
    } 

    glutSwapBuffers(); 
    ft_overall.Update((float)(glutGet(GLUT_ELAPSED_TIME) - before)); 
} 


///////////////////////////////////////////////////////////////////////////// 
// MAIN ///////////////////////////////////////////////////////////////////// 

int main(int argc, char *argv[]) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); 
    glutInitWindowSize(screen_width, screen_height); 
    glutInitWindowPosition(100, 100); 
    glutCreateWindow("FBO Test"); 

    glutDisplayFunc(CB_Display); 
    glutIdleFunc(CB_Idle); 
    glutReshapeFunc(CB_Reshape); 
    glutKeyboardFunc(CB_Keyboard); 
    glutMouseFunc(CB_Mouse); 
    glutMotionFunc(CB_Motion); 
    atexit(CB_Exit); 

    CB_Init(); 
    glutMainLoop(); 
    return 0; 
} 
9

拘束されているため、テクスチャが機能しませんでした。 バインドのテクスチャをレンダリングターゲットとしてFBOで使用することはできません。 これは非常に文書化されていないものですが、あなたはそれがドライバの開発者は、あなたが同時に同じテクスチャに読書のような奇妙なと書いて何かをするだけの場合には、あまりにもいくつかのセーフガードが必要 考えると理にかなって

関連する問題