GL_LUMINANCE和ATI的问题

时间:2012-11-18 17:56:39

标签: opengl glsl luminance

我正在尝试在ATI显卡上使用亮度纹理。

问题:我无法从GPU正确检索数据。每当我尝试阅读它时(使用glReadPixels),它给我的全部是'all-one'数组(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卡尚不支持亮度。有谁知道这是真的吗?

2 个答案:

答案 0 :(得分:1)

这与亮度值无关;问题在于您阅读浮点值。

为了通过glReadPixels正确读取浮点数据,首先需要set the color clamping mode。由于您显然没有使用OpenGL 3.0+,因此您应该查看ARB_color_buffer_float extension。在该扩展名为glClampColorARB,其功能与核心3.0版本相同。

答案 1 :(得分:0)

这是我发现的:

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。猜测会发生这种情况,因为当您使用GLLUMINANCE it internally replicates each array component three times时使用glTexImage2D(..)以及使用glReadPixel(..)it calculates its values from the sum of the RGB components读取GL_LUMINANCE值时(因此,您输入的值是您输入的三倍)。但同样,它仍然会给你一些限制值。

3)最后,如果您使用GL_RED作为纹理格式(而不是GL_LUMINANCE),则无需打包输入缓冲区并正确获取输出缓冲区。这些值没有被限制,你根本不需要调用glClampColor(..)。

所以,我想我会坚持使用GL_RED,因为最终我想要的是从我的“内核”发送和收集浮点值的简单方法,而不必担心偏移数组索引或类似的东西