【问题标题】:OpenGL Stereo: alternating between left and right texturesOpenGL Stereo:在左右纹理之间交替
【发布时间】:2014-08-16 03:47:45
【问题描述】:

我正在使用 openGL quad 缓冲区来渲染立体 3D 图像(我对 openGL 非常陌生)。

我遇到了一个关于如何为每个后台缓冲区定义输出纹理的问题,我假设这是通过定义输出颜色(对应于指定的纹理)在片段缓冲区中完成的。

这是我用于着色器源的代码:

// Shader sources
const GLchar* vertexSource =
    "#version 150 core\n"
    "in vec2 position;"
    "in vec3 color;"
    "in vec2 texcoord;"
    "out vec3 Color;"
    "out vec2 Texcoord;"
    "void main() {"
    " Color = color;"
    " Texcoord = texcoord;"
    " gl_Position = vec4(position, 0.0, 1.0);"
  "}"; // Vertex buffer source
const GLchar* fragmentSource =
    "#version 150 core\n"
    "in vec3 Color;"
    "in vec2 Texcoord;"
    "out vec4 outColor;"
    "uniform sampler2D texRight;"
    "uniform sampler2D texLeft;"
    "void main() {"
    " outColor = texture(texRight, Texcoord);"
    " outColor = texture(texLeft, Texcoord);"
  "}"; // Fragment buffer source

这是我用来填充后台缓冲区的代码,我在 freeglut 上下文窗口的显示函数中使用它。

 // Clear Buffers
    glDrawBuffer(GL_BACK);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.0f, 0.0f, 0.0f,1.0f);

    cudaGLMapBufferObject((void**)d_glpointer, pbo);

    cudaGLMapBufferObject((void**)d_glpointer, pbo_Right);
    //...

    // Unmap buffer object
    cudaGLUnmapBufferObject(pbo);
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pbo);

    glDrawBuffer(GL_BACK_LEFT);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texturesID[1]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,NULL); // NULL specifies that the image is in memory

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glUniform1i(glGetUniformLocation(shaderProgram, "texLeft"), 1);

    // Draw a rectangle from the 2 triangles using 6 indices
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);


    // Unmap buffer object
    cudaGLUnmapBufferObject(pbo_Right);
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pbo_Right);

   // Draw Back Buffers
    glDrawBuffer(GL_BACK_RIGHT);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texturesID[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,NULL); // NULL specifies that the image is in memory

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glUniform1i(glGetUniformLocation(shaderProgram, "texRight"), 0);

    // Draw a rectangle from the 2 triangles using 6 indices
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    // Swap buffers
    glutSwapBuffers();

通过使用此代码,我只能看到定义的最后一个 outcolor,但我无法根据我使用的缓冲区找出在 outColor 定义之间进行选择的功能方法。

我正在使用 Cuda 将图像放入内存,但问题似乎与此映射无关,因为我总是能够看到与着色器外色中最后定义的纹理相关联的图像。

如果您能帮我解决这个问题,我将不胜感激。

编辑 1: 我在着色器中添加了一个计数器,用于验证帧计数 (texCount) 是偶数还是奇数。虽然,我现在没有输出图像。

#version 150 core
in vec3 Color;
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D texRight;
uniform sampler2D texLeft;
uniform int texCount=1;

void main() {
if (texCount%2){ // if texCount division by two is exact then this is false
    outColor = texture(texLeft, Texcoord);
}else{
    outColor = texture(texRight, Texcoord);
}
texCount++;
}

【问题讨论】:

  • 如果我理解正确,您希望交替显示两个纹理,即偶数帧上的纹理 0 和奇数帧上的纹理 1? (或texLefttexRight)。
  • 是的,这正是我想要做的。虽然只显示纹理 1(“texleft”)。
  • 是否可以在片段着色器中添加一个统一指示必须使用哪个纹理(0 或 1),并在每帧更新该值(类似于frame_counter % 2)?
  • 我在 glBindBuffer 之后添加了一个从 0 变为 1 的标志(GLuint texCount),我的片段着色器现在如下所示,但现在我没有显示图像:#version 150 core in vec3 颜色;在 vec2 Texcoord 中; out vec4 outColor;统一的 sampler2D texRight;统一的sampler2D texLeft; void main() { if (texCount==1){ outColor = texture(texLeft, Texcoord); }else if (texCount==0){ outColor = texture(texRight, Texcoord); } }
  • 嗯,没有任何输出也就不足为奇了。您的新着色器使用未定义的变量,因此无法编译。顺便说一句,您应该编辑您的问题以包含任何更改,而不是将它们放在无法阅读的 cmets 中。

标签: c++ opengl cuda stereo-3d


【解决方案1】:

我认为以下应该可行。

新的片段着色器:

#version 150 core in vec3 Color;
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D texIndex;
void main() {
    outColor = texture(texIndex, Texcoord); 
}

然后将代码中的”texLeft””texRight” 替换为”texIndex”

请注意,如果纹理是静态的,则不必在每一帧上传纹理。理想情况下,您会将只需要执行一次的所有命令放在设置函数中,只有在操作系统通知窗口重塑时才会执行。

【讨论】:

  • 非常感谢,它就像一个魅力。在这种特殊情况下,我将目录中的多个图像渲染到纹理中,因此我需要在每一帧进行纹理上传。
  • 您可能希望为outColor 分配一个值,否则此着色器不会做太多事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 2014-11-21
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
  • 2019-11-20
相关资源
最近更新 更多