Opengl 将glortho与着色器代码结合使用 编辑+摘要以提高清晰度:
我的代码就是这样做的:给定一个图像,它会修改它(使用着色器)。它将其输出到纹理。然后,一个旧的opengl代码(使用glOrtho)移动并重新缩放该图像,使其显示在屏幕上 我的问题:如何更改当前着色器代码以包含此转换和重缩放?Opengl 将glortho与着色器代码结合使用 编辑+摘要以提高清晰度:,opengl,shader,gpu,fbo,Opengl,Shader,Gpu,Fbo,我的代码就是这样做的:给定一个图像,它会修改它(使用着色器)。它将其输出到纹理。然后,一个旧的opengl代码(使用glOrtho)移动并重新缩放该图像,使其显示在屏幕上 我的问题:如何更改当前着色器代码以包含此转换和重缩放? 我当前的管道是这样的(请参见下面的代码): 图像-->现代opengl处理-->渲染到纹理T-->使用旧opengl将纹理T渲染到屏幕上 但我希望它是这样的: 图像-->现代opengl处理-->现代opengl直接渲染到屏幕给定坐标 所以基本上我的问题是: 给定屏幕坐
我当前的管道是这样的(请参见下面的代码): 图像-->现代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);
}
为什么会出现这段复杂的代码: 您所要做的(据我所知)是,您的纹理四边形覆盖整个视口。没有比这更容易的了。与正交投影和某些modelview变换不同,只需使用标识变换并直接在剪辑空间中指定顶点。视口的边界始终是NDC空间的坐标-1和1。通过剪辑空间==ND空间进行身份转换
因此,只需使用顶点位置(-1,-1)、(1,-1)、(1,1)和(-1,1),并将它们直接传递到顶点着色器中的
gl\u位置。等等,又是什么问题?我在上面添加了一个解释。我正在修改现有图像。然后,glOrtho代码移动并将此图像重新缩放到屏幕上应显示的位置。如何更改当前代码以包含此翻译和重缩放?代码是复杂的,因为我已经进入了旧的opengl代码的中间呈现。我需要使用着色器来增强图像(使用gpgpu);但不想改变整个管道。这个代码实际上是有效的;我只是想节省一些处理时间。所以-我想直接在屏幕上渲染,而不是FBO,然后再次在屏幕上渲染。@zuuz:你们有窗口像素坐标中的坐标吗?如果是这样,只需使用glViewport将其放置在窗口中。如果它是相对于视口的,那么您的方法不错,但是保持顶点z=0,并使用GLM、Eigen(GL)、linmath.h或类似函数构建的正交投影矩阵使用near=-1、far=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();