【问题标题】:combine glortho with shader code将 glortho 与着色器代码相结合
【发布时间】:2014-11-19 22:59:00
【问题描述】:

编辑 + 总结更清晰:

我的代码是这样做的:给定一个图像,它会修改它(使用着色器)。它将其输出到纹理。然后一个旧的 opengl 代码(使用 glOrtho)移动并重新缩放这个图像到它应该在屏幕上显示的位置。

我的问题:如何更改我当前的着色器代码以包含此转换和重新缩放?


我目前的管道是这样的(见下面的代码):

图像 --> 现代 opengl 处理 --> 渲染到纹理 T --> 使用旧的 opengl 将纹理 T 渲染到屏幕

但我希望它是这样的:

图像 --> 现代 opengl 处理 --> 现代 opengl 直接渲染到屏幕给定坐标

所以基本上我的问题是:

给定 glOrtho 中的屏幕坐标,如何更改下面的着色器代码以渲染到给定坐标,同时仍执行我的增强功能?

这是我当前代码的草图:

//render to texture T
RenderEnhancementIntoTexture(T);  

//bind this texture:
glBindTexture(GL_TEXTURE_2D, T);

//clean-up shaders, vertices, return to fixed-pipeline:
glBindFramebuffer(GL_FRAMEBUFFER,0);
glUseProgram(0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);


//position the canvas on screen based on the gui:
glOrtho(l, r, b, t, 0, 10.0);

//use this texture to paint on the screen segment:
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(left, bottom,  -5);    // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( right, bottom,  -5);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( right, top,  -5); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(left,  top,  -5);  // Top Left Of The Texture and Quad
glEnd();

以及着色器代码:

顶点着色器:

#version 330 core

in vec2 VertexPosition;
uniform vec2 u_step;
void main(void) {
  gl_Position = vec4(VertexPosition, 0.0, 1.0);
}

和片段着色器:

//simple example - just output the pixel value:
#version 330 core
uniform sampler2D image;
uniform vec2 u_step;
out vec4 FragmentColor;

void main(void)
{
  vec3 accum = texture( image, vec2(gl_FragCoord)*u_step ).rgb;
  FragmentColor = vec4(accum , 1.0);
}

以及初始化顶点的代码:

void initVAO(void)
{
    GLuint positionLocation = 0;

    GLfloat vertices[] =
    { 
        -1.0f, -1.0f, 
        1.0f, -1.0f, 
        1.0f,  1.0f, 
        -1.0f,  1.0f, 
    };

    GLushort indices[] = { 0, 1, 3, 3, 1, 2 };

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer((GLuint)positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); 
    glEnableVertexAttribArray(positionLocation);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexBufferObjID[2]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
}

【问题讨论】:

  • 等等,又是什么问题?
  • 我在上面添加了解释。

标签: opengl shader gpu fbo


【解决方案1】:

为什么会有这么复杂的代码:

//position the canvas on screen based on the gui:
glOrtho(l, r, b, t, 0, 10.0);

//use this texture to paint on the screen segment:
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(left, bottom,  -5);    // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( right, bottom,  -5);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( right, top,  -5); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(left,  top,  -5);  // Top Left Of The Texture and Quad
glEnd();

您想要做的(据我所知)是,您的纹理四边形覆盖整个视口。好吧,没有比这更容易的了。而不是正交投影和一些模型视图转换,只需使用恒等转换并直接在剪辑空间中指定顶点。视口的边界始终是 NDC 空间的坐标 -1 和 1。并且在整个剪辑空间 == ND 空间中进行恒等变换。

所以只需使用顶点位置 (-1,-1)、(1,-1)、(1,1) 和 (-1,1) 并将它们直接传递给顶点着色器中的gl_Position

【讨论】:

  • 我正在修改现有图像。然后 glOrtho 代码将该图像移动并重新缩放到它应该在屏幕上显示的位置。如何更改我当前的代码以包含此翻译和重新缩放?代码很复杂,因为我已经进入了渲染的旧 opengl 代码的中间。我需要使用着色器来增强图像(使用 gpgpu);但不想改变整个管道。这段代码确实有效;我只是想节省一些处理以节省时间。因此 - 我想直接在屏幕上渲染,而不是 FBO,然后再次屏幕。
  • @zuuz:你有窗口像素坐标中的坐标吗?如果是这样,只需使用 glViewport 将其放置在窗口中。如果它相对于视口很好,那么您的方法还不错,但保持顶点 z=0 并使用 near=-1, far=1 用于您使用 GLM、Eigen (GL) 提供的函数构建的正射投影矩阵, linmath.h 或类似的。
猜你喜欢
  • 1970-01-01
  • 2013-10-03
  • 1970-01-01
  • 2021-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多