Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 片段着色器中调色板的PBO索引颜色纹理渲染不工作_Opengl_Glsl_Fragment Shader_Color Palette_Pbo - Fatal编程技术网

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

Opengl 片段着色器中调色板的PBO索引颜色纹理渲染不工作,opengl,glsl,fragment-shader,color-palette,pbo,Opengl,Glsl,Fragment Shader,Color Palette,Pbo,我正在开发一款8位图形的游戏。我提供了一个像素缓冲区(OSXRenderer.pbo) 到我的gameloop来填满它。然后将其子映像到纹理上(OSXRenderer.ScreenTexture)。 纹理通过四边形渲染到屏幕 我使用RGB PBO(尺寸:宽*高*3)使其正常工作。 但现在我希望pbo被索引为彩色。所以我将调色板加载到另一个纹理中 (OSXRenderer.PaletteTexture)并更改了我的PBO。(尺寸:宽*高) 我认为它应该如何工作: PBO被噪声填充(随机uint8

我正在开发一款8位图形的游戏。我提供了一个像素缓冲区(OSXRenderer.pbo) 到我的gameloop来填满它。然后将其子映像到纹理上(OSXRenderer.ScreenTexture)。 纹理通过四边形渲染到屏幕

我使用RGB PBO(尺寸:宽*高*3)使其正常工作。 但现在我希望pbo被索引为彩色。所以我将调色板加载到另一个纹理中 (OSXRenderer.PaletteTexture)并更改了我的PBO。(尺寸:宽*高)

我认为它应该如何工作: PBO被噪声填充(随机uint8 0-63),Screentexture被子成像, 当通过quad将其渲染到屏幕上时,我的fragmentshader将替换所有 红色通道值和调色板中相应的颜色,我在屏幕上得到8比特噪声

但我就是不能让它工作。我只有一个黑屏。如果我将fragcolor设置为传入 屏幕纹理(pbo)数据我得到红色噪音。正如所料

[编辑] 我测试了片段着色器“颜色”-变量值。它们总是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();
顶点着色器:

    # version 120
    varying vec2 texcoord;

    // Simple Passthrough
    void main(void) 
    {
        gl_Position = ftransform();
        texcoord = gl_MultiTexCoord0.xy;
    }
碎片着色器:

    # 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;
    }

首先,当您尝试这样做时,您不希望使用
GL\u线性
纹理过滤器。这应该是
GL\u最近的
,您可能还希望在S和T包裹模式中使用
GL\u夹紧到边缘
。当您尝试使用规范化纹理坐标来实现查找表时,这些都是必须考虑的重要事项。理想情况下,您只需使用
texelFetch(…)
并避免所有这些,但您的GLSL版本让我认为这不实用。更重要的是,为什么要将
index.r*255
相乘
index.r
将是一个标准化的浮点值,您应该能够直接将其作为纹理坐标输入。感谢您的建议,您有权使用index.r*255。那太愚蠢了。我在没有255的情况下测试了它,并实现了您所有的其他建议。我的问题仍然存在。啊,好的。要记住的另一件事是,当某些东西绑定到
GL\u PIXEL\u UNPACK\u BUFFER
时,
glTexImage2D(…)
的数据指针参数是绑定缓冲区内存池的偏移量
OSXRenderer.Pixelbuffer.Data
在第一次调用时可能是合适的,但是在第二次调用时,您正在获取客户端内存中某个变量的地址,除非您首先解除绑定(绑定0)解包PBO,否则该调用肯定无效。仅此而已!我在设置中生成调色板纹理时,GL_像素_解包_缓冲区仍然绑定到我的pbo。在将其绑定到0后,它工作了!非常感谢你!!