Changes in framebuffer creation, framebuffer error detection and small other graphical things

dev-time-step
Tomasz Kapuściński 2016-02-29 16:42:01 +01:00
parent 0bb5f96d7a
commit 78e877d9a8
15 changed files with 210 additions and 57 deletions

View File

@ -32,8 +32,9 @@ CDefaultFramebuffer::CDefaultFramebuffer(const FramebufferParams& params)
{
}
void CDefaultFramebuffer::Create()
bool CDefaultFramebuffer::Create()
{
return true;
}
void CDefaultFramebuffer::Destroy()

View File

@ -70,7 +70,7 @@ public:
virtual ~CFramebuffer() {}
//! Creates this framebuffer
virtual void Create() = 0;
virtual bool Create() = 0;
//! Destroys this framebuffer
virtual void Destroy() = 0;
@ -122,7 +122,7 @@ public:
explicit CDefaultFramebuffer(const FramebufferParams &params);
//! Creates default framebuffer
void Create() override;
bool Create() override;
//! Destroys default framebuffer
void Destroy() override;

View File

@ -3392,7 +3392,7 @@ void CEngine::RenderShadowMap()
CFramebuffer *framebuffer = m_device->CreateFramebuffer("shadow", params);
if (framebuffer == nullptr)
{
GetLogger()->Error("Could not create framebuffer, disabling shadows\n");
GetLogger()->Error("Could not create shadow mapping framebuffer, disabling dynamic shadows\n");
m_shadowMapping = false;
m_offscreenShadowRendering = false;
m_qualityShadows = false;
@ -3722,6 +3722,12 @@ void CEngine::UseMSAA(bool enable)
params.samples = m_multisample;
framebuffer = m_device->CreateFramebuffer("multisample", params);
if (framebuffer == nullptr)
{
GetLogger()->Error("Could not create MSAA framebuffer, disabling MSAA\n");
m_multisample = 1;
}
}
framebuffer->Bind();
@ -4518,8 +4524,6 @@ void CEngine::DrawPlanet()
if (! m_planet->PlanetExist())
return;
m_device->SetRenderMode(RENDER_MODE_INTERFACE);
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
m_device->SetRenderState(RENDER_STATE_FOG, false);
@ -4529,8 +4533,6 @@ void CEngine::DrawPlanet()
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
m_planet->Draw(); // draws the planets
m_device->SetRenderMode(RENDER_MODE_NORMAL);
}
void CEngine::DrawForegroundImage()

View File

@ -392,9 +392,9 @@ bool CGL21Device::Create()
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");
uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_Material.ambient");
uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_Material.diffuse");
uni.specularColor = glGetUniformLocation(m_normalProgram, "uni_Material.specular");
GLchar name[64];
for (int i = 0; i < 8; i++)
@ -402,6 +402,9 @@ bool CGL21Device::Create()
sprintf(name, "uni_Light[%d].Enabled", i);
uni.lights[i].enabled = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].Type", i);
uni.lights[i].type = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].Position", i);
uni.lights[i].position = glGetUniformLocation(m_normalProgram, name);
@ -416,6 +419,15 @@ bool CGL21Device::Create()
sprintf(name, "uni_Light[%d].Attenuation", i);
uni.lights[i].attenuation = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].SpotDirection", i);
uni.lights[i].spotDirection = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].Exponent", i);
uni.lights[i].spotExponent = glGetUniformLocation(m_normalProgram, name);
sprintf(name, "uni_Light[%d].SpotCutoff", i);
uni.lights[i].spotCutoff = glGetUniformLocation(m_normalProgram, name);
}
// Set default uniform values
@ -697,14 +709,27 @@ void CGL21Device::SetLight(int index, const Light &light)
if (light.type == LIGHT_DIRECTIONAL)
{
glUniform1i(loc.type, 1);
glUniform4f(loc.position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
}
else
else if (light.type == LIGHT_POINT)
{
glUniform1i(loc.type, 2);
glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f);
}
// TODO: add spotlight params
glUniform3f(loc.spotDirection, 0.0f, 1.0f, 0.0f);
glUniform1f(loc.spotCutoff, -1.0f);
glUniform1f(loc.spotExponent, 1.0f);
}
else if (light.type == LIGHT_SPOT)
{
glUniform1i(loc.type, 3);
glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f);
glUniform3f(loc.spotDirection, -light.direction.x, -light.direction.y, -light.direction.z);
glUniform1f(loc.spotCutoff, std::cosf(light.spotAngle));
glUniform1f(loc.spotExponent, light.spotIntensity);
}
}
void CGL21Device::SetLightEnabled(int index, bool enabled)
@ -1967,7 +1992,7 @@ CFramebuffer* CGL21Device::CreateFramebuffer(std::string name, const Framebuffer
else
return nullptr;
framebuffer->Create();
if (!framebuffer->Create()) return nullptr;
CFramebuffer* framebufferPtr = framebuffer.get();
m_framebuffers[name] = std::move(framebuffer);

View File

@ -645,7 +645,7 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
glUniformMatrix4fv(m_uni->modelMatrix, 1, GL_FALSE, m_worldMat.Array());
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
m_combinedMatrixOutdated = true;
// normal transform
Math::Matrix normalMat = matrix;
@ -662,15 +662,14 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
m_viewMat = Math::MultiplyMatrices(scale, matrix);
m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
m_combinedMatrixOutdated = true;
glUniformMatrix4fv(m_uni->viewMatrix, 1, GL_FALSE, m_viewMat.Array());
}
else if (type == TRANSFORM_PROJECTION)
{
m_projectionMat = matrix;
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
m_combinedMatrixOutdated = true;
glUniformMatrix4fv(m_uni->projectionMatrix, 1, GL_FALSE, m_projectionMat.Array());
}
@ -1992,6 +1991,12 @@ void CGL33Device::DestroyStaticBuffer(unsigned int bufferId)
int CGL33Device::ComputeSphereVisibility(const Math::Vector &center, float radius)
{
if (m_combinedMatrixOutdated)
{
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
m_combinedMatrixOutdated = false;
}
Math::Matrix &m = m_combinedMatrix;
Math::Vector vec[6];
@ -2231,7 +2236,7 @@ CFramebuffer* CGL33Device::CreateFramebuffer(std::string name, const Framebuffer
}
auto framebuffer = MakeUnique<CGLFramebuffer>(params);
framebuffer->Create();
if (!framebuffer->Create()) return nullptr;
CFramebuffer* framebufferPtr = framebuffer.get();
m_framebuffers[name] = std::move(framebuffer);

View File

@ -205,6 +205,8 @@ private:
Math::Matrix m_projectionMat;
//! Combined world-view-projection matrix
Math::Matrix m_combinedMatrix;
//! true means combined matrix is outdated
bool m_combinedMatrixOutdated = true;
//! The current material
Material m_material;

View File

@ -169,7 +169,7 @@ bool CGLDevice::Create()
}
// Extract OpenGL version
int glMajor, glMinor;
int glMajor = 1, glMinor = 1;
int glVersion = GetOpenGLVersion(glMajor, glMinor);
if (glVersion < 13)
@ -402,14 +402,14 @@ void CGLDevice::SetTransform(TransformType type, const Math::Matrix &matrix)
m_worldMat = matrix;
UpdateModelviewMatrix();
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
m_combinedMatrixOutdated = true;
}
else if (type == TRANSFORM_VIEW)
{
m_viewMat = matrix;
UpdateModelviewMatrix();
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
m_combinedMatrixOutdated = true;
}
else if (type == TRANSFORM_PROJECTION)
{
@ -417,7 +417,7 @@ void CGLDevice::SetTransform(TransformType type, const Math::Matrix &matrix)
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(m_projectionMat.Array());
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
m_combinedMatrixOutdated = true;
}
else if (type == TRANSFORM_SHADOW)
{
@ -1824,6 +1824,12 @@ void CGLDevice::DestroyStaticBuffer(unsigned int bufferId)
int CGLDevice::ComputeSphereVisibility(const Math::Vector &center, float radius)
{
if (m_combinedMatrixOutdated)
{
m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
m_combinedMatrixOutdated = false;
}
Math::Matrix &m = m_combinedMatrix;
Math::Vector vec[6];
@ -2066,7 +2072,7 @@ CFramebuffer* CGLDevice::CreateFramebuffer(std::string name, const FramebufferPa
else
return nullptr;
framebuffer->Create();
if (!framebuffer->Create()) return nullptr;
CFramebuffer* framebufferPtr = framebuffer.get();
m_framebuffers[name] = std::move(framebuffer);

View File

@ -216,6 +216,8 @@ private:
Math::Matrix m_projectionMat;
//! Combined world-view-projection matrix
Math::Matrix m_combinedMatrix;
//! true means that combined matrix is outdated
bool m_combinedMatrixOutdated = true;
//! The current material
Material m_material;

View File

@ -42,9 +42,9 @@ CGLFramebuffer::CGLFramebuffer(const FramebufferParams& params)
m_samples = 0;
}
void CGLFramebuffer::Create()
bool CGLFramebuffer::Create()
{
if (m_fbo != 0) return;
if (m_fbo != 0) return false;
m_width = m_params.width;
m_height = m_params.height;
@ -145,11 +145,37 @@ void CGLFramebuffer::Create()
GLuint result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (result != GL_FRAMEBUFFER_COMPLETE)
{
GetLogger()->Error("Framebuffer incomplete\n");
assert(false);
GetLogger()->Error("Framebuffer incomplete: ");
switch (result)
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
GetLogger()->Error("attachment point incomplete");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
GetLogger()->Error("missing attachment");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
GetLogger()->Error("draw buffer has missing color attachments");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
GetLogger()->Error("read buffer has missing color attachments");
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
GetLogger()->Error("unsupported attachment format");
break;
}
GetLogger()->Error("\n");
Destroy();
glBindFramebuffer(GL_FRAMEBUFFER, m_currentFBO);
return false;
}
glBindFramebuffer(GL_FRAMEBUFFER, m_currentFBO);
return true;
}
void CGLFramebuffer::Destroy()
@ -274,9 +300,9 @@ CGLFramebufferEXT::CGLFramebufferEXT(const FramebufferParams& params)
m_samples = 0;
}
void CGLFramebufferEXT::Create()
bool CGLFramebufferEXT::Create()
{
if (m_fbo != 0) return;
if (m_fbo != 0) return false;
m_width = m_params.width;
m_height = m_params.height;
@ -362,7 +388,7 @@ void CGLFramebufferEXT::Create()
else
{
glGenRenderbuffersEXT(1, &m_depthRenderbuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER, m_depthRenderbuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthRenderbuffer);
if (m_params.samples > 1)
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_params.samples, depthFormat, m_params.width, m_params.height);
@ -377,11 +403,38 @@ void CGLFramebufferEXT::Create()
GLuint result = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (result != GL_FRAMEBUFFER_COMPLETE_EXT)
{
GetLogger()->Error("Framebuffer incomplete: %d\n", result);
assert(false);
GetLogger()->Error("Framebuffer incomplete: ");
switch (result)
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
GetLogger()->Error("attachment point incomplete");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
GetLogger()->Error("missing attachment");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
GetLogger()->Error("incompatible attachment dimensions");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
GetLogger()->Error("draw buffer has missing color attachments");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
GetLogger()->Error("read buffer has missing color attachments");
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
GetLogger()->Error("unsupported attachment format");
break;
}
Destroy();
glBindFramebuffer(GL_FRAMEBUFFER, m_currentFBO);
return false;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_currentFBO);
return true;
}
void CGLFramebufferEXT::Destroy()

View File

@ -51,7 +51,7 @@ protected:
public:
CGLFramebuffer(const FramebufferParams& params);
void Create() override;
bool Create() override;
void Destroy() override;
@ -101,7 +101,7 @@ protected:
public:
CGLFramebufferEXT(const FramebufferParams& params);
void Create() override;
bool Create() override;
void Destroy() override;

View File

@ -292,6 +292,23 @@ std::string GetHardwareInfo(bool full)
return result.str();
}
bool CheckGLErrors()
{
GLint error = glGetError();
bool result = false;
while (error != GL_NO_ERROR)
{
GetLogger()->Error("OpenGL error: %d\n", error);
result = true;
error = glGetError();
}
return result;
}
GLenum TranslateGfxPrimitive(PrimitiveType type)
{
GLenum flag = 0;

View File

@ -68,6 +68,9 @@ bool AreExtensionsSupported(std::string list);
//! Returns information about graphics card
std::string GetHardwareInfo(bool full = false);
//! Checks for OpenGL errors
bool CheckGLErrors();
//! Translate Gfx primitive type to OpenGL primitive type
GLenum TranslateGfxPrimitive(PrimitiveType type);
@ -125,6 +128,12 @@ struct LightLocations
GLint specular = -1;
//! Attenuation
GLint attenuation = -1;
//! Spot light direction
GLint spotDirection = -1;
//! Spot light exponent
GLint spotExponent = -1;
//! Spot light cutoff
GLint spotCutoff = -1;
};
struct UniformLocations

View File

@ -37,12 +37,16 @@ uniform float uni_ShadowColor;
struct LightParams
{
bool Enabled;
int Type;
vec4 Position;
vec4 Ambient;
vec4 Diffuse;
vec4 Specular;
float Shininess;
vec3 Attenuation;
vec3 SpotDirection;
float SpotCutoff;
float SpotExponent;
};
uniform vec4 uni_AmbientColor;

View File

@ -80,12 +80,12 @@ void main()
vec4 diffuse = vec4(0.0f);
vec4 specular = vec4(0.0f);
vec3 normal = (gl_FrontFacing ? data.Normal : -data.Normal);
for(int i=0; i<8; i++)
{
if(uni_Light[i].Enabled)
{
vec3 normal = (gl_FrontFacing ? data.Normal : -data.Normal);
vec3 lightDirection = vec3(0.0f);
float atten;

View File

@ -28,17 +28,26 @@ uniform mat4 uni_NormalMatrix;
struct LightParams
{
bool Enabled;
int Type;
vec4 Position;
vec4 Ambient;
vec4 Diffuse;
vec4 Specular;
float Shininess;
vec3 Attenuation;
vec3 SpotDirection;
float SpotCutoff;
float SpotExponent;
};
uniform vec4 uni_AmbientColor;
uniform vec4 uni_DiffuseColor;
uniform vec4 uni_SpecularColor;
struct Material
{
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
uniform Material uni_Material;
uniform bool uni_LightingEnabled;
uniform LightParams uni_Light[8];
@ -70,35 +79,53 @@ void main()
{
if (uni_Light[i].Enabled)
{
vec3 lightDirection = uni_Light[i].Position.xyz;
LightParams light = uni_Light[i];
vec3 lightDirection = light.Position.xyz;
float atten = 1.0f;
// Point light
if (abs(uni_Light[i].Position.w) > 1e-3f)
if (light.Position.w != 0.0f)
{
vec3 lightDirection = normalize(uni_Light[i].Position.xyz - position.xyz);
float dist = distance(uni_Light[i].Position.xyz, position.xyz);
float dist = distance(light.Position.xyz, position.xyz);
vec3 lightAtten = uni_Light[i].Attenuation;
float atten = 1.0f / (light.Attenuation.x
+ light.Attenuation.y * dist
+ light.Attenuation.z * dist * dist);
atten = 1.0f / (lightAtten.x
+ lightAtten.y * dist
+ lightAtten.z * dist * dist);
lightDirection = normalize(light.Position.xyz - position.xyz);
}
float spot = 1.0f;
if (light.SpotCutoff > 0.0f)
{
float cone = dot(light.SpotDirection, lightDirection);
if (cone > light.SpotCutoff)
{
spot = pow(cone, light.SpotExponent);
}
else
{
spot = 0.0f;
}
}
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;
float component = atten * spot;
float diffuseComponent = clamp(dot(normal, lightDirection), 0.0f, 1.0f);
float specularComponent = clamp(pow(dot(normal, lightDirection + reflectDirection), light.Shininess), 0.0f, 1.0f);
ambient += component * light.Ambient * uni_Material.ambient;
diffuse += component * diffuseComponent * light.Diffuse * uni_Material.diffuse;
specular += component * specularComponent * light.Specular * uni_Material.specular;
}
}
vec4 result = uni_AmbientColor * ambient
+ uni_DiffuseColor * diffuse
+ uni_SpecularColor * specular;
vec4 result = ambient + diffuse + specular;
color = vec4(min(vec3(1.0f), result.rgb), 1.0f);
color = clamp(vec4(result.rgb, uni_Material.diffuse), 0.0f, 1.0f);
}
gl_Position = uni_ProjectionMatrix * eyeSpace;