1

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カードがまだ輝度をサポートしていないことを読みました。これが本当かどうか誰かが知っていますか?

4

2 に答える 2

1

これは輝度値とは何の関係もありません。問題は、浮動小数点値の読み取りにあります。

glReadPixelsを介して浮動小数点データを正しく読み戻すには、最初にカラークランプモードを設定する必要があります。明らかにOpenGL3.0以降を使用していないため、ARB_color_buffer_float拡張機能を確認する必要があります。その拡張機能にはglClampColorARB、があります。これは、コア3.0バージョンとほとんど同じように機能します。

于 2012-11-18T20:53:59.000 に答える
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 で除算する出力バッファーを「修正」する必要があるようです。 glTexImage2D(. .) GL_LUMINANCE を使用すると、各配列コンポーネントを内部的に 3 回複製し、glReadPixel(..) で GL_LUMINANCE 値を読み取ると、RGB コンポーネントの合計からその値を計算します(したがって、入力として指定した値の 3 倍)。しかし、繰り返しになりますが、それでもクランプされた値が得られます。

3) 最後に、(GL_LUMINANCE の代わりに) テクスチャ フォーマットとして GL_RED を使用すると、入力バッファをパックする必要がなくなり、出力バッファが適切に取得されます。値は固定されておらず、glClampColor(..) を呼び出す必要はまったくありません。

だから、私はGL_REDを使い続けると思います。なぜなら、最終的に私が望んでいたのは、配列インデックスのオフセットなどを心配することなく、「カーネル」から浮動小数点値を送信および収集する簡単な方法だったからです。

于 2012-11-19T16:56:26.100 に答える