Added DrawPrimitive() to CObjectRenderer and used it for rendering water

dev
Tomasz Kapuściński 2022-01-22 00:57:00 +01:00
parent 048393f448
commit cba70fc912
5 changed files with 111 additions and 27 deletions

View File

@ -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;
};
/**

View File

@ -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);

View File

@ -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<Vertex> vertices((m_brickCount+2)*2, Vertex());
std::vector<Vertex3D> 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<int>( 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)

View File

@ -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<void*>(offsetof(Vertex3D, position)));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
reinterpret_cast<void*>(offsetof(Vertex3D, normal)));
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D),
reinterpret_cast<void*>(offsetof(Vertex3D, color)));
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
reinterpret_cast<void*>(offsetof(Vertex3D, uv)));
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
reinterpret_cast<void*>(offsetof(Vertex3D, uv2)));
glDrawArrays(TranslateGfxPrimitive(type), 0, count);
}

View File

@ -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);
};
}