Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在OpenGL 3.2/GLSL 1.50中写入纹理,然后将纹理写入屏幕_Opengl_Glsl_Fragment Shader_Vertex Shader_Fbo - Fatal编程技术网

在OpenGL 3.2/GLSL 1.50中写入纹理,然后将纹理写入屏幕

在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绑定到着色器的输入 渲

我想在OpenGL中实现延迟着色

我有一个支持OpenGL的框架。使用典型的顶点着色器和片段着色器进行正向着色效果良好,缩放和变换没有问题

但实现延迟着色会导致一个问题,即我看不到任何东西,也不知道是否在FBO中写入纹理

在我的渲染方法中,我解除了FBO的绑定以直接写入屏幕。它工作正常,一切看起来都很棒。但是绑定FBO、写入纹理以及尝试将纹理写入屏幕只会给我一个空白屏幕

所以我的问题是:我能正确处理不同纹理的平行书写吗

initialize方法创建所有着色器程序,并将VBO绑定到着色器的输入

渲染方法分为延迟{}块和非延迟{}着色器块。非延迟着色是一个简单的正向着色概念

我使用OpenGL 3.2/GLSL 1.50

由于GLSL 1.50不支持布局(位置),我认为它应该能够将片段着色器输出绑定到不同的颜色(请参见initialize()方法)

创建缓冲区将成功完成GL_帧缓冲区

下面是我的initialize()方法:

这是我的渲染方法:

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)