Hey guys, I worked long time ago in shadows but I left it because I couldn't find the problem I still have. I've been following this tutorial and I adapted it on my project but when I render everything I'm having weird issues I don't know why. As you can see in this pic the shadow projection is well calculated from the shader etc but you also can see that the back and front faces of both cubes are getting also weird shadow and also the shadow is repeated among the "terrain". This last problem is because of GL_REPEAT but if I use others parameters to create the texture it's worst... I tried using GL_CULLFACE to remove the weird shadows in the cubes but doesn't work. I'll leave the code here:
#include "../stdafx.h"
#include "Main.h"
#include "../Renderer/Renderer.h"
#include "../GLUtils/GLUtils.h"
#include "../Camera/Camera.h"
#include "../Audio/Audio.h"
#include "../Physics/Physics.h"
#include "../Skybox/Skybox.h"
#include "../Lighting/LightManager.h"
#include "../Entity/Entity.h"
#include "../Editor/Editor.h"
#include "../NativeGeometry/NativeGeometry.h"
#include "../Textures/TextureManager.h"
#include "../RenderTargets/RenderTargets.h"
#include "../ParticleSystem/ParticleSystem.h"
#include "../CEV/CEV.h"
#include "../Timers/Timers.h"
#include "../LUA/LuaManager.h"
#include "../LUA/EventManager.h"
#include "../LUA/EventArguments.h"
#include "../ColShapes/ColShapes.h"
#include "../KeyCode/Keycode.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//CoInitializeEx(nullptr, COINIT_MULTITHREADED); //wtf is this xd
Console.reset(new CConsole());
Console->AllocateConsole();
Renderer = std::make_unique<CRenderer>();
ColShapeManager = std::make_unique<CColShapeManager>();
Physics = std::make_unique<CPhysics>();
EventArguments = std::make_unique<CEventsArguments>();
LuaManager = std::make_unique<CLuaManager>();
EventManager = std::make_unique<CEventManager>();
KeyCode = std::make_unique<CKeyCode>();
RenderTargetManager = std::make_unique<CRenderTargetManager>();
TextureManager = std::make_unique<CTextureManager>();
EntityManager = std::make_unique<CEntityManager>();
FogManager = std::make_unique<CFogManager>();
LightManager = std::make_unique<CLightManager>();
Skybox = std::make_unique<CSkybox>();
Camera = std::make_unique<CCamera>(glm::vec3(10, 10, 10));
CEAudio = std::make_unique<CAEngine>();
GLUtils = std::make_unique<CGLUtils>();
if (!Renderer->CreateGLWindow(1920 / 2 - (1280 / 3) + 200, 1080 / 2 - (800 / 2), 1600, 1200, 16, false))
return 0;
Renderer.release();
ColShapeManager.release();
Physics.release();
EventArguments.release();
LuaManager.release();
EventManager.release();
KeyCode.release();
RenderTargetManager.release();
TextureManager.release();
EntityManager.release();
FogManager.release();
LightManager.release();
Skybox.release();
Camera.release();
CEAudio.release();
GLUtils.release();
return 0;
}
bool first = true;
BOOL DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
static GLuint depthMapFBO;
static GLuint SHADOW_WIDTH = 2048, SHADOW_HEIGHT = 2048;
static GLuint depthMap;
if (first)
{
glGenFramebuffers(1, &depthMapFBO);
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
first = false;
}
//SKYBOX RENDERING, LIGHT, FOG, CAMERA UPDATE & VIEWMATRIX UPDATE
Renderer->MainProgram.Start();
Camera->Update();
Renderer->SetViewMatrices();
Skybox->RenderSkybox();
LightManager->SetUpAmbientColor();
LightManager->UpdateLightsInShader(Renderer->MainProgram);
FogManager->RenderFog();
for (int i = 0; i < RenderTargetManager->GetRenderTargets(); i++)
{
CRenderTarget* RT = RenderTargetManager->GetRenderTarget(i);
if (RT)
{
RT->Bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RT->UpdateTrans();
Skybox->RenderSkybox();
RenderTargetManager->BackToNormalRenderer();
}
}
//SHADOWS
static float xx = 0, yy = 3.f, zz = 0;
if (GetAsyncKeyState(VK_NUMPAD8))
{
xx += 0.1f;
}
if (GetAsyncKeyState(VK_NUMPAD2))
{
xx -= 0.1f;
}
if (GetAsyncKeyState(VK_NUMPAD7))
{
yy += 0.1f;
}
if (GetAsyncKeyState(VK_NUMPAD1))
{
yy -= 0.1f;
}
if (GetAsyncKeyState(VK_NUMPAD9))
{
zz += 0.1f;
}
if (GetAsyncKeyState(VK_NUMPAD3))
{
zz -= 0.1f;
}
glm::mat4 mPROJ = glm::ortho<float>(-10.0f, 10.0f, -10.0f, 10.0f, 0.05f, 50.f);
glm::mat4 lightView = glm::lookAt(glm::vec3(5.f, 5.f, 5.f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 biasMatrix(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0
);
glm::mat4 lightSpaceMatrix = biasMatrix * mPROJ * lightView;
Renderer->ShadowMapping.Start();
Renderer->ShadowMapping.setUniform("depthMVP", lightSpaceMatrix);
glm::mat4 mModelToCamera;
glm::vec3 vPos = glm::vec3(xx, yy, zz);
mModelToCamera = glm::translate(glm::mat4(1.0), vPos);
mModelToCamera = glm::scale(mModelToCamera, glm::vec3(2.f));
Renderer->ShadowMapping.setUniform("model", mModelToCamera);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
/*glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);*/
glClear(GL_DEPTH_BUFFER_BIT);
Environment::DrawCube(glm::vec3(xx, yy, zz), glm::vec3(2.f), glm::vec4(1.f), 7, true);
vPos = glm::vec3(xx + 3.f, yy, zz);
mModelToCamera = glm::translate(glm::mat4(1.0), vPos);
mModelToCamera = glm::scale(mModelToCamera, glm::vec3(2.f));
Renderer->ShadowMapping.setUniform("model", mModelToCamera);
Environment::DrawCube(glm::vec3(xx + 3, yy, zz), glm::vec3(2.f), glm::vec4(1.f), 7, true);
RenderTargetManager->BackToNormalRenderer();
//glDisable(GL_CULL_FACE);
Renderer->ShadowMapping.Stop();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Renderer->MainProgram.Start();
Environment::DrawPlane(glm::vec3(0, 20.f, -20.f), glm::vec3(0.f, 90.f, 90.f), glm::vec3(10.f, 1.f, 10.f), depthMap);
Renderer->MainProgram.setUniform("EngineMatrices.DepthBiasMVP", lightSpaceMatrix);
Renderer->MainProgram.setUniform("shadowMap", 1);
Renderer->MainProgram.setUniform("bShadowsOn", 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, depthMap);
glActiveTexture(GL_TEXTURE0);
Environment::DrawCube(glm::vec3(xx, yy, zz), glm::vec3(2.f), glm::vec4(1.f), 7, false);
Environment::DrawCube(glm::vec3(xx + 3.f, yy, zz), glm::vec3(2.f), glm::vec4(1.f), 7, false);
//SHADOWS
//SHADOWS
#ifdef ENGINE_EDITOR
//CEditor::UpdateSelectedEntity();
#endif
//MODEL TYPE RENDERING
if (Renderer->IsCullFaceEnabled())
{
/*glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glFrontFace(GL_CW);*/
}
auto RenderEntity = [](Entity* _Entity)
{
if (_Entity->UpdateTransform())
{
_Entity->StartShader();
_Entity->Mesh->Render();
_Entity->StopShader();
}
if (_Entity->ShowCollider)
{
btVector3 one, two;
_Entity->Phys->RigidBody->getAabb(one, two);
Environment::DrawPoint(glm::vec3(one.x(), one.y(), one.z()), glm::vec3(2.f), glm::vec3(0.f, 1.f, 0.f));
Environment::DrawPoint(glm::vec3(one.x() + (two.x() - one.x()), one.y(), one.z()), glm::vec3(2.f), glm::vec3(0.f, 1.f, 0.f));
Environment::DrawPoint(glm::vec3(one.x(), one.y(), one.z() + (two.z() - one.z())), glm::vec3(2.f), glm::vec3(0.f, 1.f, 0.f));
Environment::DrawPoint(glm::vec3(one.x(), one.y() + (two.y() - one.y()), one.z()), glm::vec3(2.f), glm::vec3(0.f, 1.f, 0.f));
Environment::DrawPoint(glm::vec3(two.x() - (two.x() - one.x()), two.y(), two.z()), glm::vec3(2.f), glm::vec3(0.f, 1.f, 0.f));
Environment::DrawPoint(glm::vec3(two.x(), two.y() - (two.y() - one.y()), two.z()), glm::vec3(2.f), glm::vec3(0.f, 1.f, 0.f));
Environment::DrawPoint(glm::vec3(two.x(), two.y(), two.z() - (two.z() - one.z())), glm::vec3(2.f), glm::vec3(0.f, 1.f, 0.f));
Environment::DrawPoint(glm::vec3(two.x(), two.y(), two.z()), glm::vec3(2.f), glm::vec3(0.f, 1.f, 0.f));
}
};
//COL SHAPES
#ifdef ENGINE_EDITOR
for (uint i = 0; i < ColShapeManager->GetShapes(SHAPE_RECTANGLE); i++)
{
RectangleCol* currentShape = ColShapeManager->GetShape<RectangleCol>(SHAPE_RECTANGLE, i);
if (currentShape && currentShape->IsDebugEnabled())
currentShape->DebugShowCol();
}
for (uint i = 0; i < ColShapeManager->GetShapes(SHAPE_SPHERE); i++)
{
SphereCol* currentShape = ColShapeManager->GetShape<SphereCol>(SHAPE_SPHERE, i);
if (currentShape && currentShape->IsDebugEnabled())
currentShape->DebugShowCol();
}
#endif
//ENTITIES
std::map<float, Entity*> TransparentEntities;
std::map<float, Entity*> FarestEntities;
EntityManager->LoadQueueEntities();
#ifdef ENGINE_EDITOR
EntityManager->ResetEntitiesRendered();
#endif
for (uint i = 0; i < EntityManager->GetEntities(); i++)
{
Entity* currentEntity = EntityManager->GetEntity(i);
float EntityToCamera = glm::distance(Camera->Position, currentEntity->Position);
if (currentEntity && currentEntity->CanRender() && EntityToCamera <= Renderer->GetRenderMaxDistance() && currentEntity->IsVisible())
{
if (currentEntity->IsDestroying())
{
float _alpha = currentEntity->GetAlpha();
if (_alpha <= 0.f)
{
EntityManager->DestroyEntity(currentEntity);
continue;
}
currentEntity->SetAlpha(_alpha - 0.01f);
}
#ifdef ENGINE_EDITOR
EntityManager->IncreaseEntitiesRendered();
#endif
if (currentEntity->GetAlpha() < 1.f)
TransparentEntities[EntityToCamera] = currentEntity;
else
FarestEntities[EntityToCamera] = currentEntity;
}
}
//RENDER TRANSPARENT ENTITIES & FAREST ENTITIES FIRST (lol?)
for (auto it = FarestEntities.begin(); it != FarestEntities.end(); ++it)
RenderEntity(it->second);
for (auto it = TransparentEntities.rbegin(); it != TransparentEntities.rend(); ++it)
RenderEntity(it->second);
Renderer->MainProgram.setUniform("bShadowsOn", 0);
TransparentEntities.empty();
TransparentEntities.clear();
//PARTICLE SYSTEM
for (uint i = 0; i < ParticleSystemManager::GetParticleSystems(); i++)
{
if (ParticleSystems[i] && ParticleSystems[i]->ID != INT_MAX)
{
ParticleSystems[i]->SetMatrices(&Renderer->GetProjectionMatrix(), Camera->Position, Camera->vView, Camera->vUp);
ParticleSystems[i]->UpdateParticles(0.025f);
ParticleSystems[i]->RenderParticles();
}
}
Renderer->ResetColor();
Renderer->MainProgram.Stop();
if (Renderer->IsCullFaceEnabled())
glDisable(GL_CULL_FACE);
OGLImGui::DrawGUI();
EventManager->CallEvent(ON_RENDER, EventArguments->GetEventArguments(ON_RENDER));
return true;
}
Sorry for the messed code but I use to do that when I'm testing something instead of organizing it first. Maybe I'm missing something stupid but I can't figure out lol. I appreciate any help. Thanks in advance.