PBO Indexed Color Texture Rendering with Palette in Fragment Shader not working

505 views Asked by At

I am working on a game with 8bit graphics. I provide a Pixelbuffer (OSXRenderer.pbo) to my gameloop to fill it up. Then texsubimage it onto a texture (OSXRenderer.ScreenTexture). The texture is rendered to the screen via a quad.

I got it working without problems with a RGB PBO (size: width*height*3). But now i want the pbo to be indexed color. So i load a palette into another texture (OSXRenderer.PaletteTexture) and changed my PBO. (size: width*height).

How i figure it should work is: PBO gets filled with noise (random uint8 0-63), Screentexture gets texsubimaged, and when rendering it onto the screen via quad, my fragmentshader replaces all the RED channel values with the corresponding colors from my palette and i get 8bit noise on the screen.

But i simply can't get it to work. I only get a black screen. If I set my fragcolor to the incoming screentexture(pbo) data i get red noise. Just as expected.

[EDIT] I tested the fragment-shaders "color"-variable values. And they are always 0.0 except alpha which is always 1.0

setup:

    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");

update loop:

    /* 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

There are 0 answers