ПрограммированиеФорумГрафика

Проблема с отрисовкой сцены в текстуру

#0
21:07, 28 авг 2010

Всем привет.

Рисую сцену в текстуру
создание RTT и FBO

#define  TEXTURE_WIDTH 1024
#define TEXTURE_HEIGHT 768

..........................................

              glGenTextures(1, &textureId);
  glBindTexture(GL_TEXTURE_2D, textureId);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);
  glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); 
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
         GL_RGBA, GL_UNSIGNED_BYTE, 0);
  glBindTexture(GL_TEXTURE_2D, 0);


  glGenFramebuffersEXT(1, &fboId);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);

  GLuint rboId;
  glGenRenderbuffersEXT(1, &rboId);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,TEXTURE_WIDTH, TEXTURE_HEIGHT);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);


  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, textureId, 0);
  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, rboId);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
............................................

И отрисовка

              Camera->Look();
  Camera->SetViewByMouse();

  vec4  mLight = vec4_VectorMatrixMultiply(Camera->GetModelViewMatrix(),Light);



  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


  shadScene->Start();
  shadScene->SetUniform4f("Light",mLight.x,mLight.y,mLight.z,1.0);
  Entity->Render(entLevel);
  shadScene->End();
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

    /*glBindTexture(GL_TEXTURE_2D, textureId);
        glGenerateMipmapEXT(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, 0);*/


vec3  p[4];
Camera->GetCoordPolyForZ(1,p);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,textureId);
glBegin(GL_QUADS);
  glTexCoord2f(1.0,1.0);    glVertex3f(p[0].x,p[0].y,p[0].z);
  glTexCoord2f(1.0,0.0);    glVertex3f(p[1].x,p[1].y,p[1].z);
  glTexCoord2f(0.0,0.0);      glVertex3f(p[2].x,p[2].y,p[2].z);
  glTexCoord2f(0.0,1.0);    glVertex3f(p[3].x,p[3].y,p[3].z);

glEnd();
glDisable(GL_TEXTURE_2D);

В результате на кваде я получаю заливку усредненным цветом сцены, которая меняется от вращения камеры. Без рендера в текстуру все отрисовывается нормально. Подскажите, пожалуйста, в чем проблема?

#1
21:25, 28 авг 2010

какой там у нас drawBuffer ?

#2
21:56, 28 авг 2010

Эм, я ставил так

Camera->Look();
  Camera->SetViewByMouse();

  vec4  mLight = vec4_VectorMatrixMultiply(Camera->GetModelViewMatrix(),Light);



  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
  glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);  
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

но не помогало, а какой должен быть?

#3
22:00, 28 авг 2010

BenTech
> glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

см glDrawBuffers

а, вообще, проще найти пример вендоров

#4
22:05, 28 авг 2010

Так я делаю по примеру

FBO_Sample

Там вообще нет glDrawBuffers в той часте где glBindFramebuffer

#5
22:42, 28 авг 2010

BenTech
проверьне убил ли ты вьюпорт.

#6
23:26, 28 авг 2010

Всмысле убил?

#7
0:10, 29 авг 2010

если glViewPort(0,0,1,1) гдето проскачило. то ты увидиш усреднённый цвет всей сцены.
проверь все пуш атрибуты там бла-бла-бла нуты понял

#8
1:36, 29 авг 2010

Проверил, viewport впорядке.  >< Не рисует как надо и все тут. Может кто-нибудь для примера привести 100% рабочий код именно самого рендера в RT без лишних наворотов? Кажется что что-то не по порядку идет.

#9
2:15, 29 авг 2010

ну вот это работает...
хедер

#pragma once
#ifndef _FBO_H_
#define _FBO_H_
#include "glaux.h"
#include "glext.h"

struct sFBO  {
  bool ready;
  int w,h;
  int vpW, vpH;
  //descriptor
  unsigned type, internalFormat,
         format, dataType, minFilter, magFilter;


  unsigned rbDepth;                    // id of framebuffer object
    unsigned fbDepth;
  unsigned renderTarget;

  void create(int _w = 512, int _h= 512, unsigned _type = GL_TEXTURE_2D,   
        unsigned _internalFormat = GL_RGBA32F_ARB, 
        unsigned _format = GL_RGBA, unsigned _dataType = GL_FLOAT,
        unsigned _minFilter = GL_LINEAR, unsigned _magFilter = GL_LINEAR);

  void startRTT(bool depth = true);
  void stopRTT();
  void check();
  void set(int level = 3);
};

#endif


сипупышка

#include "stdafx.h"
#include "FBO.h"

extern int screenW;
extern int screenH;

extern PFNGLDELETERENDERBUFFERSEXTPROC    glDeleteRenderbuffersEXT;
extern PFNGLDELETEFRAMEBUFFERSEXTPROC    glDeleteFramebuffersEXT ;
extern PFNGLGENFRAMEBUFFERSEXTPROC      glGenFramebuffersEXT ;
extern PFNGLGENRENDERBUFFERSEXTPROC      glGenRenderbuffersEXT ;
extern PFNGLBINDFRAMEBUFFEREXTPROC      glBindFramebufferEXT ;
extern PFNGLBINDRENDERBUFFEREXTPROC      glBindRenderbufferEXT ;
extern PFNGLRENDERBUFFERSTORAGEEXTPROC    glRenderbufferStorageEXT ;
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC  glFramebufferRenderbufferEXT ;
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC    glFramebufferTexture2DEXT;
extern PFNGLDRAWBUFFERSPROC          glDrawBuffers ; 
extern PFNGLACTIVETEXTUREARBPROC      glActiveTextureARB;
extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC   glCheckFramebufferStatusEXT;

void sFBO::create(int _w, int _h, unsigned _type,   unsigned _internalFormat, 
                          unsigned _format, unsigned _dataType,
                  unsigned _minFilter, unsigned _magFilter) {
  w = _w;
  h = _h;

  type = _type ;
  internalFormat = _internalFormat ;
  format = _format ;
  dataType = _dataType ;
  minFilter = _minFilter;
  magFilter = _magFilter;

  glEnable ( type );

  glGenTextures(1, &renderTarget);
  glBindTexture( type, renderTarget);
  glTexParameterf( type, GL_TEXTURE_MIN_FILTER, minFilter);
  glTexParameterf( type, GL_TEXTURE_MAG_FILTER, magFilter);
  
  if ( type == GL_TEXTURE_CUBE_MAP )  {
    
  //for (int size = 512, level = 0; size > 0; size >>= 1, level++)  {  
    int level = 0;
  //  glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
  //  glTexParameteri ( GL_TEXTURE_CUBE_MAP_ARB,  GL_TEXTURE_WRAP_S, GL_REPEAT);
  //  glTexParameteri ( GL_TEXTURE_CUBE_MAP_ARB,  GL_TEXTURE_WRAP_T, GL_REPEAT);

/*
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    
    glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_GENERATE_MIPMAP_SGIS, GL_TRUE );
*/
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internalFormat,  w, h, 0, format, dataType, NULL);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internalFormat,  w, h, 0, format, dataType, NULL);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internalFormat,  w, h, 0, format, dataType, NULL);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internalFormat,  w, h, 0, format, dataType, NULL);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internalFormat,  w, h, 0, format, dataType, NULL);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internalFormat,  w, h, 0, format, dataType, NULL);  
  //}
  } else {
    glTexImage2D( type, 0, internalFormat, w, h, 0, format, dataType, NULL);    
  }

  //Теперь создадим рендер-буфер, он нам нужен для теста глубины:
  glGenRenderbuffersEXT(1, &rbDepth);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbDepth);
  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, w, h);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    
  //И последнее, создаём фрейм-буфер:
  glGenFramebuffersEXT(1, &fbDepth);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbDepth);
  
  if ( type == GL_TEXTURE_CUBE_MAP )  {  
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,  GL_TEXTURE_CUBE_MAP_POSITIVE_X, renderTarget, 0);
  /*  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,  GL_TEXTURE_CUBE_MAP_NEGATIVE_X, renderTarget, 0);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,  GL_TEXTURE_CUBE_MAP_POSITIVE_Y, renderTarget, 0);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, renderTarget, 0);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,  GL_TEXTURE_CUBE_MAP_POSITIVE_Z, renderTarget, 0);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, renderTarget, 0);
*/
  } else {
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, renderTarget, 0);
  }

  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbDepth);
  check();
  
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  glDisable (type);
}

void sFBO::check()  {
  if(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
    MessageBox(NULL, _T("frameBuffer mandec"), _T("mandec message"), MB_OK);

}

void sFBO::startRTT( bool depth)  {
  glViewport(0, 0, w, h);
  //направляем рендер в нашу текстуру
  
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbDepth); 
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbDepth); 

  check();
  // Очищать текстуру нужно значением соответствующим дальней плоскости отсечения
  if (depth)  glClearColor(1, 1, 1, 1);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}  

void sFBO::stopRTT()  {
  glViewport(0, 0, screenW, screenH);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  //  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);  
}

void sFBO::set(int level)  { 
  glActiveTextureARB(GL_TEXTURE0_ARB + level );   
  glEnable(type);  glBindTexture(type, renderTarget); 
}

фурычит воттак

sFBO RT;
RT.create();

RT.startRTT();
        renderScene();
RT.stopRTT();
#10
7:20, 29 авг 2010

BenTech
> Может кто-нибудь для примера привести 100% рабочий код именно самого рендера в
> RT без лишних наворотов? Кажется что что-то не по порядку идет.
есть примеры от вендоров

сам фреймбуффер комплитед ?

#11
12:08, 29 авг 2010

Все, заработало, надо было просто активировать текстурный стейт glActiveTexture.

Правда вторая пробема, fov на текстуре не соответствует fov на камере(хотя я его не трогую при рендере в текстуру).

#12
15:31, 29 авг 2010

а ты потрогай....нестесняйся...
ерьёзно попробуй сохранить проекцию поставить для РТТ, восстановить для норм отрисовки

#13
16:43, 29 авг 2010

innuendo,coordBox спасибо большое, разобрался с FBO, все заработало =)

ПрограммированиеФорумГрафика

Тема в архиве.

Тема закрыта.