1

我正在尝试编写一个简单的测试程序来演示 GLSL 4.2 的ImageLoad功能。到目前为止,我有:

  • 一个简单的着色器,它从 an 加载左下角的纹素image2D并显示它。
  • 一些简单的顶点代码来绘制全屏小队
  • 其他用于创建上下文、编译着色器等的脚手架代码。

这是我的片段代码(顶点是一个简单的直通着色器):

#version 420

#include <gtest/SmallImage.h> //NOTE: I have a preprocessor that takes care of includes

layout(binding = SMALL_IMAGE_ONE_BINDING, rgba8) uniform image2D image_one;

smooth in vec2 texture_coords;
out vec4 out_color;

void main(void)
{
  vec4 loaded = imageLoad(image_one, ivec2(0,0));
  vec4;
  out_color = vec4(loaded.r,
               loaded.g,
                   gl_FragCoord.y/1200.0,
                   1);
}

很简单,没有阅读空间。与像素坐标成比例的蓝色通道让我知道即使imageLoad调用失败,四边形也被正确渲染。

这是我用来渲染到屏幕的 C++ 循环。它绑定一个纹理,写入一个黄色纹素,然后渲染一个全屏四边形。有两种变体:当MAKE_ONCE定义时,纹理在循环之前生成一次。如果未定义,则循环的每次迭代都会生成一个新纹理:

MyTestFun(void)
{
  glm::vec4 yellow = glm::vec4(1.0, 1.0, 0.0, 1.0); 

#ifdef MAKE_ONCE
  renderer->InitFrame();  //sets current OpenGL context 
  GLuint name = 0;
  glGenTextures(1, &name);   
  renderer->EndFrame();  
#endif

  while(1)
  {     
    renderer->InitFrame();

#ifndef MAKE_ONCE
    GLuint name =0;
    glGenTextures(1, &name);   
#endif

    glBindTexture(GL_TEXTURE_2D, name);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_FLOAT,
                 glm::value_ptr(yellow));

    glBindTexture(GL_TEXTURE_2D, 0);

    glBindImageTexture(SMALL_IMAGE_ONE_UNIT, name, 0, false, 0, GL_READ_ONLY,
                       GL_RGBA8);


    renderer->FullscreenQuad(); //shades using the frag shader shown above

    //bind the default texture to the image unit, hopefully freeing ours for editing
    glBindImageTexture(SMALL_IMAGE_ONE_UNIT, 0, 0, false, 0, GL_READ_WRITE,
                       GL_RGBA8);

    renderer->EndFrame();
  }
}

定义时MAKE_ONCE,第一帧显示从白色到黄色的垂直渐变,但随后的帧显示从蓝色到黑色的垂直渐变,表示IMAGE_LOAD调用返回 0.0。

MAKE_ONCE未定义时,例如在每一帧上重新制作纹理,程序将按预期运行,在每一帧上显示相同的白色<->黄色渐变。

什么可能导致这种行为?OpenGL 4.2 规范说,imageLoad如果图像处于无效状态 (p255-266),则调用将返回黑色(全零),但此处似乎没有任何有效条件。

4

0 回答 0