Added rendering modes and implemented additional OpenGL 2.1 shaders
parent
bf8916b9eb
commit
6b7e6cbc75
|
@ -130,6 +130,17 @@ enum RenderState
|
||||||
RENDER_STATE_DEPTH_BIAS,
|
RENDER_STATE_DEPTH_BIAS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \enum RenderMode
|
||||||
|
* \brief Render modes the graphics device can be in
|
||||||
|
*/
|
||||||
|
enum RenderMode
|
||||||
|
{
|
||||||
|
RENDER_MODE_NORMAL,
|
||||||
|
RENDER_MODE_INTERFACE,
|
||||||
|
RENDER_MODE_SHADOW,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \enum CompFunc
|
* \enum CompFunc
|
||||||
* \brief Type of function used to compare values
|
* \brief Type of function used to compare values
|
||||||
|
@ -310,6 +321,9 @@ public:
|
||||||
//! Clears the screen to blank
|
//! Clears the screen to blank
|
||||||
virtual void Clear() = 0;
|
virtual void Clear() = 0;
|
||||||
|
|
||||||
|
//! Sets current rendering mode
|
||||||
|
virtual void SetRenderMode(RenderMode mode) = 0;
|
||||||
|
|
||||||
//! Sets the transform matrix of given type
|
//! Sets the transform matrix of given type
|
||||||
virtual void SetTransform(TransformType type, const Math::Matrix &matrix) = 0;
|
virtual void SetTransform(TransformType type, const Math::Matrix &matrix) = 0;
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,10 @@ void CNullDevice::Clear()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CNullDevice::SetRenderMode(RenderMode mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void CNullDevice::SetTransform(TransformType type, const Math::Matrix &matrix)
|
void CNullDevice::SetTransform(TransformType type, const Math::Matrix &matrix)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ public:
|
||||||
|
|
||||||
void Clear() override;
|
void Clear() override;
|
||||||
|
|
||||||
|
void SetRenderMode(RenderMode mode) override;
|
||||||
|
|
||||||
void SetTransform(TransformType type, const Math::Matrix &matrix) override;
|
void SetTransform(TransformType type, const Math::Matrix &matrix) override;
|
||||||
|
|
||||||
void SetMaterial(const Material &material) override;
|
void SetMaterial(const Material &material) override;
|
||||||
|
|
|
@ -2038,7 +2038,8 @@ void CEngine::SetState(int state, const Color& color)
|
||||||
}
|
}
|
||||||
else if (state & ENG_RSTATE_ALPHA) // image with alpha channel?
|
else if (state & ENG_RSTATE_ALPHA) // image with alpha channel?
|
||||||
{
|
{
|
||||||
m_device->SetRenderState(RENDER_STATE_BLENDING, false);
|
m_device->SetRenderState(RENDER_STATE_BLENDING, true);
|
||||||
|
m_device->SetBlendFunc(BLEND_SRC_ALPHA, BLEND_INV_SRC_ALPHA);
|
||||||
|
|
||||||
m_device->SetRenderState(RENDER_STATE_FOG, true);
|
m_device->SetRenderState(RENDER_STATE_FOG, true);
|
||||||
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, true);
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, true);
|
||||||
|
@ -3113,6 +3114,8 @@ void CEngine::Render()
|
||||||
UseMSAA(true);
|
UseMSAA(true);
|
||||||
|
|
||||||
DrawBackground(); // draws the background
|
DrawBackground(); // draws the background
|
||||||
|
|
||||||
|
|
||||||
if (m_drawWorld)
|
if (m_drawWorld)
|
||||||
Draw3DScene();
|
Draw3DScene();
|
||||||
|
|
||||||
|
@ -3367,6 +3370,7 @@ void CEngine::Draw3DScene()
|
||||||
|
|
||||||
void CEngine::RenderShadowMap()
|
void CEngine::RenderShadowMap()
|
||||||
{
|
{
|
||||||
|
|
||||||
m_shadowMapping = m_shadowMapping && m_device->IsShadowMappingSupported();
|
m_shadowMapping = m_shadowMapping && m_device->IsShadowMappingSupported();
|
||||||
m_offscreenShadowRendering = m_offscreenShadowRendering && m_device->IsFramebufferSupported();
|
m_offscreenShadowRendering = m_offscreenShadowRendering && m_device->IsFramebufferSupported();
|
||||||
m_offscreenShadowRenderingResolution = Math::Min(m_offscreenShadowRenderingResolution, m_device->GetMaxTextureSize());
|
m_offscreenShadowRenderingResolution = Math::Min(m_offscreenShadowRenderingResolution, m_device->GetMaxTextureSize());
|
||||||
|
@ -3387,7 +3391,7 @@ void CEngine::RenderShadowMap()
|
||||||
|
|
||||||
FramebufferParams params;
|
FramebufferParams params;
|
||||||
params.width = params.height = width;
|
params.width = params.height = width;
|
||||||
params.depth = depth = 32;
|
params.depth = depth = 16;
|
||||||
params.depthTexture = true;
|
params.depthTexture = true;
|
||||||
|
|
||||||
CFramebuffer *framebuffer = m_device->CreateFramebuffer("shadow", params);
|
CFramebuffer *framebuffer = m_device->CreateFramebuffer("shadow", params);
|
||||||
|
@ -3427,6 +3431,7 @@ void CEngine::RenderShadowMap()
|
||||||
m_device->GetFramebuffer("shadow")->Bind();
|
m_device->GetFramebuffer("shadow")->Bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_SHADOW);
|
||||||
m_device->Clear();
|
m_device->Clear();
|
||||||
|
|
||||||
// change state to rendering shadow maps
|
// change state to rendering shadow maps
|
||||||
|
@ -3441,7 +3446,7 @@ void CEngine::RenderShadowMap()
|
||||||
m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, false);
|
m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, false);
|
||||||
m_device->SetAlphaTestFunc(COMP_FUNC_GREATER, 0.5f);
|
m_device->SetAlphaTestFunc(COMP_FUNC_GREATER, 0.5f);
|
||||||
m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, true);
|
m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, true);
|
||||||
m_device->SetDepthBias(1.5f, 8.0f);
|
m_device->SetDepthBias(2.0f, 8.0f);
|
||||||
|
|
||||||
m_device->SetViewport(0, 0, m_shadowMap.size.x, m_shadowMap.size.y);
|
m_device->SetViewport(0, 0, m_shadowMap.size.x, m_shadowMap.size.y);
|
||||||
|
|
||||||
|
@ -3543,6 +3548,7 @@ void CEngine::RenderShadowMap()
|
||||||
|
|
||||||
m_app->StopPerformanceCounter(PCNT_RENDER_SHADOW_MAP);
|
m_app->StopPerformanceCounter(PCNT_RENDER_SHADOW_MAP);
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_NORMAL);
|
||||||
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false);
|
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3776,6 +3782,8 @@ void CEngine::DrawObject(const EngineBaseObjDataTier& p4)
|
||||||
|
|
||||||
void CEngine::DrawInterface()
|
void CEngine::DrawInterface()
|
||||||
{
|
{
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_INTERFACE);
|
||||||
|
|
||||||
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false);
|
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false);
|
||||||
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
||||||
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
||||||
|
@ -3808,6 +3816,8 @@ void CEngine::DrawInterface()
|
||||||
// 3D objects drawn in front of interface
|
// 3D objects drawn in front of interface
|
||||||
if (m_drawFront)
|
if (m_drawFront)
|
||||||
{
|
{
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_NORMAL);
|
||||||
|
|
||||||
// Display the objects
|
// Display the objects
|
||||||
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, true);
|
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, true);
|
||||||
|
|
||||||
|
@ -3877,6 +3887,8 @@ void CEngine::DrawInterface()
|
||||||
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
||||||
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_INTERFACE);
|
||||||
|
|
||||||
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
||||||
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
||||||
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
||||||
|
@ -3893,6 +3905,8 @@ void CEngine::DrawInterface()
|
||||||
DrawStats();
|
DrawStats();
|
||||||
if (m_renderInterface)
|
if (m_renderInterface)
|
||||||
DrawMouse();
|
DrawMouse();
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEngine::UpdateGroundSpotTextures()
|
void CEngine::UpdateGroundSpotTextures()
|
||||||
|
@ -4366,6 +4380,8 @@ void CEngine::DrawShadowSpots()
|
||||||
|
|
||||||
void CEngine::DrawBackground()
|
void CEngine::DrawBackground()
|
||||||
{
|
{
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_INTERFACE);
|
||||||
|
|
||||||
if (m_cloud->GetLevel() != 0.0f) // clouds ?
|
if (m_cloud->GetLevel() != 0.0f) // clouds ?
|
||||||
{
|
{
|
||||||
if (m_backgroundCloudUp != m_backgroundCloudDown) // degraded?
|
if (m_backgroundCloudUp != m_backgroundCloudDown) // degraded?
|
||||||
|
@ -4381,6 +4397,8 @@ void CEngine::DrawBackground()
|
||||||
{
|
{
|
||||||
DrawBackgroundImage(); // image
|
DrawBackgroundImage(); // image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEngine::DrawBackgroundGradient(const Color& up, const Color& down)
|
void CEngine::DrawBackgroundGradient(const Color& up, const Color& down)
|
||||||
|
@ -4502,6 +4520,8 @@ void CEngine::DrawPlanet()
|
||||||
if (! m_planet->PlanetExist())
|
if (! m_planet->PlanetExist())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_INTERFACE);
|
||||||
|
|
||||||
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
||||||
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
||||||
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
||||||
|
@ -4511,6 +4531,8 @@ void CEngine::DrawPlanet()
|
||||||
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
||||||
|
|
||||||
m_planet->Draw(); // draws the planets
|
m_planet->Draw(); // draws the planets
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEngine::DrawForegroundImage()
|
void CEngine::DrawForegroundImage()
|
||||||
|
@ -4541,12 +4563,16 @@ void CEngine::DrawForegroundImage()
|
||||||
SetTexture(m_foregroundTex);
|
SetTexture(m_foregroundTex);
|
||||||
SetState(ENG_RSTATE_CLAMP | ENG_RSTATE_TTEXTURE_BLACK);
|
SetState(ENG_RSTATE_CLAMP | ENG_RSTATE_TTEXTURE_BLACK);
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_INTERFACE);
|
||||||
|
|
||||||
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
||||||
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
||||||
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
||||||
|
|
||||||
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
||||||
AddStatisticTriangle(2);
|
AddStatisticTriangle(2);
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEngine::DrawOverColor()
|
void CEngine::DrawOverColor()
|
||||||
|
@ -4565,6 +4591,8 @@ void CEngine::DrawOverColor()
|
||||||
Color(0.0f, 0.0f, 0.0f, 0.0f)
|
Color(0.0f, 0.0f, 0.0f, 0.0f)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_INTERFACE);
|
||||||
|
|
||||||
SetState(m_overMode);
|
SetState(m_overMode);
|
||||||
|
|
||||||
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
||||||
|
@ -4582,6 +4610,8 @@ void CEngine::DrawOverColor()
|
||||||
|
|
||||||
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
||||||
AddStatisticTriangle(2);
|
AddStatisticTriangle(2);
|
||||||
|
|
||||||
|
m_device->SetRenderMode(RENDER_MODE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEngine::DrawHighlight()
|
void CEngine::DrawHighlight()
|
||||||
|
|
|
@ -251,21 +251,24 @@ bool CGL21Device::Create()
|
||||||
m_perPixelLighting = value > 0;
|
m_perPixelLighting = value > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char shading[16];
|
||||||
|
|
||||||
if (m_perPixelLighting)
|
if (m_perPixelLighting)
|
||||||
|
{
|
||||||
GetLogger()->Info("Using per-pixel lighting\n");
|
GetLogger()->Info("Using per-pixel lighting\n");
|
||||||
|
strcpy(shading, "perpixel");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
GetLogger()->Info("Using per-vertex lighting\n");
|
GetLogger()->Info("Using per-vertex lighting\n");
|
||||||
|
strcpy(shading, "pervertex");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create shader program for normal rendering
|
||||||
// Create normal shader program
|
|
||||||
GLint shaders[2];
|
GLint shaders[2];
|
||||||
char filename[128];
|
char filename[128];
|
||||||
|
|
||||||
if (m_perPixelLighting)
|
sprintf(filename, "shaders/vertex_shader_21_%s.glsl", shading);
|
||||||
sprintf(filename, "shaders/vertex_shader_21_perpixel.glsl");
|
|
||||||
else
|
|
||||||
sprintf(filename, "shaders/vertex_shader_21_pervertex.glsl");
|
|
||||||
|
|
||||||
shaders[0] = LoadShader(GL_VERTEX_SHADER, filename);
|
shaders[0] = LoadShader(GL_VERTEX_SHADER, filename);
|
||||||
if (shaders[0] == 0)
|
if (shaders[0] == 0)
|
||||||
{
|
{
|
||||||
|
@ -273,114 +276,242 @@ bool CGL21Device::Create()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_perPixelLighting)
|
sprintf(filename, "shaders/fragment_shader_21_%s.glsl", shading);
|
||||||
sprintf(filename, "shaders/fragment_shader_21_perpixel.glsl");
|
|
||||||
else
|
|
||||||
sprintf(filename, "shaders/fragment_shader_21_pervertex.glsl");
|
|
||||||
|
|
||||||
shaders[1] = LoadShader(GL_FRAGMENT_SHADER, filename);
|
shaders[1] = LoadShader(GL_FRAGMENT_SHADER, filename);
|
||||||
if (shaders[1] == 0)
|
if (shaders[1] == 0)
|
||||||
{
|
{
|
||||||
m_errorMessage = GetLastShaderError();
|
m_errorMessage = GetLastShaderError();
|
||||||
|
GetLogger()->Error("Count not create vertex shader from file '%s'\n", filename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_program = LinkProgram(2, shaders);
|
m_normalProgram = LinkProgram(2, shaders);
|
||||||
if (m_program == 0)
|
if (m_normalProgram == 0)
|
||||||
{
|
{
|
||||||
m_errorMessage = GetLastShaderError();
|
m_errorMessage = GetLastShaderError();
|
||||||
|
GetLogger()->Error("Count not link shader program for normal rendering\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
glDeleteShader(shaders[0]);
|
glDeleteShader(shaders[0]);
|
||||||
glDeleteShader(shaders[1]);
|
glDeleteShader(shaders[1]);
|
||||||
|
|
||||||
// Obtain uniform locations
|
// Create shader program for interface rendering
|
||||||
uni_ProjectionMatrix = glGetUniformLocation(m_program, "uni_ProjectionMatrix");
|
strcpy(filename, "shaders/vertex_shader_21_interface.glsl");
|
||||||
uni_ViewMatrix = glGetUniformLocation(m_program, "uni_ViewMatrix");
|
shaders[0] = LoadShader(GL_VERTEX_SHADER, filename);
|
||||||
uni_ModelMatrix = glGetUniformLocation(m_program, "uni_ModelMatrix");
|
if (shaders[0] == 0)
|
||||||
uni_NormalMatrix = glGetUniformLocation(m_program, "uni_NormalMatrix");
|
|
||||||
uni_ShadowMatrix = glGetUniformLocation(m_program, "uni_ShadowMatrix");
|
|
||||||
|
|
||||||
uni_PrimaryTexture = glGetUniformLocation(m_program, "uni_PrimaryTexture");
|
|
||||||
uni_SecondaryTexture = glGetUniformLocation(m_program, "uni_SecondaryTexture");
|
|
||||||
uni_ShadowTexture = glGetUniformLocation(m_program, "uni_ShadowTexture");
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
{
|
||||||
char name[64];
|
m_errorMessage = GetLastShaderError();
|
||||||
sprintf(name, "uni_TextureEnabled[%d]", i);
|
GetLogger()->Error("Count not create vertex shader from file '%s'\n", filename);
|
||||||
uni_TextureEnabled[i] = glGetUniformLocation(m_program, name);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uni_AlphaTestEnabled = glGetUniformLocation(m_program, "uni_AlphaTestEnabled");
|
strcpy(filename, "shaders/fragment_shader_21_interface.glsl");
|
||||||
uni_AlphaReference = glGetUniformLocation(m_program, "uni_AlphaReference");
|
shaders[1] = LoadShader(GL_FRAGMENT_SHADER, filename);
|
||||||
|
if (shaders[1] == 0)
|
||||||
uni_FogEnabled = glGetUniformLocation(m_program, "uni_FogEnabled");
|
|
||||||
uni_FogRange = glGetUniformLocation(m_program, "uni_FogRange");
|
|
||||||
uni_FogColor = glGetUniformLocation(m_program, "uni_FogColor");
|
|
||||||
|
|
||||||
uni_ShadowColor = glGetUniformLocation(m_program, "uni_ShadowColor");
|
|
||||||
uni_LightingEnabled = glGetUniformLocation(m_program, "uni_LightingEnabled");
|
|
||||||
|
|
||||||
uni_AmbientColor = glGetUniformLocation(m_program, "uni_AmbientColor");
|
|
||||||
uni_DiffuseColor = glGetUniformLocation(m_program, "uni_DiffuseColor");
|
|
||||||
uni_SpecularColor = glGetUniformLocation(m_program, "uni_SpecularColor");
|
|
||||||
|
|
||||||
GLchar name[64];
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
{
|
{
|
||||||
sprintf(name, "uni_Light[%d].Enabled", i);
|
m_errorMessage = GetLastShaderError();
|
||||||
uni_Light[i].Enabled = glGetUniformLocation(m_program, name);
|
GetLogger()->Error("Count not compile fragment shader from file '%s'\n", filename);
|
||||||
|
return false;
|
||||||
sprintf(name, "uni_Light[%d].Position", i);
|
|
||||||
uni_Light[i].Position = glGetUniformLocation(m_program, name);
|
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].Ambient", i);
|
|
||||||
uni_Light[i].Ambient = glGetUniformLocation(m_program, name);
|
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].Diffuse", i);
|
|
||||||
uni_Light[i].Diffuse = glGetUniformLocation(m_program, name);
|
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].Specular", i);
|
|
||||||
uni_Light[i].Specular = glGetUniformLocation(m_program, name);
|
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].Attenuation", i);
|
|
||||||
uni_Light[i].Attenuation = glGetUniformLocation(m_program, name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default uniform values
|
m_interfaceProgram = LinkProgram(2, shaders);
|
||||||
Math::Matrix matrix;
|
if (m_interfaceProgram == 0)
|
||||||
matrix.LoadIdentity();
|
{
|
||||||
|
m_errorMessage = GetLastShaderError();
|
||||||
|
GetLogger()->Error("Count not link shader program for interface rendering\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
glUseProgram(m_program);
|
glDeleteShader(shaders[0]);
|
||||||
|
glDeleteShader(shaders[1]);
|
||||||
|
|
||||||
glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, matrix.Array());
|
// Create shader program for shadow rendering
|
||||||
glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, matrix.Array());
|
strcpy(filename, "shaders/vertex_shader_21_shadow.glsl");
|
||||||
glUniformMatrix4fv(uni_ModelMatrix, 1, GL_FALSE, matrix.Array());
|
shaders[0] = LoadShader(GL_VERTEX_SHADER, filename);
|
||||||
glUniformMatrix4fv(uni_NormalMatrix, 1, GL_FALSE, matrix.Array());
|
if (shaders[0] == 0)
|
||||||
glUniformMatrix4fv(uni_ShadowMatrix, 1, GL_FALSE, matrix.Array());
|
{
|
||||||
|
m_errorMessage = GetLastShaderError();
|
||||||
|
GetLogger()->Error("Count not create vertex shader from file '%s'\n", filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
glUniform1i(uni_PrimaryTexture, 0);
|
strcpy(filename, "shaders/fragment_shader_21_shadow.glsl");
|
||||||
glUniform1i(uni_SecondaryTexture, 1);
|
shaders[1] = LoadShader(GL_FRAGMENT_SHADER, filename);
|
||||||
glUniform1i(uni_ShadowTexture, 2);
|
if (shaders[1] == 0)
|
||||||
|
{
|
||||||
|
m_errorMessage = GetLastShaderError();
|
||||||
|
GetLogger()->Error("Count not compile fragment shader from file '%s'\n", filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
m_shadowProgram = LinkProgram(2, shaders);
|
||||||
glUniform1i(uni_TextureEnabled[i], 0);
|
if (m_shadowProgram == 0)
|
||||||
|
{
|
||||||
|
m_errorMessage = GetLastShaderError();
|
||||||
|
GetLogger()->Error("Count not link shader program for shadow rendering\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
glUniform1i(uni_AlphaTestEnabled, 0);
|
glDeleteShader(shaders[0]);
|
||||||
glUniform1f(uni_AlphaReference, 0.5f);
|
glDeleteShader(shaders[1]);
|
||||||
|
|
||||||
glUniform1i(uni_FogEnabled, 0);
|
// Obtain uniform locations from normal rendering program and initialize them
|
||||||
glUniform2f(uni_FogRange, 100.0f, 200.0f);
|
{
|
||||||
glUniform4f(uni_FogColor, 0.8f, 0.8f, 0.8f, 1.0f);
|
UniformLocations &uni = m_uniforms[0];
|
||||||
|
|
||||||
glUniform1f(uni_ShadowColor, 0.5f);
|
uni.projectionMatrix = glGetUniformLocation(m_normalProgram, "uni_ProjectionMatrix");
|
||||||
|
uni.viewMatrix = glGetUniformLocation(m_normalProgram, "uni_ViewMatrix");
|
||||||
|
uni.modelMatrix = glGetUniformLocation(m_normalProgram, "uni_ModelMatrix");
|
||||||
|
uni.normalMatrix = glGetUniformLocation(m_normalProgram, "uni_NormalMatrix");
|
||||||
|
uni.shadowMatrix = glGetUniformLocation(m_normalProgram, "uni_ShadowMatrix");
|
||||||
|
|
||||||
glUniform1i(uni_LightingEnabled, 0);
|
uni.primaryTexture = glGetUniformLocation(m_normalProgram, "uni_PrimaryTexture");
|
||||||
for (int i = 0; i < 8; i++)
|
uni.secondaryTexture = glGetUniformLocation(m_normalProgram, "uni_SecondaryTexture");
|
||||||
glUniform1i(uni_Light[i].Enabled, 0);
|
uni.shadowTexture = glGetUniformLocation(m_normalProgram, "uni_ShadowTexture");
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
char name[64];
|
||||||
|
sprintf(name, "uni_TextureEnabled[%d]", i);
|
||||||
|
uni.textureEnabled[i] = glGetUniformLocation(m_normalProgram, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
uni.alphaTestEnabled = glGetUniformLocation(m_normalProgram, "uni_AlphaTestEnabled");
|
||||||
|
uni.alphaReference = glGetUniformLocation(m_normalProgram, "uni_AlphaReference");
|
||||||
|
|
||||||
|
uni.fogEnabled = glGetUniformLocation(m_normalProgram, "uni_FogEnabled");
|
||||||
|
uni.fogRange = glGetUniformLocation(m_normalProgram, "uni_FogRange");
|
||||||
|
uni.fogColor = glGetUniformLocation(m_normalProgram, "uni_FogColor");
|
||||||
|
|
||||||
|
uni.shadowColor = glGetUniformLocation(m_normalProgram, "uni_ShadowColor");
|
||||||
|
uni.lightingEnabled = glGetUniformLocation(m_normalProgram, "uni_LightingEnabled");
|
||||||
|
|
||||||
|
uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_AmbientColor");
|
||||||
|
uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_DiffuseColor");
|
||||||
|
uni.specularColor = glGetUniformLocation(m_normalProgram, "uni_SpecularColor");
|
||||||
|
|
||||||
|
GLchar name[64];
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
sprintf(name, "uni_Light[%d].Enabled", i);
|
||||||
|
uni.lights[i].enabled = glGetUniformLocation(m_normalProgram, name);
|
||||||
|
|
||||||
|
sprintf(name, "uni_Light[%d].Position", i);
|
||||||
|
uni.lights[i].position = glGetUniformLocation(m_normalProgram, name);
|
||||||
|
|
||||||
|
sprintf(name, "uni_Light[%d].Ambient", i);
|
||||||
|
uni.lights[i].ambient = glGetUniformLocation(m_normalProgram, name);
|
||||||
|
|
||||||
|
sprintf(name, "uni_Light[%d].Diffuse", i);
|
||||||
|
uni.lights[i].diffuse = glGetUniformLocation(m_normalProgram, name);
|
||||||
|
|
||||||
|
sprintf(name, "uni_Light[%d].Specular", i);
|
||||||
|
uni.lights[i].specular = glGetUniformLocation(m_normalProgram, name);
|
||||||
|
|
||||||
|
sprintf(name, "uni_Light[%d].Attenuation", i);
|
||||||
|
uni.lights[i].attenuation = glGetUniformLocation(m_normalProgram, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default uniform values
|
||||||
|
Math::Matrix matrix;
|
||||||
|
matrix.LoadIdentity();
|
||||||
|
|
||||||
|
glUseProgram(m_normalProgram);
|
||||||
|
|
||||||
|
glUniformMatrix4fv(uni.projectionMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
glUniformMatrix4fv(uni.viewMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
glUniformMatrix4fv(uni.modelMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
glUniformMatrix4fv(uni.normalMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
glUniformMatrix4fv(uni.shadowMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
|
||||||
|
glUniform1i(uni.primaryTexture, 0);
|
||||||
|
glUniform1i(uni.secondaryTexture, 1);
|
||||||
|
glUniform1i(uni.shadowTexture, 2);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
glUniform1i(uni.textureEnabled[i], 0);
|
||||||
|
|
||||||
|
glUniform1i(uni.alphaTestEnabled, 0);
|
||||||
|
glUniform1f(uni.alphaReference, 0.5f);
|
||||||
|
|
||||||
|
glUniform1i(uni.fogEnabled, 0);
|
||||||
|
glUniform2f(uni.fogRange, 100.0f, 200.0f);
|
||||||
|
glUniform4f(uni.fogColor, 0.8f, 0.8f, 0.8f, 1.0f);
|
||||||
|
|
||||||
|
glUniform1f(uni.shadowColor, 0.5f);
|
||||||
|
|
||||||
|
glUniform1i(uni.lightingEnabled, 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
glUniform1i(uni.lights[i].enabled, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain uniform locations from interface rendering program and initialize them
|
||||||
|
{
|
||||||
|
UniformLocations &uni = m_uniforms[1];
|
||||||
|
|
||||||
|
uni.projectionMatrix = glGetUniformLocation(m_interfaceProgram, "uni_ProjectionMatrix");
|
||||||
|
uni.viewMatrix = glGetUniformLocation(m_interfaceProgram, "uni_ViewMatrix");
|
||||||
|
uni.modelMatrix = glGetUniformLocation(m_interfaceProgram, "uni_ModelMatrix");
|
||||||
|
|
||||||
|
uni.primaryTexture = glGetUniformLocation(m_interfaceProgram, "uni_PrimaryTexture");
|
||||||
|
|
||||||
|
uni.textureEnabled[0] = glGetUniformLocation(m_interfaceProgram, "uni_TextureEnabled");
|
||||||
|
uni.textureEnabled[1] = -1;
|
||||||
|
uni.textureEnabled[2] = -1;
|
||||||
|
|
||||||
|
// Set default uniform values
|
||||||
|
Math::Matrix matrix;
|
||||||
|
matrix.LoadIdentity();
|
||||||
|
|
||||||
|
glUseProgram(m_interfaceProgram);
|
||||||
|
|
||||||
|
glUniformMatrix4fv(uni.projectionMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
glUniformMatrix4fv(uni.viewMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
glUniformMatrix4fv(uni.modelMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
|
||||||
|
glUniform1i(uni.primaryTexture, 0);
|
||||||
|
|
||||||
|
glUniform1i(uni.textureEnabled[0], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain uniform locations from shadow rendering program and initialize them
|
||||||
|
{
|
||||||
|
UniformLocations &uni = m_uniforms[2];
|
||||||
|
|
||||||
|
uni.projectionMatrix = glGetUniformLocation(m_shadowProgram, "uni_ProjectionMatrix");
|
||||||
|
uni.viewMatrix = glGetUniformLocation(m_shadowProgram, "uni_ViewMatrix");
|
||||||
|
uni.modelMatrix = glGetUniformLocation(m_shadowProgram, "uni_ModelMatrix");
|
||||||
|
|
||||||
|
uni.primaryTexture = glGetUniformLocation(m_shadowProgram, "uni_PrimaryTexture");
|
||||||
|
|
||||||
|
uni.textureEnabled[0] = glGetUniformLocation(m_shadowProgram, "uni_TextureEnabled");
|
||||||
|
uni.textureEnabled[1] = -1;
|
||||||
|
uni.textureEnabled[2] = -1;
|
||||||
|
|
||||||
|
uni.alphaTestEnabled = glGetUniformLocation(m_shadowProgram, "uni_AlphaTestEnabled");
|
||||||
|
uni.alphaReference = glGetUniformLocation(m_shadowProgram, "uni_AlphaReference");
|
||||||
|
|
||||||
|
// Set default uniform values
|
||||||
|
Math::Matrix matrix;
|
||||||
|
matrix.LoadIdentity();
|
||||||
|
|
||||||
|
glUseProgram(m_shadowProgram);
|
||||||
|
|
||||||
|
glUniformMatrix4fv(uni.projectionMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
glUniformMatrix4fv(uni.viewMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
glUniformMatrix4fv(uni.modelMatrix, 1, GL_FALSE, matrix.Array());
|
||||||
|
|
||||||
|
glUniform1i(uni.primaryTexture, 0);
|
||||||
|
|
||||||
|
glUniform1i(uni.textureEnabled[0], 0);
|
||||||
|
|
||||||
|
glUniform1i(uni.alphaTestEnabled, 0);
|
||||||
|
glUniform1f(uni.alphaReference, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
glUseProgram(m_normalProgram);
|
||||||
glEnable(GL_VERTEX_PROGRAM_TWO_SIDE);
|
glEnable(GL_VERTEX_PROGRAM_TWO_SIDE);
|
||||||
|
|
||||||
// create default framebuffer object
|
// create default framebuffer object
|
||||||
|
@ -402,7 +533,9 @@ void CGL21Device::Destroy()
|
||||||
// Delete the remaining textures
|
// Delete the remaining textures
|
||||||
// Should not be strictly necessary, but just in case
|
// Should not be strictly necessary, but just in case
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
glDeleteProgram(m_program);
|
glDeleteProgram(m_normalProgram);
|
||||||
|
glDeleteProgram(m_interfaceProgram);
|
||||||
|
glDeleteProgram(m_shadowProgram);
|
||||||
|
|
||||||
// delete framebuffers
|
// delete framebuffers
|
||||||
for (auto& framebuffer : m_framebuffers)
|
for (auto& framebuffer : m_framebuffers)
|
||||||
|
@ -454,13 +587,39 @@ void CGL21Device::Clear()
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGL21Device::SetRenderMode(RenderMode mode)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case RENDER_MODE_NORMAL:
|
||||||
|
glUseProgram(m_normalProgram);
|
||||||
|
m_mode = 0;
|
||||||
|
break;
|
||||||
|
case RENDER_MODE_INTERFACE:
|
||||||
|
glUseProgram(m_interfaceProgram);
|
||||||
|
m_mode = 1;
|
||||||
|
break;
|
||||||
|
case RENDER_MODE_SHADOW:
|
||||||
|
glUseProgram(m_shadowProgram);
|
||||||
|
m_mode = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
glUniform1i(m_uniforms[m_mode].textureEnabled[i], m_texturesEnabled[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
|
void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
|
||||||
{
|
{
|
||||||
if (type == TRANSFORM_WORLD)
|
if (type == TRANSFORM_WORLD)
|
||||||
{
|
{
|
||||||
m_worldMat = matrix;
|
m_worldMat = matrix;
|
||||||
|
|
||||||
glUniformMatrix4fv(uni_ModelMatrix, 1, GL_FALSE, m_worldMat.Array());
|
glUniformMatrix4fv(m_uniforms[m_mode].modelMatrix, 1, GL_FALSE, m_worldMat.Array());
|
||||||
|
|
||||||
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
|
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
|
||||||
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
|
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
|
||||||
|
@ -471,7 +630,7 @@ void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
|
||||||
if (fabs(normalMat.Det()) > 1e-6)
|
if (fabs(normalMat.Det()) > 1e-6)
|
||||||
normalMat = normalMat.Inverse();
|
normalMat = normalMat.Inverse();
|
||||||
|
|
||||||
glUniformMatrix4fv(uni_NormalMatrix, 1, GL_TRUE, normalMat.Array());
|
glUniformMatrix4fv(m_uniforms[m_mode].normalMatrix, 1, GL_TRUE, normalMat.Array());
|
||||||
}
|
}
|
||||||
else if (type == TRANSFORM_VIEW)
|
else if (type == TRANSFORM_VIEW)
|
||||||
{
|
{
|
||||||
|
@ -482,7 +641,7 @@ void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
|
||||||
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
|
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
|
||||||
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
|
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
|
||||||
|
|
||||||
glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, m_viewMat.Array());
|
glUniformMatrix4fv(m_uniforms[m_mode].viewMatrix, 1, GL_FALSE, m_viewMat.Array());
|
||||||
}
|
}
|
||||||
else if (type == TRANSFORM_PROJECTION)
|
else if (type == TRANSFORM_PROJECTION)
|
||||||
{
|
{
|
||||||
|
@ -490,12 +649,12 @@ void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
|
||||||
|
|
||||||
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
|
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
|
||||||
|
|
||||||
glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, m_projectionMat.Array());
|
glUniformMatrix4fv(m_uniforms[m_mode].projectionMatrix, 1, GL_FALSE, m_projectionMat.Array());
|
||||||
}
|
}
|
||||||
else if (type == TRANSFORM_SHADOW)
|
else if (type == TRANSFORM_SHADOW)
|
||||||
{
|
{
|
||||||
Math::Matrix temp = matrix;
|
Math::Matrix temp = matrix;
|
||||||
glUniformMatrix4fv(uni_ShadowMatrix, 1, GL_FALSE, temp.Array());
|
glUniformMatrix4fv(m_uniforms[m_mode].shadowMatrix, 1, GL_FALSE, temp.Array());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -507,9 +666,9 @@ void CGL21Device::SetMaterial(const Material &material)
|
||||||
{
|
{
|
||||||
m_material = material;
|
m_material = material;
|
||||||
|
|
||||||
glUniform4fv(uni_AmbientColor, 1, m_material.ambient.Array());
|
glUniform4fv(m_uniforms[m_mode].ambientColor, 1, m_material.ambient.Array());
|
||||||
glUniform4fv(uni_DiffuseColor, 1, m_material.diffuse.Array());
|
glUniform4fv(m_uniforms[m_mode].diffuseColor, 1, m_material.diffuse.Array());
|
||||||
glUniform4fv(uni_SpecularColor, 1, m_material.specular.Array());
|
glUniform4fv(m_uniforms[m_mode].specularColor, 1, m_material.specular.Array());
|
||||||
}
|
}
|
||||||
|
|
||||||
int CGL21Device::GetMaxLightCount()
|
int CGL21Device::GetMaxLightCount()
|
||||||
|
@ -524,18 +683,20 @@ void CGL21Device::SetLight(int index, const Light &light)
|
||||||
|
|
||||||
m_lights[index] = light;
|
m_lights[index] = light;
|
||||||
|
|
||||||
glUniform4fv(uni_Light[index].Ambient, 1, light.ambient.Array());
|
UniformLocations::LightLocations &loc = m_uniforms[m_mode].lights[index];
|
||||||
glUniform4fv(uni_Light[index].Diffuse, 1, light.diffuse.Array());
|
|
||||||
glUniform4fv(uni_Light[index].Specular, 1, light.specular.Array());
|
glUniform4fv(loc.ambient, 1, light.ambient.Array());
|
||||||
glUniform3f(uni_Light[index].Attenuation, light.attenuation0, light.attenuation1, light.attenuation2);
|
glUniform4fv(loc.diffuse, 1, light.diffuse.Array());
|
||||||
|
glUniform4fv(loc.specular, 1, light.specular.Array());
|
||||||
|
glUniform3f(loc.attenuation, light.attenuation0, light.attenuation1, light.attenuation2);
|
||||||
|
|
||||||
if (light.type == LIGHT_DIRECTIONAL)
|
if (light.type == LIGHT_DIRECTIONAL)
|
||||||
{
|
{
|
||||||
glUniform4f(uni_Light[index].Position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
|
glUniform4f(loc.position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glUniform4f(uni_Light[index].Position, light.position.x, light.position.y, light.position.z, 1.0f);
|
glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add spotlight params
|
// TODO: add spotlight params
|
||||||
|
@ -548,7 +709,7 @@ void CGL21Device::SetLightEnabled(int index, bool enabled)
|
||||||
|
|
||||||
m_lightsEnabled[index] = enabled;
|
m_lightsEnabled[index] = enabled;
|
||||||
|
|
||||||
glUniform1i(uni_Light[index].Enabled, enabled ? 1 : 0);
|
glUniform1i(m_uniforms[m_mode].lights[index].enabled, enabled ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If image is invalid, returns invalid texture.
|
/** If image is invalid, returns invalid texture.
|
||||||
|
@ -899,7 +1060,7 @@ void CGL21Device::UpdateTextureStatus()
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
bool enabled = m_texturesEnabled[i] && (m_currentTextures[i].id != 0);
|
bool enabled = m_texturesEnabled[i] && (m_currentTextures[i].id != 0);
|
||||||
glUniform1i(uni_TextureEnabled[i], enabled ? 1 : 0);
|
glUniform1i(m_uniforms[m_mode].textureEnabled[i], enabled ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1639,19 +1800,19 @@ void CGL21Device::SetRenderState(RenderState state, bool enabled)
|
||||||
{
|
{
|
||||||
m_lighting = enabled;
|
m_lighting = enabled;
|
||||||
|
|
||||||
glUniform1i(uni_LightingEnabled, enabled ? 1 : 0);
|
glUniform1i(m_uniforms[m_mode].lightingEnabled, enabled ? 1 : 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (state == RENDER_STATE_ALPHA_TEST)
|
else if (state == RENDER_STATE_ALPHA_TEST)
|
||||||
{
|
{
|
||||||
glUniform1i(uni_AlphaTestEnabled, enabled ? 1 : 0);
|
glUniform1i(m_uniforms[m_mode].alphaTestEnabled, enabled ? 1 : 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (state == RENDER_STATE_FOG)
|
else if (state == RENDER_STATE_FOG)
|
||||||
{
|
{
|
||||||
glUniform1i(uni_FogEnabled, enabled ? 1 : 0);
|
glUniform1i(m_uniforms[m_mode].fogEnabled, enabled ? 1 : 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1691,7 +1852,7 @@ void CGL21Device::SetDepthBias(float factor, float units)
|
||||||
|
|
||||||
void CGL21Device::SetAlphaTestFunc(CompFunc func, float refValue)
|
void CGL21Device::SetAlphaTestFunc(CompFunc func, float refValue)
|
||||||
{
|
{
|
||||||
glUniform1i(uni_AlphaReference, refValue);
|
glUniform1i(m_uniforms[m_mode].alphaReference, refValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL21Device::SetBlendFunc(BlendFunc srcBlend, BlendFunc dstBlend)
|
void CGL21Device::SetBlendFunc(BlendFunc srcBlend, BlendFunc dstBlend)
|
||||||
|
@ -1711,8 +1872,8 @@ void CGL21Device::SetGlobalAmbient(const Color &color)
|
||||||
|
|
||||||
void CGL21Device::SetFogParams(FogMode mode, const Color &color, float start, float end, float density)
|
void CGL21Device::SetFogParams(FogMode mode, const Color &color, float start, float end, float density)
|
||||||
{
|
{
|
||||||
glUniform2f(uni_FogRange, start, end);
|
glUniform2f(m_uniforms[m_mode].fogRange, start, end);
|
||||||
glUniform4f(uni_FogColor, color.r, color.g, color.b, color.a);
|
glUniform4f(m_uniforms[m_mode].fogColor, color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (mode == FOG_LINEAR) glFogi(GL_FOG_MODE, GL_LINEAR);
|
if (mode == FOG_LINEAR) glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||||
|
@ -1745,7 +1906,7 @@ void CGL21Device::SetShadeModel(ShadeModel model)
|
||||||
|
|
||||||
void CGL21Device::SetShadowColor(float value)
|
void CGL21Device::SetShadowColor(float value)
|
||||||
{
|
{
|
||||||
glUniform1f(uni_ShadowColor, value);
|
glUniform1f(m_uniforms[m_mode].shadowColor, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL21Device::SetFillMode(FillMode mode)
|
void CGL21Device::SetFillMode(FillMode mode)
|
||||||
|
|
|
@ -42,6 +42,74 @@
|
||||||
namespace Gfx
|
namespace Gfx
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct UniformLocations
|
||||||
|
{
|
||||||
|
// Uniforms
|
||||||
|
//! Projection matrix
|
||||||
|
GLint projectionMatrix = -1;
|
||||||
|
//! View matrix
|
||||||
|
GLint viewMatrix = -1;
|
||||||
|
//! Model matrix
|
||||||
|
GLint modelMatrix = -1;
|
||||||
|
//! Shadow matrix
|
||||||
|
GLint shadowMatrix = -1;
|
||||||
|
//! Normal matrix
|
||||||
|
GLint normalMatrix = -1;
|
||||||
|
|
||||||
|
//! Primary texture sampler
|
||||||
|
GLint primaryTexture = -1;
|
||||||
|
//! Secondary texture sampler
|
||||||
|
GLint secondaryTexture = -1;
|
||||||
|
//! Shadow texture sampler
|
||||||
|
GLint shadowTexture = -1;
|
||||||
|
|
||||||
|
//! true enables texture
|
||||||
|
GLint textureEnabled[3] = {};
|
||||||
|
|
||||||
|
// Alpha test parameters
|
||||||
|
//! true enables alpha test
|
||||||
|
GLint alphaTestEnabled = -1;
|
||||||
|
//! Alpha test reference value
|
||||||
|
GLint alphaReference = -1;
|
||||||
|
|
||||||
|
//! true enables fog
|
||||||
|
GLint fogEnabled = -1;
|
||||||
|
//! Fog range
|
||||||
|
GLint fogRange = -1;
|
||||||
|
//! Fog color
|
||||||
|
GLint fogColor = -1;
|
||||||
|
|
||||||
|
//! Shadow color
|
||||||
|
GLint shadowColor = -1;
|
||||||
|
|
||||||
|
//! true enables lighting
|
||||||
|
GLint lightingEnabled = -1;
|
||||||
|
//! Ambient color
|
||||||
|
GLint ambientColor = -1;
|
||||||
|
//! Diffuse color
|
||||||
|
GLint diffuseColor = -1;
|
||||||
|
//! Specular color
|
||||||
|
GLint specularColor = -1;
|
||||||
|
|
||||||
|
struct LightLocations
|
||||||
|
{
|
||||||
|
//! true enables light
|
||||||
|
GLint enabled = -1;
|
||||||
|
//! Light type
|
||||||
|
GLint type = -1;
|
||||||
|
//! Position or direction vector
|
||||||
|
GLint position = -1;
|
||||||
|
//! Ambient color
|
||||||
|
GLint ambient = -1;
|
||||||
|
//! Diffuse color
|
||||||
|
GLint diffuse = -1;
|
||||||
|
//! Specular color
|
||||||
|
GLint specular = -1;
|
||||||
|
//! Attenuation
|
||||||
|
GLint attenuation = -1;
|
||||||
|
} lights[8];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\class CGL21Device
|
\class CGL21Device
|
||||||
\brief Implementation of CDevice interface in OpenGL
|
\brief Implementation of CDevice interface in OpenGL
|
||||||
|
@ -72,6 +140,8 @@ public:
|
||||||
|
|
||||||
void Clear() override;
|
void Clear() override;
|
||||||
|
|
||||||
|
void SetRenderMode(RenderMode mode) override;
|
||||||
|
|
||||||
void SetTransform(TransformType type, const Math::Matrix &matrix) override;
|
void SetTransform(TransformType type, const Math::Matrix &matrix) override;
|
||||||
|
|
||||||
void SetMaterial(const Material &material) override;
|
void SetMaterial(const Material &material) override;
|
||||||
|
@ -254,75 +324,17 @@ private:
|
||||||
//! true enables per-pixel lighting
|
//! true enables per-pixel lighting
|
||||||
bool m_perPixelLighting = false;
|
bool m_perPixelLighting = false;
|
||||||
|
|
||||||
//! Shader program
|
//! Shader program for normal rendering
|
||||||
GLuint m_program = 0;
|
GLuint m_normalProgram = 0;
|
||||||
|
//! Shader program for interface rendering
|
||||||
|
GLuint m_interfaceProgram = 0;
|
||||||
|
//! Shader program for shadow rendering
|
||||||
|
GLuint m_shadowProgram = 0;
|
||||||
|
|
||||||
// Uniforms
|
//! Uniform locations
|
||||||
//! Projection matrix
|
UniformLocations m_uniforms[3];
|
||||||
GLint uni_ProjectionMatrix = 0;
|
//! Current mode
|
||||||
//! View matrix
|
int m_mode = 0;
|
||||||
GLint uni_ViewMatrix = 0;
|
|
||||||
//! Model matrix
|
|
||||||
GLint uni_ModelMatrix = 0;
|
|
||||||
//! Shadow matrix
|
|
||||||
GLint uni_ShadowMatrix = 0;
|
|
||||||
//! Normal matrix
|
|
||||||
GLint uni_NormalMatrix = 0;
|
|
||||||
|
|
||||||
//! Primary texture sampler
|
|
||||||
GLint uni_PrimaryTexture = 0;
|
|
||||||
//! Secondary texture sampler
|
|
||||||
GLint uni_SecondaryTexture = 0;
|
|
||||||
//! Shadow texture sampler
|
|
||||||
GLint uni_ShadowTexture = 0;
|
|
||||||
|
|
||||||
//! true enables texture
|
|
||||||
GLint uni_TextureEnabled[3] = {};
|
|
||||||
|
|
||||||
// Alpha test parameters
|
|
||||||
//! true enables alpha test
|
|
||||||
GLint uni_AlphaTestEnabled = 0;
|
|
||||||
//! Alpha test reference value
|
|
||||||
GLint uni_AlphaReference = 0;
|
|
||||||
|
|
||||||
//! true enables fog
|
|
||||||
GLint uni_FogEnabled = 0;
|
|
||||||
//! Fog range
|
|
||||||
GLint uni_FogRange = 0;
|
|
||||||
//! Fog color
|
|
||||||
GLint uni_FogColor = 0;
|
|
||||||
|
|
||||||
//! Shadow color
|
|
||||||
GLint uni_ShadowColor = 0;
|
|
||||||
|
|
||||||
//! true enables lighting
|
|
||||||
GLint uni_LightingEnabled = 0;
|
|
||||||
//! Ambient color
|
|
||||||
GLint uni_AmbientColor = 0;
|
|
||||||
//! Diffuse color
|
|
||||||
GLint uni_DiffuseColor = 0;
|
|
||||||
//! Specular color
|
|
||||||
GLint uni_SpecularColor = 0;
|
|
||||||
|
|
||||||
struct LightUniforms
|
|
||||||
{
|
|
||||||
//! true enables light
|
|
||||||
GLint Enabled = 0;
|
|
||||||
//! Light type
|
|
||||||
GLint Type = 0;
|
|
||||||
//! Position or direction vector
|
|
||||||
GLint Position = 0;
|
|
||||||
//! Ambient color
|
|
||||||
GLint Ambient = 0;
|
|
||||||
//! Diffuse color
|
|
||||||
GLint Diffuse = 0;
|
|
||||||
//! Specular color
|
|
||||||
GLint Specular = 0;
|
|
||||||
//! Attenuation
|
|
||||||
GLint Attenuation = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
LightUniforms uni_Light[8];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -479,6 +479,11 @@ void CGL33Device::Clear()
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGL33Device::SetRenderMode(RenderMode mode)
|
||||||
|
{
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
|
void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
|
||||||
{
|
{
|
||||||
if (type == TRANSFORM_WORLD)
|
if (type == TRANSFORM_WORLD)
|
||||||
|
|
|
@ -84,6 +84,8 @@ public:
|
||||||
|
|
||||||
void Clear() override;
|
void Clear() override;
|
||||||
|
|
||||||
|
void SetRenderMode(RenderMode mode) override;
|
||||||
|
|
||||||
void SetTransform(TransformType type, const Math::Matrix &matrix) override;
|
void SetTransform(TransformType type, const Math::Matrix &matrix) override;
|
||||||
|
|
||||||
void SetMaterial(const Material &material) override;
|
void SetMaterial(const Material &material) override;
|
||||||
|
|
|
@ -386,6 +386,11 @@ void CGLDevice::Clear()
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGLDevice::SetRenderMode(RenderMode mode)
|
||||||
|
{
|
||||||
|
// nothing is done
|
||||||
|
}
|
||||||
|
|
||||||
void CGLDevice::SetTransform(TransformType type, const Math::Matrix &matrix)
|
void CGLDevice::SetTransform(TransformType type, const Math::Matrix &matrix)
|
||||||
{
|
{
|
||||||
if (type == TRANSFORM_WORLD)
|
if (type == TRANSFORM_WORLD)
|
||||||
|
|
|
@ -91,6 +91,8 @@ public:
|
||||||
|
|
||||||
void Clear() override;
|
void Clear() override;
|
||||||
|
|
||||||
|
void SetRenderMode(RenderMode mode) override;
|
||||||
|
|
||||||
void SetTransform(TransformType type, const Math::Matrix &matrix) override;
|
void SetTransform(TransformType type, const Math::Matrix &matrix) override;
|
||||||
|
|
||||||
void SetMaterial(const Material &material) override;
|
void SetMaterial(const Material &material) override;
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Colobot: Gold Edition source code
|
||||||
|
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||||
|
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see http://gnu.org/licenses
|
||||||
|
*/
|
||||||
|
// FRAGMENT SHADER - INTERFACE MODE
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform sampler2D uni_PrimaryTexture;
|
||||||
|
|
||||||
|
uniform bool uni_TextureEnabled;
|
||||||
|
|
||||||
|
varying vec4 pass_Color;
|
||||||
|
varying vec2 pass_TexCoord0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
if (uni_TextureEnabled)
|
||||||
|
{
|
||||||
|
gl_FragColor = pass_Color * texture2D(uni_PrimaryTexture, pass_TexCoord0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gl_FragColor = pass_Color;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Colobot: Gold Edition source code
|
||||||
|
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||||
|
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see http://gnu.org/licenses
|
||||||
|
*/
|
||||||
|
// FRAGMENT SHADER - SHADOW MODE
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform sampler2D uni_PrimaryTexture;
|
||||||
|
|
||||||
|
uniform bool uni_TextureEnabled;
|
||||||
|
|
||||||
|
uniform bool uni_AlphaTestEnabled;
|
||||||
|
uniform float uni_AlphaReference;
|
||||||
|
|
||||||
|
varying vec2 pass_TexCoord0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 color = vec4(1.0f);
|
||||||
|
|
||||||
|
if (uni_TextureEnabled)
|
||||||
|
{
|
||||||
|
color = color * texture2D(uni_PrimaryTexture, pass_TexCoord0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uni_AlphaTestEnabled)
|
||||||
|
{
|
||||||
|
if(color.a < uni_AlphaReference)
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = vec4(1.0f);
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Colobot: Gold Edition source code
|
||||||
|
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||||
|
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see http://gnu.org/licenses
|
||||||
|
*/
|
||||||
|
// VERTEX SHADER - INTERFACE MODE
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 uni_ProjectionMatrix;
|
||||||
|
uniform mat4 uni_ViewMatrix;
|
||||||
|
uniform mat4 uni_ModelMatrix;
|
||||||
|
|
||||||
|
varying vec4 pass_Color;
|
||||||
|
varying vec2 pass_TexCoord0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = uni_ProjectionMatrix * uni_ViewMatrix * uni_ModelMatrix * gl_Vertex;
|
||||||
|
|
||||||
|
pass_Color = gl_Color;
|
||||||
|
pass_TexCoord0 = gl_MultiTexCoord0.st;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Colobot: Gold Edition source code
|
||||||
|
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||||
|
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see http://gnu.org/licenses
|
||||||
|
*/
|
||||||
|
// VERTEX SHADER - SHADOW MODE
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 uni_ProjectionMatrix;
|
||||||
|
uniform mat4 uni_ViewMatrix;
|
||||||
|
uniform mat4 uni_ModelMatrix;
|
||||||
|
|
||||||
|
varying vec2 pass_TexCoord0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = uni_ProjectionMatrix * uni_ViewMatrix * uni_ModelMatrix * gl_Vertex;
|
||||||
|
|
||||||
|
pass_TexCoord0 = gl_MultiTexCoord0.st;
|
||||||
|
}
|
Loading…
Reference in New Issue