gpt4 book ai didi

opengl - 具有 float 纹理钳位值的帧缓冲区对象

转载 作者:行者123 更新时间:2023-12-01 12:52:52 26 4
gpt4 key购买 nike

我查过这个类似的问题,但建议并没有解决我的问题:Low precision and clamping when writing to floating point FBO .

我正在使用帧缓冲区对象作为渲染目标来渲染 float 图像。但是,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;

}

最佳答案

initGL() 函数中执行一整套 glClampColor() 操作:

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

关于opengl - 具有 float 纹理钳位值的帧缓冲区对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11211698/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com