PBO索引颜色纹理渲染与片段着色器调色板不工作

时间:2015-06-09 19:59:43

标签: opengl glsl fragment-shader color-palette pbo

我正在开发一款8位图形的游戏。我提供了一个Pixelbuffer(OSXRenderer.pbo) 到我的游戏圈来填补它。然后texsubimage它到纹理(OSXRenderer.ScreenTexture)。 纹理通过四边形呈现在屏幕上。

我使用RGB PBO(尺寸:宽*高* 3)没有问题。 但现在我希望pbo被编入索引颜色。所以我将调色板加载到另一个纹理中 (OSXRenderer.PaletteTexture)并改变了我的PBO。 (尺寸:宽*高)。

我认为应该如何运作: PBO充满了噪音(随机uint8 0-63),Screentexture被texsubimaged, 当通过四边形将它渲染到屏幕上时,我的碎片整理器取代了所有的碎片 使用调色板中相应颜色的RED通道值,屏幕上会出现8bit噪音。

但我根本无法让它发挥作用。我只得到一个黑屏。如果我将fragcolor设置为传入 screentexture(pbo)数据我得到红噪声。正如预期的那样。

[编辑] 我测试了片段着色器" color" -variable值。它们总是0.0,除了alpha总是1.0

设置:

    static uint8 palette[] = {
        0x80,0x80,0x80, 0x00,0x00,0xBB, 0x37,0x00,0xBF, 0x84,0x00,0xA6,
        0xBB,0x00,0x6A, 0xB7,0x00,0x1E, 0xB3,0x00,0x00, 0x91,0x26,0x00,
        0x7B,0x2B,0x00, 0x00,0x3E,0x00, 0x00,0x48,0x0D, 0x00,0x3C,0x22,
        0x00,0x2F,0x66, 0x00,0x00,0x00, 0x05,0x05,0x05, 0x05,0x05,0x05,

        0xC8,0xC8,0xC8, 0x00,0x59,0xFF, 0x44,0x3C,0xFF, 0xB7,0x33,0xCC,
        0xFF,0x33,0xAA, 0xFF,0x37,0x5E, 0xFF,0x37,0x1A, 0xD5,0x4B,0x00,
        0xC4,0x62,0x00, 0x3C,0x7B,0x00, 0x1E,0x84,0x15, 0x00,0x95,0x66,
        0x00,0x84,0xC4, 0x11,0x11,0x11, 0x09,0x09,0x09, 0x09,0x09,0x09,

        0xFF,0xFF,0xFF, 0x00,0x95,0xFF, 0x6F,0x84,0xFF, 0xD5,0x6F,0xFF,
        0xFF,0x77,0xCC, 0xFF,0x6F,0x99, 0xFF,0x7B,0x59, 0xFF,0x91,0x5F,
        0xFF,0xA2,0x33, 0xA6,0xBF,0x00, 0x51,0xD9,0x6A, 0x4D,0xD5,0xAE,
        0x00,0xD9,0xFF, 0x66,0x66,0x66, 0x0D,0x0D,0x0D, 0x0D,0x0D,0x0D,

        0xFF,0xFF,0xFF, 0x84,0xBF,0xFF, 0xBB,0xBB,0xFF, 0xD0,0xBB,0xFF,
        0xFF,0xBF,0xEA, 0xFF,0xBF,0xCC, 0xFF,0xC4,0xB7, 0xFF,0xCC,0xAE,
        0xFF,0xD9,0xA2, 0xCC,0xE1,0x99, 0xAE,0xEE,0xB7, 0xAA,0xF7,0xEE,
        0xB3,0xEE,0xFF, 0xDD,0xDD,0xDD, 0x11,0x11,0x11, 0x11,0x11,0x11
    };

    /* Create the PBO */
    glGenBuffers(1, &OSXRenderer.pbo);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, OSXRenderer.pbo);
    glBufferData(GL_PIXEL_UNPACK_BUFFER, W*H, NULL, GL_STREAM_DRAW);

    /* Create the Screen Texture (400*240 pixel) */
    glGenTextures(1, &OSXRenderer.ScreenTexture);
    glBindTexture(GL_TEXTURE_2D, OSXRenderer.ScreenTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, W, H, 0, 
        GL_RED, GL_UNSIGNED_BYTE, OSXRenderer.Pixelbuffer.Data); 

    /* Create the Palette Texture (64*1 pixel) */
    glGenTextures(1, &OSXRenderer.PaletteTexture);
    glBindTexture(GL_TEXTURE_2D, OSXRenderer.PaletteTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 1, 0, 
        GL_RGB, GL_UNSIGNED_BYTE, &palette);

    /* Compile and Link Shaders */
    OSXRenderer.Program = OSXCreateProgram();
    glUseProgram(OSXRenderer.Program);

    /* Get the uniforms for the screen- and the palette-texture */
    OSXRenderer.UniformTex = glGetUniformLocation(OSXRenderer.Program, "tex");
    OSXRenderer.UniformPal = glGetUniformLocation(OSXRenderer.Program, "pal");

更新循环:

    /* Rendering Prerequesites */
    glUseProgram(OSXRenderer.Program);

    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, OSXRenderer.PaletteTexture);
    glUniform1i(OSXRenderer.UniformPal, 0);

    glActiveTexture(GL_TEXTURE1);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, OSXRenderer.ScreenTexture);
    glUniform1i(OSXRenderer.UniformTex, 1);

    /* Bind the PBO */
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, OSXRenderer.pbo);
    glBufferData(GL_PIXEL_UNPACK_BUFFER, W*H, NULL, GL_STREAM_DRAW);

    OSXRenderer.Pixelbuffer.Data = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);

    //
    //
    FillPixelBuffer();
    //
    //

    glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
    glBindTexture(GL_TEXTURE_2D, OSXRenderer.ScreenTexture);

    /* Bind the screentexture again just to be save
    and fill it with the PBO data */
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, W, H, GL_RED, GL_UNSIGNED_BYTE, 0);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

    /* Render it to the screen */
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f,1.0f);
    glVertex2f(-1.0f,1.0f);
    glTexCoord2f(1.0f,1.0f);
    glVertex2f(1.0f,1.0f);
    glTexCoord2f(1.0f,0.0f);
    glVertex2f(1.0f,-1.0f);
    glTexCoord2f(0.0f,0.0f);
    glVertex2f(-1.0f,-1.0f);
    glEnd();

    /* glFlush() */
    CGLFlushDrawable();

vertexshader:

    # version 120
    varying vec2 texcoord;

    // Simple Passthrough
    void main(void) 
    {
        gl_Position = ftransform();
        texcoord = gl_MultiTexCoord0.xy;
    }

fragmentshader:

    # version 120
    uniform sampler2D tex;
    uniform sampler2D pal;
    varying vec2 texcoord;


    void main(void) 
    {
        // Get the color values of the screen-texture. I only want the RED channel
        vec4 index = texture2D(tex, texcoord);
        // Get the color values of the palette texture 
        // using the screen-texture's RED channel as an index

//[EDIT] First post multiplied index.r with 255 here.
        vec4 color = texture2D(pal, vec2(index.r, 0));
        // Use it
        gl_FragColor = color;
    }

0 个答案:

没有答案