我在 Orwell Dev-C++ 5.4.0 上用 GLEW 和 GLFW 制作了一个 OpenGL 程序,它显示了块。我添加了环境光、漫反射光和镜面光,现在也添加了阴影。我使用了深度纹理。但是现在,方块不会在其他方块上投射阴影,而只会投射在它们自己身上!
这是我的源代码的重要部分:
void createShadows()
{
int error;
glGenFramebuffers(1, &buffers.depthFbo);
glBindFramebuffer(GL_FRAMEBUFFER, buffers.depthFbo);
glGenTextures(1, &buffers.depthTbo);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, buffers.depthTbo);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, winInfo.winWidth, winInfo.winHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, buffers.depthTbo, 0);
glDrawBuffer(GL_NONE);
error = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(error != GL_FRAMEBUFFER_COMPLETE)
printError("FramebufferError.txt", "Framebuffer", error);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void init()
{
renderProg = compileShaders("openglSuperTutorials12.vss", "openglSuperTutorials12.fss", 0);
renderProgDepth = compileShaders("openglSuperTutorials12_depth.vss", "openglSuperTutorials12_depth.fss", 0);
glGenVertexArrays(1, &buffers.vao);
glBindVertexArray(buffers.vao);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
matrices.mMatrixDepth = glm::mat4(1.0f);
matrices.pMatrixDepth = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 20.0f);
matrices.biasMatrixDepth = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f);
//Initialize light and material properties and give them to the "renderProg" (truncated)
glfwGetWindowSize(window, &winInfo.winWidth, &winInfo.winHeight);
glfwSetCursorPos(window, winInfo.winWidth/2.0, winInfo.winHeight/2.0);
createTexture();
createVertices();
createBlocks();
createShadows();
}
void setBlock(glm::vec3 position, int id, int depth)
{
if(depth != 1)
{
matrices.mMatrix = glm::translate(glm::mat4(1.0f), position);
matrices.mvpMatrixBiasDepth = matrices.biasMatrixDepth * matrices.mvpMatrixDepth;
glUniformMatrix4fv(glGetUniformLocation(renderProg, "mMatrix"), 1, GL_FALSE, &matrices.mMatrix[0][0]);
glUniformMatrix4fv(glGetUniformLocation(renderProg, "mvpMatrixBiasDepth"), 1, GL_FALSE, &matrices.mvpMatrixBiasDepth[0][0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, buffers.tbo);
glUniform1i(glGetUniformLocation(renderProg, "texBlock"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, buffers.depthTbo);
glUniform1i(glGetUniformLocation(renderProg, "shadowMap"), 1);
glGenBuffers(1, &buffers.tcbo);
glBindBuffer(GL_ARRAY_BUFFER, buffers.tcbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(blocks[id]), blocks[id], GL_DYNAMIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1);
}
else
{
matrices.mvpMatrixDepth = matrices.pMatrixDepth * matrices.vMatrixDepth * matrices.mMatrixDepth;
glUniformMatrix4fv(glGetUniformLocation(renderProgDepth, "mvpMatrixDepth"), 1, GL_FALSE, &matrices.mvpMatrixDepth[0][0]);
}
glDrawArrays(GL_TRIANGLES, 0, 36);
if(depth != 1)
{
glDisableVertexAttribArray(1);
glDeleteBuffers(1, &buffers.tcbo);
}
}
void display()
{
int x, y, z;
GLfloat bgColor[] = { 0.0f, 0.73f, 1.0f, 1.0f };
GLfloat depthOne = 1.0f;
glBindFramebuffer(GL_FRAMEBUFFER, buffers.depthFbo);
glClearBufferfv(GL_DEPTH, 0, &depthOne);
glUseProgram(renderProgDepth);
glEnableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
if(viewPos.lightSticky == 1)
{
lightProperties.lightPosition = glm::vec3(viewPos.eyeX, viewPos.eyeY, viewPos.eyeZ);
lightProperties.lightDirection = glm::vec3(viewPos.centerX, viewPos.centerY, viewPos.centerZ);
}
matrices.vMatrixDepth = glm::lookAt(
lightProperties.lightPosition,
lightProperties.lightDirection,
glm::vec3(viewPos.upX, viewPos.upY, viewPos.upZ));
for(z=-5; z<=5; z++)
{
for(y=0; y<=6; y++)
{
for(x=-5; x<=5; x++)
{
if(blockMap[z+5][y][x+5].id != -1)
setBlock(blockMap[z+5][y][x+5].position, blockMap[z+5][y][x+5].id, 1);
}
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearBufferfv(GL_COLOR, 0, bgColor);
glClearBufferfv(GL_DEPTH, 0, &depthOne);
glUseProgram(renderProg);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
lightProperties.cameraPosition = glm::vec3(viewPos.eyeX, viewPos.eyeY, viewPos.eyeZ);
matrices.vMatrix = glm::lookAt(glm::vec3(viewPos.eyeX, viewPos.eyeY, viewPos.eyeZ),
glm::vec3(viewPos.centerX, viewPos.centerY, viewPos.centerZ),
glm::vec3(viewPos.upX, viewPos.upY, viewPos.upZ));
matrices.pMatrix = glm::perspective(45.0f, (GLfloat)winInfo.winWidth/(GLfloat)winInfo.winHeight, 0.1f, 1000.0f);
glUniformMatrix4fv(glGetUniformLocation(renderProg, "vMatrix"), 1, GL_FALSE, &matrices.vMatrix[0][0]);
glUniformMatrix4fv(glGetUniformLocation(renderProg, "pMatrix"), 1, GL_FALSE, &matrices.pMatrix[0][0]);
//Update light uniforms (truncated)
for(z=-5; z<=5; z++)
{
for(y=0; y<=6; y++)
{
for(x=-5; x<=5; x++)
{
if(blockMap[z+5][y][x+5].id != -1)
setBlock(blockMap[z+5][y][x+5].position, blockMap[z+5][y][x+5].id, 0);
}
}
}
glfwSwapBuffers(window);
winInfo.frames++;
}
顶点着色器“openglSuperTutorials12.vss”:
#version 430 core
layout (location = 0) in vec3 vPosition;
layout (location = 1) in vec2 vTexCoord;
layout (location = 2) in vec3 vNormal;
out vec3 fPosition;
out vec4 fShadowCoord;
out vec2 fTexCoord;
out vec3 fNormal;
uniform mat4 mMatrix;
uniform mat4 vMatrix;
uniform mat4 pMatrix;
uniform mat4 mvpMatrixBiasDepth;
void main()
{
gl_Position = pMatrix * vMatrix * mMatrix * vec4(vPosition, 1.0);
fPosition = vPosition;
fShadowCoord = mvpMatrixBiasDepth * vec4(vPosition, 1.0);
fTexCoord = vTexCoord;
fNormal = normalize(transpose(inverse(mat3(mMatrix))) * vNormal);
}
片段着色器“openglSuperTutorials12.fss”:
#version 430 core
in vec3 fPosition;
in vec4 fShadowCoord;
in vec2 fTexCoord;
in vec3 fNormal;
out vec4 outColor;
uniform sampler2D texBlock;
uniform sampler2D shadowMap;
uniform mat4 mMatrix;
uniform int ambientLightEnabled;
uniform int diffuseLightEnabled;
uniform int specularLightEnabled;
uniform int shadowsEnabled;
uniform vec3 ambientLightColor;
uniform vec3 diffuseLightColor;
uniform vec3 specularLightColor;
uniform vec3 lightPosition;
uniform vec3 cameraPosition;
uniform float lightAttenuation;
uniform vec3 spotlightConeDirection;
uniform float spotlightCosCutoff;
uniform float spotlightExponent;
uniform vec3 ambientMaterialColor;
uniform vec3 diffuseMaterialColor;
uniform vec3 specularMaterialColor;
uniform float shininess;
uniform float strength;
void main()
{
vec3 shadowValue = vec3(textureProj(shadowMap, fShadowCoord));
vec3 surfacePos = vec3(mMatrix * vec4(fPosition, 1.0));
vec3 surfaceToLight = normalize(lightPosition - surfacePos);
vec3 surfaceToCamera = normalize(cameraPosition - surfacePos);
vec3 ambientColor = ambientMaterialColor * ambientLightColor;
float diffuseIntensity = max(0.0, dot(fNormal, surfaceToLight));
vec3 diffuseColor = diffuseIntensity * diffuseLightColor * diffuseMaterialColor;
float specularIntensity;
if(diffuseIntensity == 0.0)
specularIntensity = 0.0;
else
specularIntensity = pow(max(0.0, dot(fNormal, normalize(surfaceToLight + surfaceToCamera))), shininess) * strength;
vec3 specularColor = specularIntensity * specularLightColor * specularMaterialColor;
float distanceToLight = length(surfacePos - lightPosition);
float attenuation = 1.0 / (
lightAttenuation +
lightAttenuation * distanceToLight +
lightAttenuation * distanceToLight * distanceToLight);
vec3 lightColorCombined = vec3(0.0);
if(ambientLightEnabled == 1)
{
lightColorCombined += ambientColor;
}
if(diffuseLightEnabled == 1)
{
if(shadowsEnabled == 1)
diffuseColor *= shadowValue;
lightColorCombined += diffuseColor;
}
if(specularLightEnabled == 1)
{
if(shadowsEnabled == 1)
specularColor *= shadowValue;
lightColorCombined += attenuation * specularColor;
}
outColor = texture(texBlock, fTexCoord) * vec4(lightColorCombined, 1.0);
}
其他着色器(“openglSuperTutorials12_depth.vss”和“openglSuperTutorials12_depth.fss”)只是带有“mvpMatrixDepth”的简单直通着色器。
我必须改变什么才能让光线在其他物体上投射阴影?