我试图在我的ATI显卡上使用亮度纹理。
问题是:我无法正确地从GPU中检索数据。每当我尝试读取它(使用glReadPixels)时,它给我的只是一个“所有的”数组(1.0、1.0、1.0.)。
您可以使用以下代码进行测试:
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
static int arraySize = 64;
static int textureSize = 8;
//static GLenum textureTarget = GL_TEXTURE_2D;
//static GLenum textureFormat = GL_RGBA;
//static GLenum textureInternalFormat = GL_RGBA_FLOAT32_ATI;
static GLenum textureTarget = GL_TEXTURE_RECTANGLE_ARB;
static GLenum textureFormat = GL_LUMINANCE;
static GLenum textureInternalFormat = GL_LUMINANCE_FLOAT32_ATI;
int main(int argc, char** argv)
{
// create test data and fill arbitrarily
float* data = new float[arraySize];
float* result = new float[arraySize];
for (int i = 0; i < arraySize; i++)
{
data[i] = i + 1.0;
}
// set up glut to get valid GL context and
// get extension entry points
glutInit (&argc, argv);
glutCreateWindow("TEST1");
glewInit();
// viewport transform for 1:1 pixel=texel=data mapping
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, textureSize, 0.0, textureSize);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, textureSize, textureSize);
// create FBO and bind it (that is, use offscreen render target)
GLuint fboId;
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
// create texture
GLuint textureId;
glGenTextures (1, &textureId);
glBindTexture(textureTarget, textureId);
// set texture parameters
glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP);
// define texture with floating point format
glTexImage2D(textureTarget, 0, textureInternalFormat, textureSize, textureSize, 0, textureFormat, GL_FLOAT, 0);
// attach texture
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, textureTarget, textureId, 0);
// transfer data to texture
//glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
//glRasterPos2i(0, 0);
//glDrawPixels(textureSize, textureSize, textureFormat, GL_FLOAT, data);
glBindTexture(textureTarget, textureId);
glTexSubImage2D(textureTarget, 0, 0, 0, textureSize, textureSize, textureFormat, GL_FLOAT, data);
// and read back
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, textureSize, textureSize, textureFormat, GL_FLOAT, result);
// print out results
printf("**********************\n");
printf("Data before roundtrip:\n");
printf("**********************\n");
for (int i = 0; i < arraySize; i++)
{
printf("%f, ", data[i]);
}
printf("\n\n\n");
printf("**********************\n");
printf("Data after roundtrip:\n");
printf("**********************\n");
for (int i = 0; i < arraySize; i++)
{
printf("%f, ", result[i]);
}
printf("\n");
// clean up
delete[] data;
delete[] result;
glDeleteFramebuffersEXT (1, &fboId);
glDeleteTextures (1, &textureId);
system("pause");
return 0;
}我还在网上读到ATI卡还不支持亮度。有人知道这是不是真的吗?
发布于 2012-11-19 16:56:26
以下是我发现的:
1)如果使用GL_LUMINANCE作为纹理格式( GL_LUMINANCE_FLOAT32_ATI GL_LUMINANCE32F_ARB或GL_RGBA_FLOAT32_ATI作为内部格式),则glClampColor(.)(或glClampColorARB(..))似乎一点用也没有。只有当我将纹理格式设置为GL_RGBA时,我才能看到那些值正在被积极地夹紧/没有夹紧。我不明白为什么会这样,因为唯一的glClampColor(..)我听说的限制是,它只适用于浮点缓冲区,所有选择的内部格式似乎都是这样。
2)如果您使用GL_LUMINANCE (同样,以GL_LUMINANCE_FLOAT32_ATI、GL_LUMINANCE32F_ARB或GL_RGBA_FLOAT32_ATI作为内部格式),看起来您必须“修正”输出缓冲区将其每个元素除以3。使用GL_LUMINANCE 它内部复制每个数组组件三次。,以及当您使用glReadPixel(.) 它根据RGB组件之和计算其值。读取GL_LUMINANCE值时(因此,是作为输入的三倍)。但是,它仍然会给你夹紧的价值。
3)最后,如果使用GL_RED作为纹理格式(而不是GL_LUMINANCE),则不需要打包输入缓冲区并正确地获得输出缓冲区。这些值没有夹紧,不需要调用glClampColor(..)完全没有。
所以,我想我还是坚持使用GL_RED,因为最终我想要的是一种从“内核”发送和收集浮点值的简单方法,而不必担心抵消数组索引或类似的事情。
发布于 2012-11-18 20:53:59
这与亮度值无关;问题在于读取浮点值。
为了通过glReadPixels正确地读取浮点数据,首先需要设置颜色夹紧模式.由于您显然没有使用OpenGL 3.0+,所以您应该查看浮子延伸。在这个扩展中是glClampColorARB,它的工作原理与核心3.0版本非常相似。
https://stackoverflow.com/questions/13442872
复制相似问题