From f413bbe265a6cfb65aee4a15f1160b0bc900aaa8 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sat, 8 Jun 2024 20:55:56 +0300 Subject: [PATCH] Finally working cubemap --- Template/gameMap.cpp | 5 +- Template/log.txt | 143 ++++++------ Template/main.cpp | 207 +++++++++++++++++- Template/main.h | 7 + resources/negx.bmp | Bin 0 -> 786486 bytes resources/negy.bmp | Bin 0 -> 786486 bytes resources/negz.bmp | Bin 0 -> 786486 bytes resources/posx.bmp | Bin 0 -> 786486 bytes resources/posy.bmp | Bin 0 -> 786486 bytes resources/posz.bmp | Bin 0 -> 786486 bytes .../directlight — копия.fragment | 36 +++ .../shaders/directlight — копия.vertex | 35 +++ resources/shaders/directlight.fragment | 25 +-- resources/shaders/directlight.vertex | 53 +++-- resources/shaders/env.fragment | 3 +- resources/shaders/env.vertex | 11 +- 16 files changed, 406 insertions(+), 119 deletions(-) create mode 100644 resources/negx.bmp create mode 100644 resources/negy.bmp create mode 100644 resources/negz.bmp create mode 100644 resources/posx.bmp create mode 100644 resources/posy.bmp create mode 100644 resources/posz.bmp create mode 100644 resources/shaders/directlight — копия.fragment create mode 100644 resources/shaders/directlight — копия.vertex diff --git a/Template/gameMap.cpp b/Template/gameMap.cpp index 15559e5..a90abac 100644 --- a/Template/gameMap.cpp +++ b/Template/gameMap.cpp @@ -169,11 +169,8 @@ TSimpleLandClass* TGameMap::GetLand() void TGameMap::DrawVBO() { - Renderer->PushShader("Simple3D"); - Land->DrawVBO(); - Renderer->PopShader(); - //Land->DrawImmediate(); + Land->DrawVBO(); for (TLiteModelArr::iterator i = StaticModelArr.begin(); i != StaticModelArr.end(); ++i) { //i->DrawImmediate(); diff --git a/Template/log.txt b/Template/log.txt index bf536ec..4ca7e02 100644 --- a/Template/log.txt +++ b/Template/log.txt @@ -1,102 +1,109 @@ -2024-Jun-06 15:57:24: Log started -2024-Jun-06 15:57:25: OpenGL Window created -2024-Jun-06 15:57:25: Script manager ready -2024-Jun-06 15:57:25: Render::OpenGL glVersion = 4.6.0 - Build 31.0.101.4887 -2024-Jun-06 15:57:25: Render::OpenGL glVersion above 2.0 ok -2024-Jun-06 15:57:25: Render::OpenGL GL_ARB_framebuffer_object supported ok -2024-Jun-06 15:57:25: Render::OpenGL GL_ARB_uniform_buffer_object supported ok -2024-Jun-06 15:57:25: Prepare to add shader GUI -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: Log started +2024-Jun-08 20:53:34: OpenGL Window created +2024-Jun-08 20:53:34: Script manager ready +2024-Jun-08 20:53:34: Render::OpenGL glVersion = 4.6.0 - Build 31.0.101.4887 +2024-Jun-08 20:53:34: Render::OpenGL glVersion above 2.0 ok +2024-Jun-08 20:53:34: Render::OpenGL GL_ARB_framebuffer_object supported ok +2024-Jun-08 20:53:34: Render::OpenGL GL_ARB_uniform_buffer_object supported ok +2024-Jun-08 20:53:34: Prepare to add shader GUI +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: Shader program is - 3 -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader -2024-Jun-06 15:57:25: ResourceManager::ShaderManager shader loaded: GUI -2024-Jun-06 15:57:25: Prepare to add shader Parallax -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: Shader program is - 3 +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader +2024-Jun-08 20:53:34: ResourceManager::ShaderManager shader loaded: GUI +2024-Jun-08 20:53:34: Prepare to add shader Parallax +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing WARNING: 0:27: 'assign' : implicit type conversion allowed from GLSL 1.20 WARNING: 0:27: 'assign' : implicit type conversion allowed from GLSL 1.20 WARNING: 0:27: 'assign' : implicit type conversion allowed -2024-Jun-06 15:57:25: Shader program is - 6 -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader -2024-Jun-06 15:57:25: ResourceManager::ShaderManager shader loaded: Parallax -2024-Jun-06 15:57:25: Prepare to add shader Directlight -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: Shader program is - 6 +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader +2024-Jun-08 20:53:34: ResourceManager::ShaderManager shader loaded: Parallax +2024-Jun-08 20:53:34: Prepare to add shader Directlight +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: Shader program is - 9 -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader -2024-Jun-06 15:57:25: ResourceManager::ShaderManager shader loaded: Directlight -2024-Jun-06 15:57:25: Prepare to add shader Env -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: Shader program is - 9 +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader +2024-Jun-08 20:53:34: ResourceManager::ShaderManager shader loaded: Directlight +2024-Jun-08 20:53:34: Prepare to add shader Env +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: Shader program is - 12 -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader -2024-Jun-06 15:57:25: ResourceManager::ShaderManager shader loaded: Env -2024-Jun-06 15:57:25: Prepare to add shader Water -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: Shader program is - 12 +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader +2024-Jun-08 20:53:34: ResourceManager::ShaderManager shader loaded: Env +2024-Jun-08 20:53:34: Prepare to add shader Water +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing WARNING: 0:20: 'assign' : implicit type conversion allowed from GLSL 1.20 -2024-Jun-06 15:57:25: Shader program is - 15 -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader -2024-Jun-06 15:57:25: ResourceManager::ShaderManager shader loaded: Water -2024-Jun-06 15:57:25: Prepare to add shader Frame -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: Shader program is - 15 +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader +2024-Jun-08 20:53:34: ResourceManager::ShaderManager shader loaded: Water +2024-Jun-08 20:53:34: Prepare to add shader Frame +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: Shader program is - 18 -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader -2024-Jun-06 15:57:25: ResourceManager::ShaderManager shader loaded: Frame -2024-Jun-06 15:57:25: Prepare to add shader Lightview -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:5: '' : #version directive missing +2024-Jun-08 20:53:34: Shader program is - 18 +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader +2024-Jun-08 20:53:34: ResourceManager::ShaderManager shader loaded: Frame +2024-Jun-08 20:53:34: Prepare to add shader Lightview +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:5: '' : #version directive missing -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: Shader program is - 21 -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader -2024-Jun-06 15:57:25: ResourceManager::ShaderManager shader loaded: Lightview -2024-Jun-06 15:57:25: Prepare to add shader Simple3D -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: Shader program is - 21 +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader +2024-Jun-08 20:53:34: ResourceManager::ShaderManager shader loaded: Lightview +2024-Jun-08 20:53:34: Prepare to add shader Simple3D +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader WARNING: 0:1: '' : #version directive missing -2024-Jun-06 15:57:25: Shader program is - 24 -2024-Jun-06 15:57:25: ResourceManager::ShaderManager::Shader -2024-Jun-06 15:57:25: ResourceManager::ShaderManager shader loaded: Simple3D -2024-Jun-06 15:57:25: ResourceManager::TexList Texture added: bt_box_yellow.bmp with id = 1 -2024-Jun-06 15:57:25: ResourceManager::TexList Texture added: bt_box_norm.bmp32 with id = 2 -2024-Jun-06 15:57:25: Lite model added successfully: models/bt_box_yellow.lm1 -2024-Jun-06 15:57:25: ResourceManager::TexList Texture added: bt_cone.bmp with id = 3 -2024-Jun-06 15:57:25: Lite model added successfully: models/bt_cone.lm1 -2024-Jun-06 15:57:25: Lite model added successfully: models/girl.lm1 -2024-Jun-06 15:57:25: Lite model added successfully: models/bonemodel.lm1 -2024-Jun-06 15:57:26: ResourceManager::TexList Texture added: out.bmp with id = 4 -2024-Jun-06 15:57:26: FrameManager:: frame buffer added: Skybox -2024-Jun-06 15:57:26: ResourceManager::TexList Texture added: normalmap.bmp with id = 6 -2024-Jun-06 15:57:26: FrameManager:: frame buffer added: ScreenBlur -2024-Jun-06 15:57:26: FrameManager:: frame buffer added: ShadowBufferGlobal -2024-Jun-06 15:57:26: FrameManager:: frame buffer added: ShadowBufferLocal +2024-Jun-08 20:53:34: Shader program is - 24 +2024-Jun-08 20:53:34: ResourceManager::ShaderManager::Shader +2024-Jun-08 20:53:34: ResourceManager::ShaderManager shader loaded: Simple3D +2024-Jun-08 20:53:34: ResourceManager::TexList Texture added: bt_box_yellow.bmp with id = 1 +2024-Jun-08 20:53:34: ResourceManager::TexList Texture added: bt_box_norm.bmp32 with id = 2 +2024-Jun-08 20:53:34: Lite model added successfully: models/bt_box_yellow.lm1 +2024-Jun-08 20:53:34: ResourceManager::TexList Texture added: bt_cone.bmp with id = 3 +2024-Jun-08 20:53:34: Lite model added successfully: models/bt_cone.lm1 +2024-Jun-08 20:53:34: Lite model added successfully: models/girl.lm1 +2024-Jun-08 20:53:34: Lite model added successfully: models/bonemodel.lm1 +2024-Jun-08 20:53:35: ResourceManager::TexList Texture added: out.bmp with id = 4 +2024-Jun-08 20:53:35: FrameManager:: frame buffer added: Skybox +2024-Jun-08 20:53:35: ResourceManager::TexList Texture added: normalmap.bmp with id = 6 +2024-Jun-08 20:53:35: Going to add texture: C:\Work\OldProjects\ho3\resources\../resources/posx.bmp +2024-Jun-08 20:53:35: Going to add texture: C:\Work\OldProjects\ho3\resources\../resources/negx.bmp +2024-Jun-08 20:53:35: Going to add texture: C:\Work\OldProjects\ho3\resources\../resources/posy.bmp +2024-Jun-08 20:53:35: Going to add texture: C:\Work\OldProjects\ho3\resources\../resources/negy.bmp +2024-Jun-08 20:53:35: Going to add texture: C:\Work\OldProjects\ho3\resources\../resources/posz.bmp +2024-Jun-08 20:53:35: Going to add texture: C:\Work\OldProjects\ho3\resources\../resources/negz.bmp +2024-Jun-08 20:53:35: ResourceManager::TexList texture added succesfuly: posx.bmp +2024-Jun-08 20:53:35: FrameManager:: frame buffer added: ScreenBlur +2024-Jun-08 20:53:35: FrameManager:: frame buffer added: ShadowBufferGlobal +2024-Jun-08 20:53:35: FrameManager:: frame buffer added: ShadowBufferLocal diff --git a/Template/main.cpp b/Template/main.cpp index 03539f9..65fbca6 100644 --- a/Template/main.cpp +++ b/Template/main.cpp @@ -10,6 +10,7 @@ cardinal CONST_CUBEMAP_UPDATE_INTERVAL = 5000; void TMyApplication::DrawToCubemap() { + Renderer->PushPerspectiveProjectionMatrix(pi/2, 1.0, 1, 1000); Renderer->PushShader("Directlight"); Renderer->SwitchToCubemapBuffer("Skybox",0); @@ -39,6 +40,8 @@ void TMyApplication::DrawToCubemap() Renderer->SwitchToScreen(); Renderer->PopShader(); + + Renderer->PopProjectionMatrix(); } void TMyApplication::DrawToShadowMap() @@ -86,11 +89,33 @@ void TMyApplication::DrawWaterSurface() Renderer->PopShader(); } +void TMyApplication::DrawCubemap() +{ + Renderer->PushShader("Env"); + Renderer->SetGLCamAngleView(); + //Renderer->LoadIdentity(); + RenderUniformMatrix3fv(CONST_STRING_MODELROTATEMATRIX_UNIFORM, false, (float*)IdentityMatrix.m); + RenderUniform3fv(CONST_STRING_MODELTRANSLATEVECTOR_UNIFORM, (float*)ZeroVec3.v); + + glBindTexture(GL_TEXTURE_CUBE_MAP, ResourceManager->FrameManager.GetFrameTexture("Skybox")); + //glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture); + + EnableVertexAttribArray("vPosition"); + + DrawVertexDataStruct(cubemapVertexDataStruct); + + DisableVertexAttribArray("vPosition"); + + Renderer->PopShader(); +} + //What to do on init void TMyApplication::InnerInit() { ResourceManager->PathToResources = "C:\\Work\\OldProjects\\ho3\\resources\\"; + glDisable(GL_CULL_FACE); + ResourceManager->ShaderManager.AddShader("GUI", "shaders/gui_transparent.vertex", "shaders/gui_transparent.fragment"); ResourceManager->ShaderManager.AddShader("Parallax", "shaders/directlight_parallax_shadow.vertex", "shaders/directlight_parallax_shadow.fragment"); @@ -136,6 +161,13 @@ void TMyApplication::InnerInit() ResourceManager->TexList.AddTexture("../resources/normalmap.bmp"); + std::array cubemapTextureStr = { + "../resources/posx.bmp", "../resources/negx.bmp", "../resources/posy.bmp", "../resources/negy.bmp", "../resources/posz.bmp", "../resources/negz.bmp" + }; + + cubemapTexture = ResourceManager->TexList.AddCubemapTexture(cubemapTextureStr); + //."posx.bmp","negx.bmp","posy.bmp","negy.bmp","posz.bmp","negz.bmp" + ResourceManager->FrameManager.AddFrameRenderBuffer("ScreenBlur", 512, 512); ResourceManager->FrameManager.AddDepthBuffer("ShadowBufferGlobal", 512, 512); @@ -151,9 +183,119 @@ void TMyApplication::InnerInit() glClearColor(0.2f, 0.5f, 1.0f, 1.0f); //Renderer->SetShadowClampValue(0.3f); - Renderer->SetShadowClampValue(0.0f); - + //Renderer->SetShadowClampValue(0.0f); + Renderer->SetFogBeginDistance(15.f); + Renderer->SetFogEndDistance(30.f); + + + // +x + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f }); + + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, 10.0f }); + + // -x + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, 10.0f }); + + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, 10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, 10.0f }); + + + // +y + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f }); + + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, 10.0f }); + + + // -y + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, 10.0f }); + + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, 10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, 10.0f }); + + + // +z + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, 10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, 10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f }); + + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, 10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, 10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, 10.0f }); + // -z + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, -10.0f }); + + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, -10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ 10.0f, 10.0f, -10.0f }); + cubemapVertexDataStruct.PositionData.push_back({ -10.0f, 10.0f, -10.0f }); + + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + cubemapVertexDataStruct.TexCoordData.push_back({ 0.0, 0.0 }); + + + cubemapVertexDataStruct.RefreshVBO(); } @@ -168,12 +310,64 @@ void TMyApplication::InnerDeinit() void TMyApplication::InnerDraw() { Renderer->SwitchToScreen(); - glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClearColor(0.2f, 0.55f, 1.0f, 1.0f); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - Renderer->PushShader("GUI"); + + Renderer->PushShader("Directlight"); + + DrawToCubemap(); + + //Renderer->SwitchToCubemapBuffer("Skybox", 0); + //Renderer->SetGlPosXView(); + //DrawSceneWithoutWater(); + if (view == 6) + { + DrawCubemap(); + } + else + { + + Renderer->PushPerspectiveProjectionMatrix(pi / 2, 1.0, 1, 1000); + if (view == 0) + { + Renderer->SetGlNegZView(); + } + else if (view == 1) + { + Renderer->SetGlNegYView(); + } + else if (view == 2) + { + Renderer->SetGlPosXView(); + } + else if (view == 3) + { + Renderer->SetGlNegXView(); + } + else if (view == 4) + { + Renderer->SetGlPosZView(); + } + else if (view == 5) + { + Renderer->SetGlPosYView(); + } + DrawSceneWithoutWater(); + Renderer->PopProjectionMatrix(); + } + + //DrawCubemap(); + + Renderer->PopShader(); + + + /* + Renderer->PushShader("Directlight"); DrawSceneWithoutWater(); Renderer->PopShader(); + */ + //DrawToCubemap(); /* DrawToCubemap(); @@ -270,6 +464,11 @@ void TMyApplication::OnMouseDown(TMouseState& mouseState) if (mouseState.LeftButtonPressed) { MouseLeftButtonPressed = true; + view += 1; + if (view == 7) + { + view = 0; + } } } diff --git a/Template/main.h b/Template/main.h index d460324..dd716b8 100644 --- a/Template/main.h +++ b/Template/main.h @@ -26,6 +26,8 @@ class TMyApplication : public SE::TApplication int MouseX0, MouseY0; //Mouse pos caught on right button click + int view = 0; + float WaterTimer; void DrawSceneWithoutWater(); @@ -36,6 +38,11 @@ class TMyApplication : public SE::TApplication void DrawWaterSurface(); + void DrawCubemap(); + + cardinal cubemapTexture; + VertexDataStruct cubemapVertexDataStruct; + public: //Constructor diff --git a/resources/negx.bmp b/resources/negx.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6caee8cd46532328785941e2a54bdda0c322bce0 GIT binary patch literal 786486 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