Мы не делаем игры :)
Главная  Статьи  Проекты  Загрузки  Ссылки  Гостевая  О нас 
Рендинг в текстуру (FBO)

В статье Рендинг в текстуру мы рассмотрели самую простую реализацию рендинга в текстуру. В этой статье, для выполнения этой задачи мы воспользуемся еще и расширением GL_EXT_framebuffer_object. Итак, инициализация расширения:

const
  GL_FRAMEBUFFER_EXT = $8D40;
  GL_COLOR_ATTACHMENT0_EXT = $8CE0;
  GL_FRAMEBUFFER_COMPLETE_EXT = $8CD5;

var
  GL_EXT_framebuffer_object: Boolean;

glGenFramebuffersEXT: procedure(n: GLsizei; FrameBuffers: PGLuint); stdcall;
glBindFramebufferEXT: procedure(Target, FrameBuffer: GLuint); stdcall;
glFramebufferTexture2DEXT: procedure(Target, Attachment, TexTarget, Texture: GLuint; Level: GLint); stdcall;
glCheckFramebufferStatusEXT: function(Target: GLenum): GLenum; stdcall;

var
  Extensions: String;
begin
  Extensions := glGetString(GL_EXTENSIONS);

  GL_EXT_framebuffer_object := Pos('GL_EXT_framebuffer_object', Extensions) <> 0;
  if GL_EXT_framebuffer_object then
  begin
    glGenFramebuffersEXT := wglGetProcAddress('glGenFramebuffersEXT');
    glBindFramebufferEXT := wglGetProcAddress('glBindFramebufferEXT');
    glFramebufferTexture2DEXT := wglGetProcAddress('glFramebufferTexture2DEXT');
    glCheckFramebufferStatusEXT := wglGetProcAddress('glCheckFramebufferStatusEXT');
  end
  else
    PostQuitMessage(0);

Это не все функции (константы), а только те которыми мы будем пользоваться, полный список функций (констант) вы можете увидеть на opengl.org/registry/ выбрав расширение GL_EXT_framebuffer_object. Теперь алгоритм. Первое - инициализируем текстуру и обьект кадрового буфера (Frame Buffer Object - FBO):

var
  Texture: Cardinal;
  FrameBuffer: Cardinal;

glEnable(GL_TEXTURE_2D);

//создаем текстуру для редндинга
glGenTextures(1, @Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGB,
GL_UNSIGNED_BYTE, nil);

//создаем кадровый буфер
glGenFramebuffersEXT(1, @FrameBuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FrameBuffer);

//прикрепим текстуру к кадровому буферу (содержимое буфера будет "на ней")
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, Texture, 0);

//проверяем на наличие ошибок
if glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) <>
GL_FRAMEBUFFER_COMPLETE_EXT then
begin
  PostQuitMessage(0);
end;

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

Теперь можем использовать наш буфер, рисуем на буфере:

//активируем буфер
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FrameBuffer);
//запоминаем вьюпорт
glPushAttrib(GL_VIEWPORT_BIT);

//устанавливаем размер вьюпорта, очищаем экран
glViewport(0, 0, TEX_WIDTH, TEX_HEIGHT);
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

//рисуем наши треугольники
glPushMatrix;
glLoadIdentity;
glTranslatef(0,0,-5);

glRotatef(Angle,0,0,1);

glBegin(GL_TRIANGLES);
  glColor3ub(255,0,0);
  glVertex3f(-0.8, -0.8, 0);
  glVertex3f( 0.8, -0.8, 0);
  glVertex3f( 0.8, 0.8, 0);

  glColor3ub(0,255,0);
  glVertex3f( 0.8, 0.8, 0);
  glVertex3f(-0.8, 0.8, 0);
  glVertex3f( 0.8, -0.8, 0);
glEnd;

glPopMatrix;

//восстанавливаем все
glPopAttrib;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

Теперь все что мы нарисовали на нашей текстуре можно показывать:

glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;

glTranslatef(0,0,-5);
glRotatef(Angle,0,1,0);

//натягиваем текстуру на прямоугольник
glBindTexture(GL_TEXTURE_2D, Texture);
glBegin(GL_QUADS);
  glColor3ub(255,255,255);
  glTexCoord2f(0,0); glVertex3f(-1,-1,0);
  glTexCoord2f(1,0); glVertex3f( 1,-1,0);
  glTexCoord2f(1,1); glVertex3f( 1, 1,0);
  glTexCoord2f(0,1); glVertex3f(-1, 1,0);
glEnd;

Как вы видите основные моменты не отличаются от простого рендинга в текстуру представленного в предыдущей статье, мы просто добавили работу с обьектом кадрового буфера. Кроме более высокой скорости у этого метода есть еще одно преимущество, размер текстуры для рендинга ограничивается только возможностями вашей видеокарты. Вот пример, приятного вам кодинга.

Автор: Sokal

(c) GameDev 32, 2007-2008
Сайт управляется системой uCoz