在OpenGL 3.2/GLSL 1.50中写入纹理,然后将纹理写入屏幕
我想在OpenGL中实现延迟着色 我有一个支持OpenGL的框架。使用典型的顶点着色器和片段着色器进行正向着色效果良好,缩放和变换没有问题 但实现延迟着色会导致一个问题,即我看不到任何东西,也不知道是否在FBO中写入纹理 在我的渲染方法中,我解除了FBO的绑定以直接写入屏幕。它工作正常,一切看起来都很棒。但是绑定FBO、写入纹理以及尝试将纹理写入屏幕只会给我一个空白屏幕 所以我的问题是:我能正确处理不同纹理的平行书写吗 initialize方法创建所有着色器程序,并将VBO绑定到着色器的输入 渲染方法分为延迟{}块和非延迟{}着色器块。非延迟着色是一个简单的正向着色概念 我使用OpenGL 3.2/GLSL 1.50 由于GLSL 1.50不支持布局(位置),我认为它应该能够将片段着色器输出绑定到不同的颜色(请参见initialize()方法) 创建缓冲区将成功完成GL_帧缓冲区 下面是我的initialize()方法: 这是我的渲染方法:在OpenGL 3.2/GLSL 1.50中写入纹理,然后将纹理写入屏幕,opengl,glsl,fragment-shader,vertex-shader,fbo,Opengl,Glsl,Fragment Shader,Vertex Shader,Fbo,我想在OpenGL中实现延迟着色 我有一个支持OpenGL的框架。使用典型的顶点着色器和片段着色器进行正向着色效果良好,缩放和变换没有问题 但实现延迟着色会导致一个问题,即我看不到任何东西,也不知道是否在FBO中写入纹理 在我的渲染方法中,我解除了FBO的绑定以直接写入屏幕。它工作正常,一切看起来都很棒。但是绑定FBO、写入纹理以及尝试将纹理写入屏幕只会给我一个空白屏幕 所以我的问题是:我能正确处理不同纹理的平行书写吗 initialize方法创建所有着色器程序,并将VBO绑定到着色器的输入 渲
doLightAnimationStep();
// Create matrices
//QMatrix4x4 modelMatrix = createMouseViewMatrix();
//QMatrix4x4 mouseViewMatrix = createViewMatrix();
//QMatrix4x4 projectionMatrix = createProjectionMatrix();
QMatrix4x4 mvpMatrix = createProjectionMatrix() * createMouseViewMatrix();
QMatrix4x4 viewportMatrix = MatrixHandler::createScaleMatrix(
10.f / scaling, 10.f / scaling, 10.f / scaling);
if(deferredShading) {
// Bind FBO to context and clear all buffers before rendering
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
//glViewport(0, 0, viewWidth, viewHeight);
GLenum windowBufferSelector[] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2 };
glDrawBuffers(3, windowBufferSelector); // Select all buffers
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set everything to zero.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
printError("Bound FBO and depth buffer");
// First render stage -> writing all data into the textures and the depth buffer
glUseProgram(firstStageProgram_ID);
// Set uniforms
glUniformMatrix4fv(uniform_mvpMatrix_first_stage_ID, 1, GL_FALSE, mvpMatrix.data());
glUniformMatrix4fv(uniform_viewportMatrix_first_stage_ID, 1, GL_FALSE, viewportMatrix.data());
printError("Prepared buffer 0, 1 and 2 for writing");
//DrawTheWorld(); // Will also produce depth data in the depth buffer
glBindVertexArray(VAO_deferred); // VAO aktivieren
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glBindVertexArray(0);
printError("Wrote into buffer 0, 1 and 2");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Deferred render stage -> read the data for all pixels from the textures and the depth buffer to calculate the color for the pixel
// The depth buffer from stage 1 is not used now as the fbo is disabled.
// Clearing the active buffer means clearing the screen
glClearColor(255.0f, 255.0f, 255.0f, 0.0f); // Set everything to zero.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//EnableRenderProgramDeferredStage();
glUseProgram(deferredStageProgram_ID);
//SetupDeferredStageUniforms();
printError("Setting uniforms for deferred stage vertex shader.");
glBindTexture(GL_TEXTURE_2D, fDiffuseTexture);
glUniform1i(uniform_diffuseTexture_ID, fDiffuseTexture);
//glUniform1i(uniform_positionTexture_ID, fPositionTexture);
//glUniform1i(uniform_normalTexture_ID, fNormalsTexture);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, fNormalsTexture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fPositionTexture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fDiffuseTexture);
printError("Setted uniforms for deferred stage vertex shader.");
glBindVertexArray(VAO_texture); // VAO aktivieren
glDrawArrays(GL_TRIANGLES, 0, 2);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);
printError("End of deffered shading rendering");
} else {
// Enable and disable z-buffering and backface culling
if(zBuffering) {
if(!(glIsEnabled(GL_DEPTH_TEST) == GL_TRUE)) {
glEnable(GL_DEPTH_TEST);
}
} else {
if(glIsEnabled(GL_DEPTH_TEST) == GL_TRUE) {
glDisable(GL_DEPTH_TEST);
}
}
if(backfaceCulling) {
if(!(glIsEnabled(GL_CULL_FACE) == GL_TRUE)) {
glEnable(GL_CULL_FACE);
}
} else {
if(glIsEnabled(GL_CULL_FACE) == GL_TRUE) {
glDisable(GL_CULL_FACE);
}
}
glClearColor(255, 255, 255, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use shader program
glUseProgram(program_ID);
glBindTexture(GL_TEXTURE_2D, texture_ID);
glUniform1i(samplerTexture_ID, 0);
if(textureMode == CLAMP) {
// Werte auf kleiner 0 auf 0 beschränken , Werte größer 1 auf 1:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} else if(textureMode == REPEAT) {
// Texturen wiederholen
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
} else if(textureMode == MIRRORED_REPEAT) {
// Texturen wiederholen, die Koordinaten jedoch an den Grenzen ”spiegeln ”
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
} else {
// Should never be reached!
assert(false);
}
if(filterMode == NEAREST_NEIGHBOUR) {
// Für Nearest−Neighbor Filterung (wie im Software−Renderer)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
} else if (filterMode == LINEAR) {
// Für Lineare Filterung (qualitativhochwertiger)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else if (filterMode == MIPMAPPING) {
// Mipmapping (weniger Aliasing Artefakte, aber höherer Speicherbedarf)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
} else {
// Should never be reached!
assert(false);
}
glUniformMatrix4fv(mvpMatrix_ID, 1, GL_FALSE, mvpMatrix.data());
glUniformMatrix4fv(viewportMatrix_ID, 1, GL_FALSE, viewportMatrix.data());
//float light_dist_f = (float)light_dist/100.f;
//GLfloat lightPos__vec [3] = {light_dist_f*(float) cos(Math::toRadian(light_angle)), light_dist_f*(float) sin(Math::toRadian(light_angle)),light_dist_f};
//glUniform3fv(lightPos_ID, 1, lightPos__vec);
GLfloat lightPos__vec [3] = {lights[0].position.x(), lights[0].position.y(), lights[0].position.z()};
glUniform3fv(lightPos_ID, 1, lightPos__vec);
GLfloat intensity = ((GLfloat)light_intensity/(GLfloat)100);
glUniform1fv(lightInt_ID, 1, &intensity);
GLfloat ambient = ((GLfloat)light_ambient/(GLfloat)100);
glUniform1fv(lightAmb_ID, 1, &ambient);
glBindVertexArray(VAO); // VAO aktivieren
glDrawArrays(GL_TRIANGLES, 0 , vertexCount);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);
}
每次更改框架的大小时,我都会更改视口和FBO+纹理的大小
sizeChanged()
:
第一阶段片段着色器:
#version 150
precision mediump float;
uniform sampler2D firstTexture;
in vec4 position_varying; // The model coordinate, as given by the vertex shader
in vec3 color_varying; // The interpolated color of the fragment
in vec3 normal_varying; // The interpolated normal of the fragment
in vec2 texCoord_varying; // The interpolated texture coordinates of the fragment
// To be written into texture buffers
out vec4 out_position; // layout(location = 0)
out vec3 out_normal; // layout(location = 1)
out vec3 out_diffuse; // layout(location = 2)
/*
* The first stage shader program performs geometric calculations.
* Light calculations are done in the second stage, the deferred stage shader
* program.
*/
// Output the model-transformed vertex-coordinates
// Output normal (normalized)
void main(void) {
out_position = position_varying; // Position given by the vertext shader
out_normal = normal_varying;
out_diffuse = color_varying;
/*
// The blending is not necessary in calculation with the GDV framework
// as there are no transparent models
vec4 clr = texture(firstTexture, texCoord_varying);
out_diffuse = clr;
*/
}
#version 150
precision mediump float;
uniform sampler2D positionTexture; // World position
uniform sampler2D normalTexture; // Normals
uniform sampler2D diffuseTexture; // The color information
// Not used?
//uniform vec3 camera; // The coordinate of the camera
in vec2 texture_varying; // The world position
out vec4 fragColor; // layout(location = 0)
/*
* The first stage shader program performs geometric calculations.
* Light calculations are done in the second stage, the deferred stage shader
* program.
*/
void main(void) {
// Load data, stored in textures, from the first stage rendering.
// Color
fragColor = texture2D(diffuseTexture, texture_varying);
//fragColor = vec4(0, 0, 0, 1);
//vec4 worldPos = texture(positionTexture, texture_varying.xy);
// Normals
//fragColor = texture(normalTexture, texture_varying.xy);
// Use information about lamp coordinate (not shown here), the pixel
// coordinate (worldpos.xyz), the normal of this pixel (normal.xyz)
// to compute a lighting effect.
// Use this lighting effect to update 'diffuse'
//vec4 preBlend = diffuse * lamp + specularGlare;
//fragColor = (normal+1)/2;
//fragColor = diffuse;
//fragColor = worldPos; // Scaling may be needed to range [0,1]
//fragColor = lamp*vec4(1,1,1,1);
}
延迟阶段顶点着色器:
#version 150
precision mediump float;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 MVPMatrix;
uniform mat4 viewportMatrix;
in vec4 in_position;
in vec3 in_color;
in vec3 in_normal;
in vec2 in_texCoord;
in float in_intensity; // Sun light
in float in_ambient;
out vec4 position_varying;
out vec3 color_varying;
out vec3 normal_varying;
out vec2 texCoord_varying;
out float extIntensity_varying;
out float extAmbientLight_varying;
/*
* The first stage shader program performs geometric calculations.
* Light calculations are done in the second stage, the deferred stage shader
* program.
*/
// Texture coordinates are applied to the first stage fragment shader.
// The normal vector is being transformed in world coordinates.
// gl_Position is being calculated with the MVP matrix in screen coordinates
// The intensity of the sun is in range [0;255], perhaps this has to be adjusted
// The ambient light is in the range of [0;255] aswell, perhaps this has to be
// adjusted too.
void main(void) {
gl_Position = viewportMatrix * (MVPMatrix * in_position);
color_varying = in_color;
normal_varying = in_normal;
texCoord_varying = in_texCoord;
// Not used right now
//extIntensity_varying = in_intensity;
//extAmbientLight_varying = in_ambient;
/*
normal_varying = normalize((modelMatrix*vec4(in_normal, 0.0)));
gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_vertex;
position_varying = vec3(modelMatrix * in_vertex); // Copy position to the fragment shader
extIntensity_varying = in_intensity/255.0; // Scale the intensity from [0..255] to [0..1].
extAmbientLight_varying = in_ambientLight/255.0;
*/
}
#version 150
precision mediump float;
in vec2 in_texture_vertex;
out vec2 texture_varying;
/*
* The first stage shader program performs geometric calculations.
* Light calculations are done in the second stage, the deferred stage shader
* program.
*/
void main(void) {
// Why is there a calculation in_vertex*2-1?
gl_Position = vec4(in_texture_vertex.xy, 0.f, 0.f);
// Copy position to the fragment shader. Only x and y is needed.
texture_varying = in_texture_vertex;
}
延迟阶段片段着色器:
#version 150
precision mediump float;
uniform sampler2D firstTexture;
in vec4 position_varying; // The model coordinate, as given by the vertex shader
in vec3 color_varying; // The interpolated color of the fragment
in vec3 normal_varying; // The interpolated normal of the fragment
in vec2 texCoord_varying; // The interpolated texture coordinates of the fragment
// To be written into texture buffers
out vec4 out_position; // layout(location = 0)
out vec3 out_normal; // layout(location = 1)
out vec3 out_diffuse; // layout(location = 2)
/*
* The first stage shader program performs geometric calculations.
* Light calculations are done in the second stage, the deferred stage shader
* program.
*/
// Output the model-transformed vertex-coordinates
// Output normal (normalized)
void main(void) {
out_position = position_varying; // Position given by the vertext shader
out_normal = normal_varying;
out_diffuse = color_varying;
/*
// The blending is not necessary in calculation with the GDV framework
// as there are no transparent models
vec4 clr = texture(firstTexture, texCoord_varying);
out_diffuse = clr;
*/
}
#version 150
precision mediump float;
uniform sampler2D positionTexture; // World position
uniform sampler2D normalTexture; // Normals
uniform sampler2D diffuseTexture; // The color information
// Not used?
//uniform vec3 camera; // The coordinate of the camera
in vec2 texture_varying; // The world position
out vec4 fragColor; // layout(location = 0)
/*
* The first stage shader program performs geometric calculations.
* Light calculations are done in the second stage, the deferred stage shader
* program.
*/
void main(void) {
// Load data, stored in textures, from the first stage rendering.
// Color
fragColor = texture2D(diffuseTexture, texture_varying);
//fragColor = vec4(0, 0, 0, 1);
//vec4 worldPos = texture(positionTexture, texture_varying.xy);
// Normals
//fragColor = texture(normalTexture, texture_varying.xy);
// Use information about lamp coordinate (not shown here), the pixel
// coordinate (worldpos.xyz), the normal of this pixel (normal.xyz)
// to compute a lighting effect.
// Use this lighting effect to update 'diffuse'
//vec4 preBlend = diffuse * lamp + specularGlare;
//fragColor = (normal+1)/2;
//fragColor = diffuse;
//fragColor = worldPos; // Scaling may be needed to range [0,1]
//fragColor = lamp*vec4(1,1,1,1);
}
我注意到的一件事是这个绘图调用:
gldrawArray(GL\u三角形,0,2)
。为绘制三角形指定2个顶点将不会渲染任何内容。不确定这是否是唯一的问题。有很多代码,我还没有全部看过。另一件需要注意的事情是,在第二遍采样之前,在所有纹理上设置过滤模式。你是对的,这是错误之一。我想出来了,现在它正在工作,但我会解释:-一定要画3个或更多的顶点来画一个三角形绑定你的纹理,然后按如下方式设置你的制服:glUniform1i(uniform\u diffuseTexture\u ID,0)代码>而不是类似于glUniform1i(均匀扩散纹理,myTexture)代码>-对于延迟着色,请考虑第二个着色器阶段中的坐标!确保获得了均匀坐标,并按如下方式进行计算:gl\u Position=-1+2*vec4(in\u texture\u vertex.xy,0.f,1.f)代码>