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());
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
// normal transform
Math::Matrix normalMat = matrix;
@ -450,17 +453,21 @@ void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
}
else if (type == TRANSFORM_VIEW)
{
m_viewMat = matrix;
Math::Matrix scale;
Math::LoadScaleMatrix(scale, Math::Vector(1.0f, 1.0f, -1.0f));
Math::Matrix temp = Math::MultiplyMatrices(scale, matrix);
scale.Set(3, 3, -1.0f);
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)
{
m_projectionMat = matrix;
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, m_projectionMat.Array());
}
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);
}
UpdateLightPosition(index);
}
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)
if (light.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);
}
if (m_lights[index].type == LIGHT_DIRECTIONAL)
else if (light.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);
}
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);
}
glPopMatrix();
}
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)
{
Math::Matrix m;
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::Matrix &m = m_combinedMatrix;
Math::Vector vec[6];
float originPlane[6];
@ -1655,12 +1638,6 @@ void CGL21Device::SetRenderState(RenderState state, bool enabled)
glUniform1i(uni_LightingEnabled, enabled ? 1 : 0);
if (enabled)
{
for (int index = 0; index < static_cast<int>( m_lights.size() ); ++index)
UpdateLightPosition(index);
}
return;
}
else if (state == RENDER_STATE_ALPHA_TEST)

View File

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

View File

@ -254,11 +254,6 @@ bool CGL33Device::Create()
m_texturesEnabled = std::vector<bool> (maxTextures, false);
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;
if (CConfigFile::GetInstance().GetIntProperty("Setup", "PerPixelLighting", value))
{
@ -396,6 +391,23 @@ bool CGL33Device::Create()
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");
return true;
@ -417,6 +429,14 @@ void CGL33Device::Destroy()
// Should not be strictly necessary, but just in case
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_lightsEnabled.clear();
@ -470,6 +490,9 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
m_worldMat = matrix;
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
Math::Matrix normalMat = matrix;
@ -480,15 +503,21 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
}
else if (type == TRANSFORM_VIEW)
{
m_viewMat = matrix;
Math::Matrix scale;
Math::LoadScaleMatrix(scale, Math::Vector(1.0f, 1.0f, -1.0f));
Math::Matrix temp = Math::MultiplyMatrices(scale, matrix);
glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, temp.Array());
scale.Set(3, 3, -1.0f);
m_viewMat = Math::MultiplyMatrices(scale, matrix);
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)
{
m_projectionMat = matrix;
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, m_projectionMat.Array());
}
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)
{
Vertex* vs = const_cast<Vertex*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertex];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
unsigned int size = vertexCount * sizeof(Vertex);
BindVAO(info.vao);
BindVBO(info.vbo);
BindVAO(m_auxiliaryVAO);
BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer
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;
UpdateDynamicBuffer(buffer, size, vs);
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
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);
}
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
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);
UpdateRenderingMode();
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)
{
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertexTex2];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
unsigned int size = vertexCount * sizeof(VertexTex2);
BindVAO(info.vao);
BindVBO(info.vbo);
BindVAO(m_auxiliaryVAO);
BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer
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;
UpdateDynamicBuffer(buffer, size, vs);
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
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)));
}
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
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)));
UpdateRenderingMode();
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
}
void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
{
VertexCol* vs = const_cast<VertexCol*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertexCol];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
unsigned int size = vertexCount * sizeof(VertexCol);
BindVAO(info.vao);
BindVBO(info.vbo);
BindVAO(m_auxiliaryVAO);
BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer
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;
UpdateDynamicBuffer(buffer, size, vs);
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, coord)));
// Normal
glDisableVertexAttribArray(1);
glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
// Normal
glDisableVertexAttribArray(1);
glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
// Color
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, color)));
// Color
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, color)));
// Texture coordinate 0
glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 0
glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
}
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
UpdateRenderingMode();
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
}
void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
int first[], int count[], int drawCount, Color color)
{
Vertex* vs = const_cast<Vertex*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertex];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
int vertexCount = 0;
@ -1355,56 +1360,47 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
unsigned int size = vertexCount * sizeof(Vertex);
BindVAO(info.vao);
BindVBO(info.vbo);
BindVAO(m_auxiliaryVAO);
BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer
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;
UpdateDynamicBuffer(buffer, size, vs);
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
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);
}
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
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);
UpdateRenderingMode();
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
}
void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
int first[], int count[], int drawCount, Color color)
{
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertexTex2];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
int vertexCount = 0;
@ -1418,57 +1414,48 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
unsigned int size = vertexCount * sizeof(VertexTex2);
BindVAO(info.vao);
BindVBO(info.vbo);
BindVAO(m_auxiliaryVAO);
BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer
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;
UpdateDynamicBuffer(buffer, size, vs);
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
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)));
}
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
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)));
UpdateRenderingMode();
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
}
void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
int first[], int count[], int drawCount)
{
VertexCol* vs = const_cast<VertexCol*>(vertices);
VertexBufferInfo &info = m_vboObjects[m_vertexCol];
DynamicBuffer &buffer = m_buffers[m_nextBuffer];
int vertexCount = 0;
@ -1482,46 +1469,38 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
unsigned int size = vertexCount * sizeof(VertexCol);
BindVAO(info.vao);
BindVBO(info.vbo);
BindVAO(m_auxiliaryVAO);
BindVBO(buffer.vbo);
// If needed vertex data is too large, increase the size of buffer
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;
UpdateDynamicBuffer(buffer, size, vs);
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, coord)));
// Normal
glDisableVertexAttribArray(1);
glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
// Normal
glDisableVertexAttribArray(1);
glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
// Color
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, color)));
// Color
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, color)));
// Texture coordinate 0
glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 0
glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
}
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
UpdateRenderingMode();
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)
@ -1870,13 +1849,7 @@ void CGL33Device::DestroyStaticBuffer(unsigned int bufferId)
int CGL33Device::ComputeSphereVisibility(const Math::Vector &center, float radius)
{
Math::Matrix m;
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::Matrix &m = m_combinedMatrix;
Math::Vector vec[6];
float originPlane[6];
@ -2163,6 +2136,19 @@ inline void CGL33Device::BindVAO(GLuint 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()
{
return m_anisotropyAvailable;

View File

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