Optimizations and changes in OpenGL 3.3 device.
* Limited number of lights to 4 * Only directional lights * Per-pixel lighting * Improved dynamic shadows a bit * Optimized texture changesdev-buzzingcars
parent
46aa6fc907
commit
7bb3245092
|
@ -233,7 +233,7 @@ bool CGL33Device::Create()
|
||||||
glViewport(0, 0, m_config.size.x, m_config.size.y);
|
glViewport(0, 0, m_config.size.x, m_config.size.y);
|
||||||
|
|
||||||
// this is set in shader
|
// this is set in shader
|
||||||
m_capabilities.maxLights = 8;
|
m_capabilities.maxLights = 4;
|
||||||
|
|
||||||
m_lights = std::vector<Light>(m_capabilities.maxLights, Light());
|
m_lights = std::vector<Light>(m_capabilities.maxLights, Light());
|
||||||
m_lightsEnabled = std::vector<bool>(m_capabilities.maxLights, false);
|
m_lightsEnabled = std::vector<bool>(m_capabilities.maxLights, false);
|
||||||
|
@ -381,14 +381,14 @@ bool CGL33Device::Create()
|
||||||
|
|
||||||
uni.shadowColor = glGetUniformLocation(m_normalProgram, "uni_ShadowColor");
|
uni.shadowColor = glGetUniformLocation(m_normalProgram, "uni_ShadowColor");
|
||||||
|
|
||||||
uni.lightingEnabled = glGetUniformLocation(m_normalProgram, "uni_LightingEnabled");
|
uni.lightCount = glGetUniformLocation(m_normalProgram, "uni_LightCount");
|
||||||
|
|
||||||
uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_AmbientColor");
|
uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_AmbientColor");
|
||||||
uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_DiffuseColor");
|
uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_DiffuseColor");
|
||||||
uni.specularColor = glGetUniformLocation(m_normalProgram, "uni_SpecularColor");
|
uni.specularColor = glGetUniformLocation(m_normalProgram, "uni_SpecularColor");
|
||||||
|
|
||||||
GLchar name[64];
|
GLchar name[64];
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < m_capabilities.maxLights; i++)
|
||||||
{
|
{
|
||||||
LightLocations &light = uni.lights[i];
|
LightLocations &light = uni.lights[i];
|
||||||
|
|
||||||
|
@ -440,12 +440,9 @@ bool CGL33Device::Create()
|
||||||
glUniform1f(uni.shadowColor, 0.5f);
|
glUniform1f(uni.shadowColor, 0.5f);
|
||||||
|
|
||||||
glUniform1i(uni.alphaTestEnabled, 0);
|
glUniform1i(uni.alphaTestEnabled, 0);
|
||||||
glUniform1f(uni.alphaReference, 1.0f);
|
glUniform1f(uni.alphaReference, 0.5f);
|
||||||
|
|
||||||
glUniform1i(uni.lightingEnabled, 0);
|
glUniform1i(uni.lightCount, 0);
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
glUniform1i(uni.lights[i].enabled, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain uniform locations for interface program
|
// Obtain uniform locations for interface program
|
||||||
|
@ -637,7 +634,9 @@ void CGL33Device::SetRenderMode(RenderMode mode)
|
||||||
|
|
||||||
m_uni = &m_uniforms[m_mode];
|
m_uni = &m_uniforms[m_mode];
|
||||||
|
|
||||||
UpdateRenderingMode();
|
UpdateTextureState(0);
|
||||||
|
UpdateTextureState(1);
|
||||||
|
UpdateTextureState(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
|
void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
|
||||||
|
@ -708,23 +707,7 @@ void CGL33Device::SetLight(int index, const Light &light)
|
||||||
|
|
||||||
m_lights[index] = light;
|
m_lights[index] = light;
|
||||||
|
|
||||||
LightLocations &uni = m_uni->lights[index];
|
m_updateLights = true;
|
||||||
|
|
||||||
glUniform4fv(uni.ambient, 1, light.ambient.Array());
|
|
||||||
glUniform4fv(uni.diffuse, 1, light.diffuse.Array());
|
|
||||||
glUniform4fv(uni.specular, 1, light.specular.Array());
|
|
||||||
glUniform3f(uni.attenuation, light.attenuation0, light.attenuation1, light.attenuation2);
|
|
||||||
|
|
||||||
if (light.type == LIGHT_DIRECTIONAL)
|
|
||||||
{
|
|
||||||
glUniform4f(uni.position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glUniform4f(uni.position, light.position.x, light.position.y, light.position.z, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: add spotlight params
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::SetLightEnabled(int index, bool enabled)
|
void CGL33Device::SetLightEnabled(int index, bool enabled)
|
||||||
|
@ -734,7 +717,7 @@ void CGL33Device::SetLightEnabled(int index, bool enabled)
|
||||||
|
|
||||||
m_lightsEnabled[index] = enabled;
|
m_lightsEnabled[index] = enabled;
|
||||||
|
|
||||||
glUniform1i(m_uni->lights[index].enabled, enabled ? 1 : 0);
|
m_updateLights = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If image is invalid, returns invalid texture.
|
/** If image is invalid, returns invalid texture.
|
||||||
|
@ -769,10 +752,9 @@ Texture CGL33Device::CreateTexture(ImageData *data, const TextureCreateParams &p
|
||||||
|
|
||||||
result.originalSize = result.size;
|
result.originalSize = result.size;
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
glGenTextures(1, &result.id);
|
glGenTextures(1, &result.id);
|
||||||
glBindTexture(GL_TEXTURE_2D, result.id);
|
|
||||||
|
BindTexture(m_freeTexture, result.id);
|
||||||
|
|
||||||
// Set texture parameters
|
// Set texture parameters
|
||||||
GLint minF = GL_NEAREST, magF = GL_NEAREST;
|
GLint minF = GL_NEAREST, magF = GL_NEAREST;
|
||||||
|
@ -835,9 +817,6 @@ Texture CGL33Device::CreateTexture(ImageData *data, const TextureCreateParams &p
|
||||||
|
|
||||||
m_allTextures.insert(result);
|
m_allTextures.insert(result);
|
||||||
|
|
||||||
// Restore the previous state of 1st stage
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,10 +828,9 @@ Texture CGL33Device::CreateDepthTexture(int width, int height, int depth)
|
||||||
result.size.x = width;
|
result.size.x = width;
|
||||||
result.size.y = height;
|
result.size.y = height;
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
glGenTextures(1, &result.id);
|
glGenTextures(1, &result.id);
|
||||||
glBindTexture(GL_TEXTURE_2D, result.id);
|
|
||||||
|
BindTexture(m_freeTexture, result.id);
|
||||||
|
|
||||||
GLuint format = GL_DEPTH_COMPONENT;
|
GLuint format = GL_DEPTH_COMPONENT;
|
||||||
|
|
||||||
|
@ -881,16 +859,14 @@ Texture CGL33Device::CreateDepthTexture(int width, int height, int depth)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::UpdateTexture(const Texture& texture, Math::IntPoint offset, ImageData* data, TexImgFormat format)
|
void CGL33Device::UpdateTexture(const Texture& texture, Math::IntPoint offset, ImageData* data, TexImgFormat format)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
if (texture.id == 0) return;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
BindTexture(m_freeTexture, texture.id);
|
||||||
|
|
||||||
PreparedTextureData texData = PrepareTextureData(data, format);
|
PreparedTextureData texData = PrepareTextureData(data, format);
|
||||||
|
|
||||||
|
@ -945,18 +921,16 @@ void CGL33Device::SetTexture(int index, const Texture &texture)
|
||||||
{
|
{
|
||||||
assert(index >= 0 && index < static_cast<int>( m_currentTextures.size() ));
|
assert(index >= 0 && index < static_cast<int>( m_currentTextures.size() ));
|
||||||
|
|
||||||
bool same = m_currentTextures[index].id == texture.id;
|
if (m_currentTextures[index].id == texture.id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BindTexture(index, texture.id);
|
||||||
|
|
||||||
m_currentTextures[index] = texture; // remember the new value
|
m_currentTextures[index] = texture; // remember the new value
|
||||||
|
|
||||||
if (same)
|
|
||||||
return; // nothing to do
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + index);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
|
||||||
|
|
||||||
// Params need to be updated for the new bound texture
|
// Params need to be updated for the new bound texture
|
||||||
UpdateTextureParams(index);
|
UpdateTextureParams(index);
|
||||||
|
UpdateTextureState(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::SetTexture(int index, unsigned int textureId)
|
void CGL33Device::SetTexture(int index, unsigned int textureId)
|
||||||
|
@ -966,27 +940,25 @@ void CGL33Device::SetTexture(int index, unsigned int textureId)
|
||||||
if (m_currentTextures[index].id == textureId)
|
if (m_currentTextures[index].id == textureId)
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
|
|
||||||
m_currentTextures[index].id = textureId;
|
BindTexture(index, textureId);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + index);
|
m_currentTextures[index].id = textureId;
|
||||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
|
||||||
|
|
||||||
// Params need to be updated for the new bound texture
|
// Params need to be updated for the new bound texture
|
||||||
UpdateTextureParams(index);
|
UpdateTextureParams(index);
|
||||||
|
UpdateTextureState(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::SetTextureEnabled(int index, bool enabled)
|
void CGL33Device::SetTextureEnabled(int index, bool enabled)
|
||||||
{
|
{
|
||||||
assert(index >= 0 && index < static_cast<int>( m_currentTextures.size() ));
|
assert(index >= 0 && index < static_cast<int>( m_currentTextures.size() ));
|
||||||
|
|
||||||
bool same = m_texturesEnabled[index] == enabled;
|
if (m_texturesEnabled[index] == enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
m_texturesEnabled[index] = enabled;
|
m_texturesEnabled[index] = enabled;
|
||||||
|
|
||||||
if (same)
|
UpdateTextureState(index);
|
||||||
return; // nothing to do
|
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1065,6 +1037,8 @@ 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)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
Vertex* vs = const_cast<Vertex*>(vertices);
|
Vertex* vs = const_cast<Vertex*>(vertices);
|
||||||
|
|
||||||
unsigned int size = vertexCount * sizeof(Vertex);
|
unsigned int size = vertexCount * sizeof(Vertex);
|
||||||
|
@ -1099,13 +1073,13 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int
|
||||||
glDisableVertexAttribArray(4);
|
glDisableVertexAttribArray(4);
|
||||||
glVertexAttrib2f(4, 0.0f, 0.0f);
|
glVertexAttrib2f(4, 0.0f, 0.0f);
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
|
|
||||||
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
|
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color)
|
void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
|
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
|
||||||
|
|
||||||
unsigned int size = vertexCount * sizeof(VertexTex2);
|
unsigned int size = vertexCount * sizeof(VertexTex2);
|
||||||
|
@ -1141,13 +1115,13 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices,
|
||||||
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
|
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
|
||||||
reinterpret_cast<void*>(offset + offsetof(VertexTex2, texCoord2)));
|
reinterpret_cast<void*>(offset + offsetof(VertexTex2, texCoord2)));
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
|
|
||||||
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
|
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
|
void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
VertexCol* vs = const_cast<VertexCol*>(vertices);
|
VertexCol* vs = const_cast<VertexCol*>(vertices);
|
||||||
|
|
||||||
unsigned int size = vertexCount * sizeof(VertexCol);
|
unsigned int size = vertexCount * sizeof(VertexCol);
|
||||||
|
@ -1181,14 +1155,14 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
|
||||||
glDisableVertexAttribArray(4);
|
glDisableVertexAttribArray(4);
|
||||||
glVertexAttrib2f(4, 0.0f, 0.0f);
|
glVertexAttrib2f(4, 0.0f, 0.0f);
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
|
|
||||||
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
|
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::DrawPrimitive(PrimitiveType type, const void *vertices,
|
void CGL33Device::DrawPrimitive(PrimitiveType type, const void *vertices,
|
||||||
int size, const VertexFormat &format, int vertexCount)
|
int size, const VertexFormat &format, int vertexCount)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
DynamicBuffer& buffer = m_dynamicBuffer;
|
DynamicBuffer& buffer = m_dynamicBuffer;
|
||||||
|
|
||||||
BindVAO(buffer.vao);
|
BindVAO(buffer.vao);
|
||||||
|
@ -1203,14 +1177,14 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const void *vertices,
|
||||||
UpdateVertexAttribute(3, format.tex1, offset);
|
UpdateVertexAttribute(3, format.tex1, offset);
|
||||||
UpdateVertexAttribute(4, format.tex2, offset);
|
UpdateVertexAttribute(4, format.tex2, offset);
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
|
|
||||||
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
|
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::DrawPrimitives(PrimitiveType type, const void *vertices,
|
void CGL33Device::DrawPrimitives(PrimitiveType type, const void *vertices,
|
||||||
int size, const VertexFormat &format, int first[], int count[], int drawCount)
|
int size, const VertexFormat &format, int first[], int count[], int drawCount)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
DynamicBuffer& buffer = m_dynamicBuffer;
|
DynamicBuffer& buffer = m_dynamicBuffer;
|
||||||
|
|
||||||
BindVAO(buffer.vao);
|
BindVAO(buffer.vao);
|
||||||
|
@ -1225,14 +1199,14 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const void *vertices,
|
||||||
UpdateVertexAttribute(3, format.tex1, offset);
|
UpdateVertexAttribute(3, format.tex1, offset);
|
||||||
UpdateVertexAttribute(4, format.tex2, offset);
|
UpdateVertexAttribute(4, format.tex2, offset);
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
|
|
||||||
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
|
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
Vertex* vs = const_cast<Vertex*>(vertices);
|
Vertex* vs = const_cast<Vertex*>(vertices);
|
||||||
|
|
||||||
int vertexCount = 0;
|
int vertexCount = 0;
|
||||||
|
@ -1277,14 +1251,14 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
|
||||||
glDisableVertexAttribArray(4);
|
glDisableVertexAttribArray(4);
|
||||||
glVertexAttrib2f(4, 0.0f, 0.0f);
|
glVertexAttrib2f(4, 0.0f, 0.0f);
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
|
|
||||||
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
|
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
|
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
|
||||||
|
|
||||||
int vertexCount = 0;
|
int vertexCount = 0;
|
||||||
|
@ -1330,14 +1304,14 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
|
||||||
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
|
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
|
||||||
reinterpret_cast<void*>(offset + offsetof(VertexTex2, texCoord2)));
|
reinterpret_cast<void*>(offset + offsetof(VertexTex2, texCoord2)));
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
|
|
||||||
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
|
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
VertexCol* vs = const_cast<VertexCol*>(vertices);
|
VertexCol* vs = const_cast<VertexCol*>(vertices);
|
||||||
|
|
||||||
int vertexCount = 0;
|
int vertexCount = 0;
|
||||||
|
@ -1381,8 +1355,6 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
|
||||||
glDisableVertexAttribArray(4);
|
glDisableVertexAttribArray(4);
|
||||||
glVertexAttrib2f(4, 0.0f, 0.0f);
|
glVertexAttrib2f(4, 0.0f, 0.0f);
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
|
|
||||||
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
|
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1701,14 +1673,14 @@ void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit
|
||||||
|
|
||||||
void CGL33Device::DrawStaticBuffer(unsigned int bufferId)
|
void CGL33Device::DrawStaticBuffer(unsigned int bufferId)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
auto it = m_vboObjects.find(bufferId);
|
auto it = m_vboObjects.find(bufferId);
|
||||||
if (it == m_vboObjects.end())
|
if (it == m_vboObjects.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VertexBufferInfo &info = (*it).second;
|
VertexBufferInfo &info = (*it).second;
|
||||||
|
|
||||||
UpdateRenderingMode();
|
|
||||||
|
|
||||||
BindVAO(info.vao);
|
BindVAO(info.vao);
|
||||||
|
|
||||||
GLenum mode = TranslateGfxPrimitive(info.primitiveType);
|
GLenum mode = TranslateGfxPrimitive(info.primitiveType);
|
||||||
|
@ -1836,7 +1808,9 @@ void CGL33Device::SetRenderState(RenderState state, bool enabled)
|
||||||
{
|
{
|
||||||
m_lighting = enabled;
|
m_lighting = enabled;
|
||||||
|
|
||||||
glUniform1i(m_uni->lightingEnabled, enabled ? 1 : 0);
|
m_updateLights = true;
|
||||||
|
|
||||||
|
//glUniform1i(m_uni->lightingEnabled, enabled ? 1 : 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1962,13 +1936,9 @@ void CGL33Device::CopyFramebufferToTexture(Texture& texture, int xOffset, int yO
|
||||||
{
|
{
|
||||||
if (texture.id == 0) return;
|
if (texture.id == 0) return;
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
BindTexture(m_freeTexture, texture.id);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
|
||||||
|
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height);
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height);
|
||||||
|
|
||||||
// Restore previous texture
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CFrameBufferPixels> CGL33Device::GetFrameBufferPixels() const
|
std::unique_ptr<CFrameBufferPixels> CGL33Device::GetFrameBufferPixels() const
|
||||||
|
@ -2014,16 +1984,52 @@ void CGL33Device::DeleteFramebuffer(std::string name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL33Device::UpdateRenderingMode()
|
inline void CGL33Device::UpdateTextureState(int index)
|
||||||
{
|
{
|
||||||
bool enabled = m_texturesEnabled[0] && m_currentTextures[0].id != 0;
|
bool enabled = m_texturesEnabled[index] && (m_currentTextures[index].id != 0);
|
||||||
glUniform1i(m_uni->textureEnabled[0], enabled ? 1 : 0);
|
glUniform1i(m_uni->textureEnabled[index], enabled ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
enabled = m_texturesEnabled[1] && m_currentTextures[1].id != 0;
|
void CGL33Device::UpdateLights()
|
||||||
glUniform1i(m_uni->textureEnabled[1], enabled ? 1 : 0);
|
{
|
||||||
|
m_updateLights = false;
|
||||||
|
|
||||||
enabled = m_texturesEnabled[2] && m_currentTextures[2].id != 0;
|
// If not in normal rendering mode, return immediately
|
||||||
glUniform1i(m_uni->textureEnabled[2], enabled ? 1 : 0);
|
if (m_mode != 0) return;
|
||||||
|
|
||||||
|
// Lighting enabled
|
||||||
|
if (m_lighting)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
// Iterate all lights
|
||||||
|
for (unsigned int i = 0; i < m_lights.size(); i++)
|
||||||
|
{
|
||||||
|
// If disabled, ignore and continue
|
||||||
|
if (!m_lightsEnabled[i]) continue;
|
||||||
|
|
||||||
|
// If not directional, ignore and continue
|
||||||
|
if (m_lights[i].type != LIGHT_DIRECTIONAL) continue;
|
||||||
|
|
||||||
|
Light &light = m_lights[i];
|
||||||
|
LightLocations &uni = m_uni->lights[index];
|
||||||
|
|
||||||
|
glUniform4fv(uni.ambient, 1, light.ambient.Array());
|
||||||
|
glUniform4fv(uni.diffuse, 1, light.diffuse.Array());
|
||||||
|
glUniform4fv(uni.specular, 1, light.specular.Array());
|
||||||
|
|
||||||
|
glUniform4f(uni.position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
glUniform1i(m_uni->lightCount, index);
|
||||||
|
}
|
||||||
|
// Lighting disabled
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glUniform1i(m_uni->lightCount, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CGL33Device::BindVBO(GLuint vbo)
|
inline void CGL33Device::BindVBO(GLuint vbo)
|
||||||
|
@ -2042,6 +2048,12 @@ inline void CGL33Device::BindVAO(GLuint vao)
|
||||||
m_currentVAO = vao;
|
m_currentVAO = vao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void CGL33Device::BindTexture(int index, GLuint texture)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + index);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int CGL33Device::UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size)
|
unsigned int CGL33Device::UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size)
|
||||||
{
|
{
|
||||||
unsigned int nextOffset = buffer.offset + size;
|
unsigned int nextOffset = buffer.offset + size;
|
||||||
|
|
|
@ -198,13 +198,17 @@ public:
|
||||||
private:
|
private:
|
||||||
//! 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 rendering mode
|
//! Updates texture state
|
||||||
void UpdateRenderingMode();
|
inline void UpdateTextureState(int index);
|
||||||
|
//! Update light parameters
|
||||||
|
void UpdateLights();
|
||||||
|
|
||||||
//! Binds VBO
|
//! Binds VBO
|
||||||
inline void BindVBO(GLuint vbo);
|
inline void BindVBO(GLuint vbo);
|
||||||
//! Binds VAO
|
//! Binds VAO
|
||||||
inline void BindVAO(GLuint vao);
|
inline void BindVAO(GLuint vao);
|
||||||
|
//! Binds texture
|
||||||
|
inline void BindTexture(int index, GLuint texture);
|
||||||
|
|
||||||
//! Uploads data to dynamic buffer and returns offset to it
|
//! Uploads data to dynamic buffer and returns offset to it
|
||||||
unsigned int UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size);
|
unsigned int UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size);
|
||||||
|
@ -233,6 +237,8 @@ private:
|
||||||
|
|
||||||
//! Whether lighting is enabled
|
//! Whether lighting is enabled
|
||||||
bool m_lighting = false;
|
bool m_lighting = false;
|
||||||
|
//! true means that light update is needed
|
||||||
|
bool m_updateLights = false;
|
||||||
//! Current lights
|
//! Current lights
|
||||||
std::vector<Light> m_lights;
|
std::vector<Light> m_lights;
|
||||||
//! Current lights enable status
|
//! Current lights enable status
|
||||||
|
@ -247,6 +253,8 @@ private:
|
||||||
|
|
||||||
//! Set of all created textures
|
//! Set of all created textures
|
||||||
std::set<Texture> m_allTextures;
|
std::set<Texture> m_allTextures;
|
||||||
|
//! Free texture unit
|
||||||
|
const int m_freeTexture = 3;
|
||||||
|
|
||||||
//! Type of vertex structure
|
//! Type of vertex structure
|
||||||
enum VertexType
|
enum VertexType
|
||||||
|
|
|
@ -196,6 +196,8 @@ struct UniformLocations
|
||||||
|
|
||||||
//! true enables lighting
|
//! true enables lighting
|
||||||
GLint lightingEnabled = -1;
|
GLint lightingEnabled = -1;
|
||||||
|
// Number of enabled lights
|
||||||
|
GLint lightCount = -1;
|
||||||
//! Ambient color
|
//! Ambient color
|
||||||
GLint ambientColor = -1;
|
GLint ambientColor = -1;
|
||||||
//! Diffuse color
|
//! Diffuse color
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
// FRAGMENT SHADER - NORMAL MODE
|
// FRAGMENT SHADER - NORMAL MODE
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#define CONFIG_QUALITY_SHADOWS 1
|
||||||
|
|
||||||
uniform sampler2D uni_PrimaryTexture;
|
uniform sampler2D uni_PrimaryTexture;
|
||||||
uniform sampler2D uni_SecondaryTexture;
|
uniform sampler2D uni_SecondaryTexture;
|
||||||
uniform sampler2DShadow uni_ShadowTexture;
|
uniform sampler2DShadow uni_ShadowTexture;
|
||||||
|
@ -37,11 +39,27 @@ uniform float uni_ShadowColor;
|
||||||
uniform bool uni_AlphaTestEnabled;
|
uniform bool uni_AlphaTestEnabled;
|
||||||
uniform float uni_AlphaReference;
|
uniform float uni_AlphaReference;
|
||||||
|
|
||||||
|
struct LightParams
|
||||||
|
{
|
||||||
|
vec4 Position;
|
||||||
|
vec4 Ambient;
|
||||||
|
vec4 Diffuse;
|
||||||
|
vec4 Specular;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform vec4 uni_AmbientColor;
|
||||||
|
uniform vec4 uni_DiffuseColor;
|
||||||
|
uniform vec4 uni_SpecularColor;
|
||||||
|
|
||||||
|
uniform int uni_LightCount;
|
||||||
|
uniform LightParams uni_Light[4];
|
||||||
|
|
||||||
in VertexData
|
in VertexData
|
||||||
{
|
{
|
||||||
vec4 Color;
|
vec4 Color;
|
||||||
vec2 TexCoord0;
|
vec2 TexCoord0;
|
||||||
vec2 TexCoord1;
|
vec2 TexCoord1;
|
||||||
|
vec3 Normal;
|
||||||
vec4 ShadowCoord;
|
vec4 ShadowCoord;
|
||||||
vec4 LightColor;
|
vec4 LightColor;
|
||||||
float Distance;
|
float Distance;
|
||||||
|
@ -53,6 +71,53 @@ void main()
|
||||||
{
|
{
|
||||||
vec4 color = data.Color;
|
vec4 color = data.Color;
|
||||||
|
|
||||||
|
if (uni_LightCount > 0)
|
||||||
|
{
|
||||||
|
vec4 ambient = vec4(0.0f);
|
||||||
|
vec4 diffuse = vec4(0.0f);
|
||||||
|
vec4 specular = vec4(0.0f);
|
||||||
|
|
||||||
|
vec3 normal = normalize(data.Normal);
|
||||||
|
|
||||||
|
for (int i = 0; i < uni_LightCount; i++)
|
||||||
|
{
|
||||||
|
vec3 lightDirection = uni_Light[i].Position.xyz;
|
||||||
|
|
||||||
|
vec3 reflectDirection = -reflect(lightDirection, normal);
|
||||||
|
|
||||||
|
ambient += uni_Light[i].Ambient;
|
||||||
|
diffuse += clamp(dot(normal, lightDirection), 0.0f, 1.0f)
|
||||||
|
* uni_Light[i].Diffuse;
|
||||||
|
specular += clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f)
|
||||||
|
* uni_Light[i].Specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
float shadow = 1.0f;
|
||||||
|
|
||||||
|
if (uni_ShadowTextureEnabled)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_QUALITY_SHADOWS
|
||||||
|
float offset = 0.00025f;
|
||||||
|
|
||||||
|
float value = (1.0f / 5.0f) * (texture(uni_ShadowTexture, data.ShadowCoord.xyz)
|
||||||
|
+ texture(uni_ShadowTexture, data.ShadowCoord.xyz + vec3( offset, 0.0f, 0.0f))
|
||||||
|
+ texture(uni_ShadowTexture, data.ShadowCoord.xyz + vec3(-offset, 0.0f, 0.0f))
|
||||||
|
+ texture(uni_ShadowTexture, data.ShadowCoord.xyz + vec3( 0.0f, offset, 0.0f))
|
||||||
|
+ texture(uni_ShadowTexture, data.ShadowCoord.xyz + vec3( 0.0f, -offset, 0.0f)));
|
||||||
|
|
||||||
|
shadow = mix(uni_ShadowColor, 1.0f, value);
|
||||||
|
#else
|
||||||
|
shadow = mix(uni_ShadowColor, 1.0f, texture(uni_ShadowTexture, data.ShadowCoord.xyz));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 result = uni_AmbientColor * ambient
|
||||||
|
+ uni_DiffuseColor * diffuse * shadow
|
||||||
|
+ uni_SpecularColor * specular * shadow;
|
||||||
|
|
||||||
|
color = vec4(min(vec3(1.0f), result.rgb), 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (uni_PrimaryTextureEnabled)
|
if (uni_PrimaryTextureEnabled)
|
||||||
{
|
{
|
||||||
color = color * texture(uni_PrimaryTexture, data.TexCoord0);
|
color = color * texture(uni_PrimaryTexture, data.TexCoord0);
|
||||||
|
@ -63,11 +128,6 @@ void main()
|
||||||
color = color * texture(uni_SecondaryTexture, data.TexCoord1);
|
color = color * texture(uni_SecondaryTexture, data.TexCoord1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uni_ShadowTextureEnabled)
|
|
||||||
{
|
|
||||||
color = color * mix(uni_ShadowColor, 1.0f, texture(uni_ShadowTexture, data.ShadowCoord.xyz));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uni_FogEnabled)
|
if (uni_FogEnabled)
|
||||||
{
|
{
|
||||||
float interpolate = (data.Distance - uni_FogRange.x) / (uni_FogRange.y - uni_FogRange.x);
|
float interpolate = (data.Distance - uni_FogRange.x) / (uni_FogRange.y - uni_FogRange.x);
|
||||||
|
|
|
@ -20,24 +20,6 @@
|
||||||
// VERTEX SHADER - NORMAL MODE
|
// VERTEX SHADER - NORMAL MODE
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
struct LightParams
|
|
||||||
{
|
|
||||||
bool Enabled;
|
|
||||||
vec4 Position;
|
|
||||||
vec4 Ambient;
|
|
||||||
vec4 Diffuse;
|
|
||||||
vec4 Specular;
|
|
||||||
float Shininess;
|
|
||||||
vec3 Attenuation;
|
|
||||||
};
|
|
||||||
|
|
||||||
uniform vec4 uni_AmbientColor;
|
|
||||||
uniform vec4 uni_DiffuseColor;
|
|
||||||
uniform vec4 uni_SpecularColor;
|
|
||||||
|
|
||||||
uniform bool uni_LightingEnabled;
|
|
||||||
uniform LightParams uni_Light[8];
|
|
||||||
|
|
||||||
uniform mat4 uni_ProjectionMatrix;
|
uniform mat4 uni_ProjectionMatrix;
|
||||||
uniform mat4 uni_ViewMatrix;
|
uniform mat4 uni_ViewMatrix;
|
||||||
uniform mat4 uni_ModelMatrix;
|
uniform mat4 uni_ModelMatrix;
|
||||||
|
@ -55,6 +37,7 @@ out VertexData
|
||||||
vec4 Color;
|
vec4 Color;
|
||||||
vec2 TexCoord0;
|
vec2 TexCoord0;
|
||||||
vec2 TexCoord1;
|
vec2 TexCoord1;
|
||||||
|
vec3 Normal;
|
||||||
vec4 ShadowCoord;
|
vec4 ShadowCoord;
|
||||||
vec4 LightColor;
|
vec4 LightColor;
|
||||||
float Distance;
|
float Distance;
|
||||||
|
@ -70,58 +53,7 @@ void main()
|
||||||
data.Color = in_Color;
|
data.Color = in_Color;
|
||||||
data.TexCoord0 = in_TexCoord0;
|
data.TexCoord0 = in_TexCoord0;
|
||||||
data.TexCoord1 = in_TexCoord1;
|
data.TexCoord1 = in_TexCoord1;
|
||||||
|
data.Normal = normalize((uni_NormalMatrix * vec4(in_Normal, 0.0f)).xyz);
|
||||||
data.ShadowCoord = vec4(shadowCoord.xyz / shadowCoord.w, 1.0f);
|
data.ShadowCoord = vec4(shadowCoord.xyz / shadowCoord.w, 1.0f);
|
||||||
data.Distance = abs(eyeSpace.z);
|
data.Distance = abs(eyeSpace.z);
|
||||||
|
|
||||||
vec4 color = in_Color;
|
|
||||||
|
|
||||||
if (uni_LightingEnabled)
|
|
||||||
{
|
|
||||||
vec4 ambient = vec4(0.0f);
|
|
||||||
vec4 diffuse = vec4(0.0f);
|
|
||||||
vec4 specular = vec4(0.0f);
|
|
||||||
|
|
||||||
vec3 normal = normalize((uni_NormalMatrix * vec4(in_Normal, 0.0f)).xyz);
|
|
||||||
|
|
||||||
for(int i=0; i<8; i++)
|
|
||||||
{
|
|
||||||
if(uni_Light[i].Enabled)
|
|
||||||
{
|
|
||||||
vec3 lightDirection = vec3(0.0f);
|
|
||||||
float atten;
|
|
||||||
|
|
||||||
// Directional light
|
|
||||||
if(uni_Light[i].Position[3] == 0.0f)
|
|
||||||
{
|
|
||||||
lightDirection = uni_Light[i].Position.xyz;
|
|
||||||
atten = 1.0f;
|
|
||||||
}
|
|
||||||
// Point light
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vec3 lightDirection = normalize(uni_Light[i].Position.xyz - position.xyz);
|
|
||||||
float dist = distance(uni_Light[i].Position.xyz, position.xyz);
|
|
||||||
|
|
||||||
atten = 1.0f / (uni_Light[i].Attenuation.x
|
|
||||||
+ uni_Light[i].Attenuation.y * dist
|
|
||||||
+ uni_Light[i].Attenuation.z * dist * dist);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 reflectDirection = -reflect(lightDirection, normal);
|
|
||||||
|
|
||||||
ambient += uni_Light[i].Ambient;
|
|
||||||
diffuse += atten * clamp(dot(normal, lightDirection), 0.0f, 1.0f) * uni_Light[i].Diffuse;
|
|
||||||
specular += atten * clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f) * uni_Light[i].Specular;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 result = uni_AmbientColor * ambient
|
|
||||||
+ uni_DiffuseColor * diffuse
|
|
||||||
+ uni_SpecularColor * specular;
|
|
||||||
|
|
||||||
color.rgb = min(vec3(1.0f), result.rgb);
|
|
||||||
color.a = 1.0f; //min(1.0f, 1.0f);
|
|
||||||
|
|
||||||
data.Color = color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue