OpenGL Framebuffer,绘制到纹理

时间:2011-09-24 23:00:12

标签: c++ opengl sdl textures framebuffer

我们很难用framebuffer对象计算渲染到纹理。我们成功了 将纹理绘制到另一个纹理,但纹理不居中。

如果我们将纹理大小设置为与窗口大小相对应,则它是居中的,但我们希望能够管理较小的纹理。

GLuint texture[3];
unsigned int fbo;
SDL_Surface *TextureImage[1];

int LoadGLTextures( )
{

  /* Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit */
  if ( ( TextureImage[0] = SDL_LoadBMP( "crate.bmp" ) ) )
   {

    /* Create The Texture */
    glGenTextures( 1, &texture[0] );

    /* Typical Texture Generation Using Data From The Bitmap */
    glBindTexture( GL_TEXTURE_2D, texture[0] );

    /* Generate The Texture */
    glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w,
                 TextureImage[0]->h, 0, GL_BGR,
                 GL_UNSIGNED_BYTE, TextureImage[0]->pixels );

    /* Linear Filtering */
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
   }

  /* Free up any memory we may have used */
  if ( TextureImage[0] )
      //SDL_FreeSurface( TextureImage[0] );

  return 1;
}


void initFrameBufferTexture(void) {
  glGenTextures(1, &texture[1]); // Generate one texture
  glBindTexture(GL_TEXTURE_2D, texture[1]); // Bind the texture fbo_texture


  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TextureImage[0]->w, TextureImage[0]->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard texture with the width and height of our window


    // Setup the basic texture parameters

  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    //glGenerateMipmapEXT(GL_TEXTURE_2D);

    // Unbind the texture
  glBindTexture(GL_TEXTURE_2D, 0);
}

void initFrameBuffer(void) {

  initFrameBufferTexture(); // Initialize our frame buffer texture

  glGenFramebuffersEXT(1, &fbo); // Generate one frame buffer and store the ID in fbo
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer

  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture[1], 0); // Attach the texture fbo_texture to the color buffer in our frame buffer



  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // Check that status of our generated frame buffer

  if (status != GL_FRAMEBUFFER_COMPLETE_EXT) // If the frame buffer does not report back as complete
   {
    exit(0); // Exit the application
   }

    //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our frame buffer
}


int main(int argc, char *argv[])
{
    gfx_manager.init(640, 480, 32);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.375f, 0.375f, 0);
    glClearColor(0.3, 0.3, 0.3, 0);
    glClear(GL_COLOR_BUFFER_BIT);

  LoadGLTextures();

  initFrameBuffer();

  glMatrixMode(GL_TEXTURE);

  glGenFramebuffersEXT(1, &fbo);
  glBindTexture(GL_TEXTURE_2D, texture[0]); 
  glPushAttrib(GL_VIEWPORT_BIT);


    //glGenerateMipmapEXT();

    //glOrtho(0, TextureImage[0]->w, TextureImage[0]->h, 0, 0, 1);
    //glViewport(0, 0, TextureImage[0]->w, TextureImage[0]->h);

  glClearColor (0.0f, 0.0f, 1.0f, 0.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


  glLoadIdentity();


  glBegin( GL_QUADS );                /* Draw A Quad */

  glTexCoord2f(0.0f, 0.0f);glVertex2f(0.0f, 0.0f);
  glTexCoord2f(1.0f, 0.0f);glVertex2f(0.0f + TextureImage[0]->w , 0.0f);
  glTexCoord2f(1.0f, 1.0f);glVertex2f(0.0f + TextureImage[0]->w, 0.0f + TextureImage[0]->h);
  glTexCoord2f(0.0f, 1.0f);glVertex2f(0.0f, 0.0f + TextureImage[0]->h);
  glEnd( );

  glPopAttrib();
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

  glLoadIdentity();

  glClearColor (0.0f, 0.0f, 1.0f, 1.0f);


  glBindTexture(GL_TEXTURE_2D, texture[1]); 


  glLoadIdentity();

  glBegin( GL_QUADS );                /* Draw A Quad */

  glTexCoord2f(0.0f, 0.0f);glVertex2f(300.0f, 200.0f);
  glTexCoord2f(0.0f, 1.0f);glVertex2f(300.0f , 200.0f + TextureImage[0]->h);
  glTexCoord2f(1.0f, 1.0f);glVertex2f(300.0f + TextureImage[0]->w, 200.0f + TextureImage[0]->h);
  glTexCoord2f(1.0f, 0.0f);glVertex2f(300.0f + TextureImage[0]->w, 200.0f);
  glEnd( );



    SDL_GL_SwapBuffers( );
    sleep(100); 

    return 0;
}

1 个答案:

答案 0 :(得分:3)

您可能已将矩阵和视口设置为与窗口大小相匹配。在绘制之前,请确保将它们更改为适合帧缓冲区大小的值。