diff --git a/src/graphics/core/renderers.h b/src/graphics/core/renderers.h index ac705c01..dd1dd816 100644 --- a/src/graphics/core/renderers.h +++ b/src/graphics/core/renderers.h @@ -180,6 +180,8 @@ public: //! Draws an object virtual void DrawObject(const CVertexBuffer* buffer) = 0; + //! Draws a primitive + virtual void DrawPrimitive(PrimitiveType type, int count, const Vertex3D* vertices) = 0; }; /** diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 3dd8e144..1971c219 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -3651,7 +3651,24 @@ void CEngine::Draw3DScene() } CProfiler::StartPerformanceCounter(PCNT_RENDER_WATER); + + objectRenderer->Begin(); + + objectRenderer->SetProjectionMatrix(m_matProj); + objectRenderer->SetViewMatrix(m_matView); + objectRenderer->SetShadowMap(m_shadowMap); + objectRenderer->SetLighting(true); + objectRenderer->SetLight(glm::vec4(1.0, 1.0, -1.0, 0.0), 1.0f, glm::vec3(1.0)); + objectRenderer->SetTransparency(TransparencyMode::NONE); + + objectRenderer->SetFog(fogStart, fogEnd, { fogColor.r, fogColor.g, fogColor.b }); + objectRenderer->SetAlphaScissor(0.0f); + objectRenderer->SetShadowParams(m_shadowRegions, shadowParams); + m_water->DrawSurf(); // draws water surface + + objectRenderer->End(); + CProfiler::StopPerformanceCounter(PCNT_RENDER_WATER); m_device->SetRenderState(RENDER_STATE_LIGHTING, false); diff --git a/src/graphics/engine/water.cpp b/src/graphics/engine/water.cpp index 0c66ab8f..80870c46 100644 --- a/src/graphics/engine/water.cpp +++ b/src/graphics/engine/water.cpp @@ -24,6 +24,7 @@ #include "common/logger.h" #include "graphics/core/device.h" +#include "graphics/core/renderers.h" #include "graphics/engine/engine.h" #include "graphics/engine/terrain.h" @@ -255,6 +256,10 @@ void CWater::AdjustLevel(glm::vec3 &pos, glm::vec3 &norm, /** This surface prevents to see the sky (background) underwater! */ void CWater::DrawBack() { + // TODO: Not currently used, needs to be rewritten + return; + + /* if (! m_draw) return; if (m_type[0] == WATER_NULL) return; if (m_lines.empty()) return; @@ -311,6 +316,7 @@ void CWater::DrawBack() m_engine->SetDeepView(deep, 0); m_engine->SetFocus(m_engine->GetFocus()); m_engine->UpdateMatProj(); // gives the initial depth of view + // */ } void CWater::DrawSurf() @@ -319,7 +325,7 @@ void CWater::DrawSurf() if (m_type[0] == WATER_NULL) return; if (m_lines.empty()) return; - std::vector vertices((m_brickCount+2)*2, Vertex()); + std::vector vertices((m_brickCount+2)*2); glm::vec3 eye = m_engine->GetEyePt(); @@ -327,31 +333,36 @@ void CWater::DrawSurf() bool under = ( rankview == 1); CDevice* device = m_engine->GetDevice(); + auto renderer = device->GetObjectRenderer(); glm::mat4 matrix = glm::mat4(1.0f); - device->SetTransform(TRANSFORM_WORLD, matrix); + renderer->SetModelMatrix(matrix); - Material material; - material.diffuse = m_diffuse; - material.ambient = m_ambient; - m_engine->SetMaterial(material); + auto texture = m_engine->LoadTexture(m_fileName); - m_engine->SetTexture(m_fileName, 0); - m_engine->SetTexture(m_fileName, 1); + renderer->SetPrimaryTexture(texture); + renderer->SetSecondaryTexture(Texture{}); if (m_type[rankview] == WATER_TT) - m_engine->SetState(ENG_RSTATE_TTEXTURE_BLACK | ENG_RSTATE_DUAL_WHITE | ENG_RSTATE_WRAP, m_color); - + { + renderer->SetTransparency(TransparencyMode::BLACK); + renderer->SetColor(m_color); + } else if (m_type[rankview] == WATER_TO) - m_engine->SetState(ENG_RSTATE_NORMAL | ENG_RSTATE_DUAL_WHITE | ENG_RSTATE_WRAP); - + { + renderer->SetTransparency(TransparencyMode::NONE); + renderer->SetColor({ 1.0f, 1.0f, 1.0f, 1.0f }); + } else if (m_type[rankview] == WATER_CT) - m_engine->SetState(ENG_RSTATE_TTEXTURE_BLACK); - + { + renderer->SetTransparency(TransparencyMode::BLACK); + renderer->SetColor({ 1.0f, 1.0f, 1.0f, 1.0f }); + } else if (m_type[rankview] == WATER_CO) - m_engine->SetState(ENG_RSTATE_NORMAL); - - device->SetRenderState(RENDER_STATE_FOG, true); + { + renderer->SetTransparency(TransparencyMode::NONE); + renderer->SetColor({ 1.0f, 1.0f, 1.0f, 1.0f }); + } float size = m_brickSize/2.0f; float sizez = 0.0f; @@ -361,8 +372,6 @@ void CWater::DrawSurf() // Draws all the lines float deep = m_engine->GetDeepView(0)*1.5f; - device->SetTextureEnabled(1, false); - for (int i = 0; i < static_cast( m_lines.size() ); i++) { glm::vec3 pos{}; @@ -385,20 +394,21 @@ void CWater::DrawSurf() glm::vec2 uv1, uv2; glm::vec3 n{}; + glm::u8vec4 white(255); p.x = pos.x-size; p.z = pos.z-sizez; p.y = pos.y; AdjustLevel(p, n, uv1, uv2); if (under) n.y = -n.y; - vertices[vertexIndex++] = { p, n, uv1 }; + vertices[vertexIndex++] = { p, white, uv1, {}, n }; p.x = pos.x-size; p.z = pos.z+sizez; p.y = pos.y; AdjustLevel(p, n, uv1, uv2); if (under) n.y = -n.y; - vertices[vertexIndex++] = { p, n, uv1 }; + vertices[vertexIndex++] = { p, white, uv1, {}, n }; for (int j = 0; j < m_lines[i].len; j++) { @@ -407,24 +417,21 @@ void CWater::DrawSurf() p.y = pos.y; AdjustLevel(p, n, uv1, uv2); if (under) n.y = -n.y; - vertices[vertexIndex++] = { p, n, uv1 }; + vertices[vertexIndex++] = { p, white, uv1, {}, n }; p.x = pos.x+size; p.z = pos.z+sizez; p.y = pos.y; AdjustLevel(p, n, uv1, uv2); if (under) n.y = -n.y; - vertices[vertexIndex++] = { p, n, uv1 }; + vertices[vertexIndex++] = { p, white, uv1, {}, n }; pos.x += size*2.0f; } - device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, &vertices[0], vertexIndex); + renderer->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, vertexIndex, vertices.data()); m_engine->AddStatisticTriangle(vertexIndex - 2); } - - if (m_engine->GetDirty()) - device->SetTextureEnabled(1, true); } bool CWater::GetWater(int x, int y) diff --git a/src/graphics/opengl/gl33objectrenderer.cpp b/src/graphics/opengl/gl33objectrenderer.cpp index c6a6fd41..219e2136 100644 --- a/src/graphics/opengl/gl33objectrenderer.cpp +++ b/src/graphics/opengl/gl33objectrenderer.cpp @@ -129,6 +129,20 @@ CGL33ObjectRenderer::CGL33ObjectRenderer(CGL33Device* device) glUseProgram(0); + // Generic buffer + glGenBuffers(1, &m_bufferVBO); + glBindBuffer(GL_COPY_WRITE_BUFFER, m_bufferVBO); + glBufferData(GL_COPY_WRITE_BUFFER, m_bufferCapacity, nullptr, GL_STREAM_DRAW); + + glGenVertexArrays(1, &m_bufferVAO); + glBindVertexArray(m_bufferVAO); + + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + glEnableVertexAttribArray(3); + glEnableVertexAttribArray(4); + GetLogger()->Info("CGL33ObjectRenderer created successfully\n"); } @@ -136,6 +150,8 @@ CGL33ObjectRenderer::~CGL33ObjectRenderer() { glDeleteProgram(m_program); glDeleteTextures(1, &m_whiteTexture); + glDeleteBuffers(1, &m_bufferVBO); + glDeleteVertexArrays(1, &m_bufferVAO); } void CGL33ObjectRenderer::CGL33ObjectRenderer::Begin() @@ -359,3 +375,36 @@ void CGL33ObjectRenderer::DrawObject(const CVertexBuffer* buffer) glDrawArrays(TranslateGfxPrimitive(b->GetType()), 0, b->Size()); } + +void CGL33ObjectRenderer::DrawPrimitive(PrimitiveType type, int count, const Vertex3D* vertices) +{ + glBindVertexArray(m_bufferVAO); + glBindBuffer(GL_ARRAY_BUFFER, m_bufferVBO); + + size_t size = count * sizeof(Vertex3D); + + if (m_bufferCapacity < size) + m_bufferCapacity = size; + + // Send new vertices to GPU + glBindBuffer(GL_ARRAY_BUFFER, m_bufferVBO); + glBufferData(GL_ARRAY_BUFFER, m_bufferCapacity, nullptr, GL_STREAM_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), + reinterpret_cast(offsetof(Vertex3D, position))); + + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), + reinterpret_cast(offsetof(Vertex3D, normal))); + + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D), + reinterpret_cast(offsetof(Vertex3D, color))); + + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), + reinterpret_cast(offsetof(Vertex3D, uv))); + + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), + reinterpret_cast(offsetof(Vertex3D, uv2))); + + glDrawArrays(TranslateGfxPrimitive(type), 0, count); +} diff --git a/src/graphics/opengl/gl33objectrenderer.h b/src/graphics/opengl/gl33objectrenderer.h index 1f5cbe81..cf818969 100644 --- a/src/graphics/opengl/gl33objectrenderer.h +++ b/src/graphics/opengl/gl33objectrenderer.h @@ -91,6 +91,8 @@ public: //! Draws an object virtual void DrawObject(const CVertexBuffer* buffer) override; + //! Draws a primitive + virtual void DrawPrimitive(PrimitiveType type, int count, const Vertex3D* vertices) override; private: CGL33Device* const m_device; @@ -136,6 +138,13 @@ private: GLuint m_secondaryTexture = 0; // Currently bound shadow map GLuint m_shadowMap = 0; + + // Vertex buffer object + GLuint m_bufferVBO = 0; + // Vertex array object + GLuint m_bufferVAO = 0; + // VBO capacity + GLsizei m_bufferCapacity = 8 * sizeof(Vertex3D); }; }