Optimizations in graphics engines

dev-time-step
Tomasz Kapuściński 2016-02-10 21:40:41 +01:00
parent a5ff72e635
commit 447b466d6e
4 changed files with 246 additions and 266 deletions

View File

@ -440,6 +440,9 @@ void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
glUniformMatrix4fv(uni_ModelMatrix, 1, GL_FALSE, m_worldMat.Array()); glUniformMatrix4fv(uni_ModelMatrix, 1, GL_FALSE, m_worldMat.Array());
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
// normal transform // normal transform
Math::Matrix normalMat = matrix; Math::Matrix normalMat = matrix;
@ -450,17 +453,21 @@ void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
} }
else if (type == TRANSFORM_VIEW) else if (type == TRANSFORM_VIEW)
{ {
m_viewMat = matrix;
Math::Matrix scale; Math::Matrix scale;
Math::LoadScaleMatrix(scale, Math::Vector(1.0f, 1.0f, -1.0f)); scale.Set(3, 3, -1.0f);
Math::Matrix temp = Math::MultiplyMatrices(scale, matrix); m_viewMat = Math::MultiplyMatrices(scale, matrix);
glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, temp.Array()); m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, m_viewMat.Array());
} }
else if (type == TRANSFORM_PROJECTION) else if (type == TRANSFORM_PROJECTION)
{ {
m_projectionMat = matrix; m_projectionMat = matrix;
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, m_projectionMat.Array()); glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, m_projectionMat.Array());
} }
else if (type == TRANSFORM_SHADOW) else if (type == TRANSFORM_SHADOW)
@ -514,39 +521,21 @@ void CGL21Device::SetLight(int index, const Light &light)
glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 180.0f); glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 180.0f);
} }
UpdateLightPosition(index); if (light.type == LIGHT_SPOT)
}
void CGL21Device::UpdateLightPosition(int index)
{
assert(index >= 0);
assert(index < static_cast<int>( m_lights.size() ));
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
//glScalef(1.0f, 1.0f, -1.0f);
if (m_lights[index].type == LIGHT_SPOT)
{ {
GLfloat direction[4] = { -m_lights[index].direction.x, -m_lights[index].direction.y, -m_lights[index].direction.z, 1.0f }; GLfloat direction[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 1.0f };
glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction); glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
} }
else if (light.type == LIGHT_DIRECTIONAL)
if (m_lights[index].type == LIGHT_DIRECTIONAL)
{ {
GLfloat position[4] = { -m_lights[index].direction.x, -m_lights[index].direction.y, -m_lights[index].direction.z, 0.0f }; GLfloat position[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 0.0f };
glLightfv(GL_LIGHT0 + index, GL_POSITION, position); glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
} }
else else
{ {
GLfloat position[4] = { m_lights[index].position.x, m_lights[index].position.y, m_lights[index].position.z, 1.0f }; GLfloat position[4] = { light.position.x, light.position.y, light.position.z, 1.0f };
glLightfv(GL_LIGHT0 + index, GL_POSITION, position); glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
} }
glPopMatrix();
} }
void CGL21Device::SetLightEnabled(int index, bool enabled) void CGL21Device::SetLightEnabled(int index, bool enabled)
@ -1560,13 +1549,7 @@ void CGL21Device::DestroyStaticBuffer(unsigned int bufferId)
int CGL21Device::ComputeSphereVisibility(const Math::Vector &center, float radius) int CGL21Device::ComputeSphereVisibility(const Math::Vector &center, float radius)
{ {
Math::Matrix m; Math::Matrix &m = m_combinedMatrix;
m = Math::MultiplyMatrices(m_worldMat, m);
m = Math::MultiplyMatrices(m_viewMat, m);
Math::Matrix sc;
Math::LoadScaleMatrix(sc, Math::Vector(1.0f, 1.0f, -1.0f));
m = Math::MultiplyMatrices(sc, m);
m = Math::MultiplyMatrices(m_projectionMat, m);
Math::Vector vec[6]; Math::Vector vec[6];
float originPlane[6]; float originPlane[6];
@ -1655,12 +1638,6 @@ void CGL21Device::SetRenderState(RenderState state, bool enabled)
glUniform1i(uni_LightingEnabled, enabled ? 1 : 0); glUniform1i(uni_LightingEnabled, enabled ? 1 : 0);
if (enabled)
{
for (int index = 0; index < static_cast<int>( m_lights.size() ); ++index)
UpdateLightPosition(index);
}
return; return;
} }
else if (state == RENDER_STATE_ALPHA_TEST) else if (state == RENDER_STATE_ALPHA_TEST)

View File

@ -172,8 +172,6 @@ public:
bool IsFramebufferSupported() override; bool IsFramebufferSupported() override;
private: private:
//! Updates position for given light based on transformation matrices
void UpdateLightPosition(int index);
//! Updates the texture params for given texture stage //! Updates the texture params for given texture stage
void UpdateTextureParams(int index); void UpdateTextureParams(int index);
//! Updates texture status //! Updates texture status
@ -193,6 +191,8 @@ private:
Math::Matrix m_modelviewMat; Math::Matrix m_modelviewMat;
//! Current projection matrix //! Current projection matrix
Math::Matrix m_projectionMat; Math::Matrix m_projectionMat;
//! Combined world-view-projection matrix
Math::Matrix m_combinedMatrix;
//! The current material //! The current material
Material m_material; Material m_material;

View File

@ -254,11 +254,6 @@ bool CGL33Device::Create()
m_texturesEnabled = std::vector<bool> (maxTextures, false); m_texturesEnabled = std::vector<bool> (maxTextures, false);
m_textureStageParams = std::vector<TextureStageParams>(maxTextures, TextureStageParams()); m_textureStageParams = std::vector<TextureStageParams>(maxTextures, TextureStageParams());
// Create auxilliary vertex buffer
m_vertex = CreateStaticBuffer(PRIMITIVE_POINTS, static_cast<Vertex*>(nullptr), 1);
m_vertexTex2 = CreateStaticBuffer(PRIMITIVE_POINTS, static_cast<VertexTex2*>(nullptr), 1);
m_vertexCol = CreateStaticBuffer(PRIMITIVE_POINTS, static_cast<VertexCol*>(nullptr), 1);
int value; int value;
if (CConfigFile::GetInstance().GetIntProperty("Setup", "PerPixelLighting", value)) if (CConfigFile::GetInstance().GetIntProperty("Setup", "PerPixelLighting", value))
{ {
@ -396,6 +391,23 @@ bool CGL33Device::Create()
m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams); m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams);
// create dynamic buffers
glGenVertexArrays(1, &m_auxiliaryVAO);
for (int i = 0; i < 64; i++)
{
DynamicBuffer buffer;
glGenBuffers(1, &buffer.vbo);
BindVBO(buffer.vbo);
buffer.size = 1024;
glBufferData(GL_ARRAY_BUFFER, buffer.size, nullptr, GL_STREAM_DRAW);
m_buffers.push_back(buffer);
}
GetLogger()->Info("CDevice created successfully\n"); GetLogger()->Info("CDevice created successfully\n");
return true; return true;
@ -417,6 +429,14 @@ void CGL33Device::Destroy()
// Should not be strictly necessary, but just in case // Should not be strictly necessary, but just in case
DestroyAllTextures(); DestroyAllTextures();
// delete all dynamic buffers
for (auto& buffer : m_buffers)
{
glDeleteBuffers(1, &buffer.vbo);
}
glDeleteVertexArrays(1, &m_auxiliaryVAO);
m_buffers.clear();
m_lights.clear(); m_lights.clear();
m_lightsEnabled.clear(); m_lightsEnabled.clear();
@ -470,6 +490,9 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
m_worldMat = matrix; m_worldMat = matrix;
glUniformMatrix4fv(uni_ModelMatrix, 1, GL_FALSE, m_worldMat.Array()); glUniformMatrix4fv(uni_ModelMatrix, 1, GL_FALSE, m_worldMat.Array());
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
// normal transform // normal transform
Math::Matrix normalMat = matrix; Math::Matrix normalMat = matrix;
@ -480,15 +503,21 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
} }
else if (type == TRANSFORM_VIEW) else if (type == TRANSFORM_VIEW)
{ {
m_viewMat = matrix;
Math::Matrix scale; Math::Matrix scale;
Math::LoadScaleMatrix(scale, Math::Vector(1.0f, 1.0f, -1.0f)); scale.Set(3, 3, -1.0f);
Math::Matrix temp = Math::MultiplyMatrices(scale, matrix); m_viewMat = Math::MultiplyMatrices(scale, matrix);
glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, temp.Array());
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, m_viewMat.Array());
} }
else if (type == TRANSFORM_PROJECTION) else if (type == TRANSFORM_PROJECTION)
{ {
m_projectionMat = matrix; m_projectionMat = matrix;
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, m_projectionMat.Array()); glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, m_projectionMat.Array());
} }
else if (type == TRANSFORM_SHADOW) else if (type == TRANSFORM_SHADOW)
@ -1186,162 +1215,138 @@ void CGL33Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode
void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount, Color color) void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount, Color color)
{ {
Vertex* vs = const_cast<Vertex*>(vertices); Vertex* vs = const_cast<Vertex*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertex];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
unsigned int size = vertexCount * sizeof(Vertex); unsigned int size = vertexCount * sizeof(Vertex);
BindVAO(info.vao); BindVAO(m_auxiliaryVAO);
BindVBO(info.vbo); BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer UpdateDynamicBuffer(buffer, size, vs);
if (info.size >= size)
{
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
}
else
{
CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
info.size = size;
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, coord))); reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Normal // Normal
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, normal))); reinterpret_cast<void*>(offsetof(Vertex, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, texCoord)));
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
}
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array()); glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, texCoord)));
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
UpdateRenderingMode(); UpdateRenderingMode();
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
} }
void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color) void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color)
{ {
VertexTex2* vs = const_cast<VertexTex2*>(vertices); VertexTex2* vs = const_cast<VertexTex2*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertexTex2];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
unsigned int size = vertexCount * sizeof(VertexTex2); unsigned int size = vertexCount * sizeof(VertexTex2);
BindVAO(info.vao); BindVAO(m_auxiliaryVAO);
BindVBO(info.vbo); BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer UpdateDynamicBuffer(buffer, size, vs);
if (info.size >= size)
{
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
}
else
{
CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
info.size = size;
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, coord))); reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Normal // Normal
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, normal))); reinterpret_cast<void*>(offsetof(VertexTex2, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, texCoord)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
}
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array()); glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, texCoord)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
UpdateRenderingMode(); UpdateRenderingMode();
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
} }
void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
{ {
VertexCol* vs = const_cast<VertexCol*>(vertices); VertexCol* vs = const_cast<VertexCol*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertexCol];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
unsigned int size = vertexCount * sizeof(VertexCol); unsigned int size = vertexCount * sizeof(VertexCol);
BindVAO(info.vao); BindVAO(m_auxiliaryVAO);
BindVBO(info.vbo); BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer UpdateDynamicBuffer(buffer, size, vs);
if (info.size >= size)
{
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
}
else
{
CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
info.size = size;
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, coord))); reinterpret_cast<void*>(offsetof(VertexCol, coord)));
// Normal // Normal
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f); glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
// Color // Color
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol), glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, color))); reinterpret_cast<void*>(offsetof(VertexCol, color)));
// Texture coordinate 0 // Texture coordinate 0
glDisableVertexAttribArray(3); glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f); glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 1 // Texture coordinate 1
glDisableVertexAttribArray(4); glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f); glVertexAttrib2f(4, 0.0f, 0.0f);
}
UpdateRenderingMode(); UpdateRenderingMode();
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
} }
void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
int first[], int count[], int drawCount, Color color) int first[], int count[], int drawCount, Color color)
{ {
Vertex* vs = const_cast<Vertex*>(vertices); Vertex* vs = const_cast<Vertex*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertex];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
int vertexCount = 0; int vertexCount = 0;
@ -1355,56 +1360,47 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
unsigned int size = vertexCount * sizeof(Vertex); unsigned int size = vertexCount * sizeof(Vertex);
BindVAO(info.vao); BindVAO(m_auxiliaryVAO);
BindVBO(info.vbo); BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer UpdateDynamicBuffer(buffer, size, vs);
if (info.size >= size)
{
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
}
else
{
CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
info.size = size;
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, coord))); reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Normal // Normal
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, normal))); reinterpret_cast<void*>(offsetof(Vertex, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, texCoord)));
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
}
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array()); glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, texCoord)));
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
UpdateRenderingMode(); UpdateRenderingMode();
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
} }
void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
int first[], int count[], int drawCount, Color color) int first[], int count[], int drawCount, Color color)
{ {
VertexTex2* vs = const_cast<VertexTex2*>(vertices); VertexTex2* vs = const_cast<VertexTex2*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertexTex2];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
int vertexCount = 0; int vertexCount = 0;
@ -1418,57 +1414,48 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
unsigned int size = vertexCount * sizeof(VertexTex2); unsigned int size = vertexCount * sizeof(VertexTex2);
BindVAO(info.vao); BindVAO(m_auxiliaryVAO);
BindVBO(info.vbo); BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer UpdateDynamicBuffer(buffer, size, vs);
if (info.size >= size)
{
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
}
else
{
CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
info.size = size;
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, coord))); reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Normal // Normal
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, normal))); reinterpret_cast<void*>(offsetof(VertexTex2, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, texCoord)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
}
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array()); glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, texCoord)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
UpdateRenderingMode(); UpdateRenderingMode();
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
} }
void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
int first[], int count[], int drawCount) int first[], int count[], int drawCount)
{ {
VertexCol* vs = const_cast<VertexCol*>(vertices); VertexCol* vs = const_cast<VertexCol*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertexCol];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
int vertexCount = 0; int vertexCount = 0;
@ -1482,46 +1469,38 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
unsigned int size = vertexCount * sizeof(VertexCol); unsigned int size = vertexCount * sizeof(VertexCol);
BindVAO(info.vao); BindVAO(m_auxiliaryVAO);
BindVBO(info.vbo); BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer UpdateDynamicBuffer(buffer, size, vs);
if (info.size >= size)
{
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
}
else
{
CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
info.size = size;
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, coord))); reinterpret_cast<void*>(offsetof(VertexCol, coord)));
// Normal // Normal
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f); glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
// Color // Color
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol), glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, color))); reinterpret_cast<void*>(offsetof(VertexCol, color)));
// Texture coordinate 0 // Texture coordinate 0
glDisableVertexAttribArray(3); glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f); glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 1 // Texture coordinate 1
glDisableVertexAttribArray(4); glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f); glVertexAttrib2f(4, 0.0f, 0.0f);
}
UpdateRenderingMode(); UpdateRenderingMode();
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
} }
unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
@ -1870,13 +1849,7 @@ void CGL33Device::DestroyStaticBuffer(unsigned int bufferId)
int CGL33Device::ComputeSphereVisibility(const Math::Vector &center, float radius) int CGL33Device::ComputeSphereVisibility(const Math::Vector &center, float radius)
{ {
Math::Matrix m; Math::Matrix &m = m_combinedMatrix;
m = Math::MultiplyMatrices(m_worldMat, m);
m = Math::MultiplyMatrices(m_viewMat, m);
Math::Matrix sc;
Math::LoadScaleMatrix(sc, Math::Vector(1.0f, 1.0f, -1.0f));
m = Math::MultiplyMatrices(sc, m);
m = Math::MultiplyMatrices(m_projectionMat, m);
Math::Vector vec[6]; Math::Vector vec[6];
float originPlane[6]; float originPlane[6];
@ -2163,6 +2136,19 @@ inline void CGL33Device::BindVAO(GLuint vao)
m_currentVAO = vao; m_currentVAO = vao;
} }
inline void CGL33Device::UpdateDynamicBuffer(DynamicBuffer &buffer, unsigned int size, void* data)
{
if (buffer.size < size)
{
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STREAM_DRAW);
buffer.size = size;
}
else
{
glBufferSubData(GL_ARRAY_BUFFER, 0, size, data);
}
}
bool CGL33Device::IsAnisotropySupported() bool CGL33Device::IsAnisotropySupported()
{ {
return m_anisotropyAvailable; return m_anisotropyAvailable;

View File

@ -44,6 +44,16 @@
namespace Gfx namespace Gfx
{ {
/**
\struct DynamicBuffer
\brief Structure for storing dynamic buffer
*/
struct DynamicBuffer
{
GLuint vbo;
unsigned int size;
};
/** /**
\class CGL33Device \class CGL33Device
\brief Implementation of CDevice interface in OpenGL 3.3 \brief Implementation of CDevice interface in OpenGL 3.3
@ -186,6 +196,9 @@ private:
//! Binds VAO //! Binds VAO
inline void BindVAO(GLuint vao); inline void BindVAO(GLuint vao);
//! Updates dynamic buffer
inline void UpdateDynamicBuffer(DynamicBuffer &buffer, unsigned int size, void* data);
private: private:
//! Current config //! Current config
DeviceConfig m_config; DeviceConfig m_config;
@ -198,6 +211,8 @@ private:
Math::Matrix m_modelviewMat; Math::Matrix m_modelviewMat;
//! Current projection matrix //! Current projection matrix
Math::Matrix m_projectionMat; Math::Matrix m_projectionMat;
//! Combined world-view-projection matrix
Math::Matrix m_combinedMatrix;
//! The current material //! The current material
Material m_material; Material m_material;
@ -264,10 +279,12 @@ private:
//! true enables per-pixel lighting //! true enables per-pixel lighting
bool m_perPixelLighting = false; bool m_perPixelLighting = false;
//! Auxilliary vertex buffers for general rendering //! Auxilliary buffers for rendering primitives with DrawPrimitive*
unsigned int m_vertex = 0; std::vector<DynamicBuffer> m_buffers = {};
unsigned int m_vertexTex2 = 0; //! Index to next auxilliary buffer
unsigned int m_vertexCol = 0; int m_nextBuffer = 0;
//! Auxiliary VAO for rendering primitives with DrawPrimitive*
GLuint m_auxiliaryVAO = 0;
// Uniforms // Uniforms
//! Projection matrix //! Projection matrix