2012-06-26 4 views
3

Я проверил этот аналогичный вопрос, но предложения не решили мою проблему: Low precision and clamping when writing to floating point FBO.Объект Framebuffer с поплавковыми текстурными зажимами

Я обрабатываю изображение с плавающей точкой, используя объект framebuffer как объект рендеринга. Однако значения, считываемые glReadPixels, зажаты между 0 и 1. Если я попытаюсь отобразить свое изображение с использованием нормализованных значений в этом диапазоне, он будет работать, но значения за пределами этого диапазона будут зажаты до 1 или 0. Выполняется некоторые части кода.

Вот как я создал текстуру, которую я прикрепленную к FBO:

glGenTextures(1, &color_tex); 
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, color_tex); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, 
     GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, 
     GL_NEAREST); 
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB32F_ARB, ResX, ResY, 0, 
     GL_RGB, GL_FLOAT, NULL); 

Как я прочитал это после покраски:

glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); 
    glReadPixels(0, 0, ResX, ResY, GL_RGB, GL_FLOAT, data); 

Я нарисовал треугольник на изображении с помощью

glColor3f(0.5f, 2.0f, -0.5f); 

И значения пикселей отображаются как (0.5f, 1.0f, 0.0f) в буфере чтения.

Как я могу вернуть значения из этого диапазона?

Следит упрощенную версию моего кода (я держал буфер глубины, потому что я использую его в исходном):

Пс. Я исправил приведенный ниже код на основе ответа. Он работает сейчас.

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

#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 

#define WINDOW_WIDTH     800 
#define WINDOW_HEIGHT     600 

bool initGL(int argc, char *argv[]) 
{ 
    // initialize GLUT and glexts 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
    glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); 
    glutInitWindowPosition(100, 100); 
    glutCreateWindow("FBO"); 

    GLenum err = glewInit(); 
    if (GLEW_OK != err) 
    { 
     /* Problem: glewInit failed. */ 
     printf("Error: %s\n", glewGetErrorString(err)); 
     return 0; 
    } 

    if (!GLEW_EXT_framebuffer_object) 
    { 
     printf("Error: no extension GL_EXT_framebuffer_object."); 
     return 0; 
    } 

    if (!GLEW_ARB_color_buffer_float) 
    { 
     printf("Error: no extension ARB_color_buffer_float."); 
     return 0; 
    } 

    glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE); 
    glClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE); 
    glClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 

    return 1; 
} 

void glErrorCheck() 
{ 
    int errCode; 
    if ((errCode = glGetError()) != GL_NO_ERROR) 
    { 
     printf("Failure in OpenGL %d", errCode); 
     exit(0); 
    } 
} 

bool renderFBO() 
{ 

    GLenum status; 
    GLuint color_tex, depth_rb, fb; 

    int ResX, ResY; 

    ResY = 4; 
    ResX = 4; 

    float *data; 

    //gen renderbuffer 
    glGenRenderbuffers(1, &depth_rb); 
    glErrorCheck(); 
    // initialize depth renderbuffer 
    glBindRenderbuffer(GL_RENDERBUFFER, depth_rb); 
    glErrorCheck(); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, ResX, 
      ResY); 

    glErrorCheck(); 

    // make a texture 
    glGenTextures(1, &color_tex); 
    // initialize texture that will store the framebuffer image (BGRA type) 
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, color_tex); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, 
      GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, 
      GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); 
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB32F_ARB, ResX, ResY, 0, 
      GL_RGB, GL_FLOAT, NULL); 
    glErrorCheck(); 

    // gen the framebuffer object 
    glGenFramebuffers(1, &fb); 
    // bind the framebuffer, fb, so operations will now occur on it 
    glBindFramebuffer(GL_FRAMEBUFFER, fb); 

    // bind this texture to the current framebuffer obj. as color_attachment_0 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
      GL_TEXTURE_RECTANGLE_ARB, color_tex, 0); 
    glErrorCheck(); 

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 
      GL_RENDERBUFFER, depth_rb); 
    glErrorCheck(); 

    //check framebuffer status 
    status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
    if (status != GL_FRAMEBUFFER_COMPLETE) 
    { 
     glBindFramebuffer(GL_FRAMEBUFFER, 0); 
     { 
      printf("Failure in OpenGL Framebuffer %d", status); 
      return 0; 
     } 
    } 
    glErrorCheck(); 

    //render to GL_TEXTURE_2D 
    glBindFramebuffer(GL_FRAMEBUFFER, fb); 
    glClearColor(0.0, 0.0, 0.0, 1.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glViewport(0, 0, ResX, ResY); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0.0, (float) ResX, 0.0, (float) ResY, -1.0, 1.0); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glBegin(GL_TRIANGLES); 

    printf("Original color: %f %f %f\n", 0.5f, 2.0f, -0.5f); 

    glColor3f(0.5f, 2.0f, -0.5f); 

    glVertex3f(0.0f, 0.0f, 0.0f); 
    glVertex3f((float) ResX, 0.0f, 0.0f); 
    glVertex3f((float) ResX, (float) ResY, 0.0f); 

    glEnd(); 

    // read framebuffer 
    glReadBuffer(GL_COLOR_ATTACHMENT0); 
    glErrorCheck(); 

    // allocate memory for texture data 
    data = new float[ResX * ResY * 3]; 
    if (data == NULL) 
    { 
     printf("Out of memory\n"); 
     return false; 
    } 

    //glClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 
    glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE); 

    glReadPixels(0, 0, ResX, ResY, GL_RGB, GL_FLOAT, data); 
    glErrorCheck(); 

    //print the last pixel of the buffer 
    int i = ResX * ResY - 1; 
    printf("Buffer color: %f %f %f\n", data[i], data[i + 1], data[i + 2]); 

    // Re-enable rendering to the window 
    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    glErrorCheck(); 

    //deallocate data 
    delete[] data; 

    //delete buffers 
    glDeleteTextures(1, &color_tex); 
    glDeleteRenderbuffers(1, &depth_rb); 
    glDeleteFramebuffers(1, &fb); 
    glErrorCheck(); 

    return true; 
} 

int main(int argc, char **argv) 
{ 

    if (!initGL(argc, argv)) 
    { 
     printf("Failure during GLUT/GLEXT initialization."); 
     return 0; 
    } 

    if (!renderFBO()) 
     printf("Fail!\n"); 

    printf("End!\n"); 
    return 0; 

} 

ответ

3

ли полный набор glClampColor() операций в вашей initGL() функции:

glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE); 
glClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE); 
glClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 

В моей системе я только нуждался в GL_CLAMP_VERTEX_COLOR.

+0

Это сработало! Я уже устанавливал 'GL_CLAMP_READ_COLOR' как false. Однако, как вам, мне нужен только «GL_CLAMP_VERTEX_COLOR». Большое спасибо! – andrade

1

Вы должны использовать glClampColor заявить, будет ли зажаты или нет цвета, которые вы читали с glReadPixels.

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

+0

Благодарим вас за ответ, Николь. Я уже пытался использовать его, но я получаю эту ошибку: 'error: 'glClampColor' не был объявлен в этой области'. Должен ли я включать в свой код какой-либо другой заголовок или библиотеку, чтобы использовать эту функцию? – andrade

+0

Вы проверяете ['ARB_color_buffer_float'] (http://www.opengl.org/registry/specs/ARB/color_buffer_float.txt) и/или версию ядра GL и загружаете соответствующие указатели (-и) функции? – genpfault

+0

@andrade: что вы используете для [загрузки функций OpenGL] (http://www.opengl.org/wiki/Load_OpenGL_Functions)? –

 Смежные вопросы

  • Нет связанных вопросов^_^