From d9c5a439d09211ec210195709d275596c6c3c9ba Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 1 Jul 2012 22:59:22 +0200 Subject: CGLDevice implementation - extended Gfx::CDevice interface - written OpenGL implementation in Gfx::CGLDevice - rewrote color and light module - added Gfx::VertexCol - added array casts to Math::Vector, Math::Matrix and Gfx::Color --- src/graphics/opengl/gldevice.cpp | 567 +++++++++++++++++++++++++++++++++++---- 1 file changed, 519 insertions(+), 48 deletions(-) (limited to 'src/graphics/opengl/gldevice.cpp') diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 9ef376f..d105a93 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -20,6 +20,35 @@ #include #include +#include + +#include + +#include + +namespace Gfx { + +struct GLDevicePrivate +{ + void (APIENTRY* glMultiTexCoord1fARB)(GLenum target, GLfloat s); + void (APIENTRY* glMultiTexCoord2fARB)(GLenum target, GLfloat s, GLfloat t); + void (APIENTRY* glMultiTexCoord3fARB)(GLenum target, GLfloat s, GLfloat t, GLfloat r); + void (APIENTRY* glMultiTexCoord4fARB)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); + void (APIENTRY* glActiveTextureARB)(GLenum texture); + void (APIENTRY* glClientActiveTextureARB)(GLenum texture); + + GLDevicePrivate() + { + glMultiTexCoord1fARB = NULL; + glMultiTexCoord2fARB = NULL; + glMultiTexCoord3fARB = NULL; + glMultiTexCoord4fARB = NULL; + glActiveTextureARB = NULL; + glClientActiveTextureARB = NULL; + } +}; + +}; // namespace Gfx void Gfx::GLDeviceConfig::LoadDefault() @@ -35,89 +64,194 @@ void Gfx::GLDeviceConfig::LoadDefault() depthSize = 24; } + + + Gfx::CGLDevice::CGLDevice() { - m_renderState = 0; + m_private = new Gfx::GLDevicePrivate(); + m_wasInit = false; } Gfx::CGLDevice::~CGLDevice() { + delete m_private; + m_private = NULL; } -void Gfx::CGLDevice::Initialize() +bool Gfx::CGLDevice::GetWasInit() { - // TODO + return m_wasInit; +} + +std::string Gfx::CGLDevice::GetError() +{ + return m_error; +} + +bool Gfx::CGLDevice::Create() +{ + m_wasInit = true; + + // TODO: move to functions? + glShadeModel(GL_SMOOTH); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + + std::string extensions = std::string( (char*) glGetString(GL_EXTENSIONS)); + + if (extensions.find("GL_ARB_multitexture") == std::string::npos) + { + m_error = "Required extension GL_ARB_multitexture not supported"; + return false; + } + + if (extensions.find("GL_EXT_texture_env_combine") == std::string::npos) + { + m_error = "Required extension GL_EXT_texture_env_combine not supported"; + return false; + } + + int maxTextures = 0; + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextures); + m_textures = std::vector(maxTextures, NULL); + + m_lights = std::vector(GL_MAX_LIGHTS, Gfx::Light()); + m_lightsEnabled = std::vector(GL_MAX_LIGHTS, false); + + m_private->glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord1fARB"); + m_private->glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord2fARB"); + m_private->glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord3fARB"); + m_private->glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord4fARB"); + m_private->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB"); + m_private->glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glClientActiveTextureARB"); + + return true; } void Gfx::CGLDevice::Destroy() { - // TODO + m_private->glMultiTexCoord1fARB = NULL; + m_private->glMultiTexCoord2fARB = NULL; + m_private->glMultiTexCoord3fARB = NULL; + m_private->glMultiTexCoord4fARB = NULL; + m_private->glActiveTextureARB = NULL; + m_private->glClientActiveTextureARB = NULL; + + // Delete the remaining textures + std::set::iterator it; + for (it = m_allTextures.begin(); it != m_allTextures.end(); ++it) + delete *it; + m_allTextures.clear(); + + m_wasInit = false; } void Gfx::CGLDevice::BeginScene() { - // TODO + Clear(); + + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(m_projectionMat.Array()); + + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(m_modelviewMat.Array()); } void Gfx::CGLDevice::EndScene() { - // TODO + glFlush(); } void Gfx::CGLDevice::Clear() { - // TODO + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void Gfx::CGLDevice::SetTransform(Gfx::TransformType type, const Math::Matrix &matrix) { - switch (type) + if (type == Gfx::TRANSFORM_WORLD) + { + m_worldMat = matrix; + m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(m_modelviewMat.Array()); + } + else if (type == Gfx::TRANSFORM_VIEW) + { + m_viewMat = matrix; + m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(m_modelviewMat.Array()); + } + else if (type == Gfx::TRANSFORM_PROJECTION) { - case Gfx::TRANSFORM_WORLD: - m_worldMat = matrix; - // TODO - break; - case Gfx::TRANSFORM_VIEW: - m_viewMat = matrix; - // TODO - break; - case Gfx::TRANSFORM_PROJECTION: - m_projectionMat = matrix; - // TODO - break; - default: - assert(false); + m_projectionMat = matrix; + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(m_projectionMat.Array()); + } + else + { + assert(false); } } const Math::Matrix& Gfx::CGLDevice::GetTransform(Gfx::TransformType type) { - switch (type) - { - case Gfx::TRANSFORM_WORLD: - return m_worldMat; - case Gfx::TRANSFORM_VIEW: - return m_viewMat; - case Gfx::TRANSFORM_PROJECTION: - return m_projectionMat; - default: - assert(false); - } + if (type == Gfx::TRANSFORM_WORLD) + return m_worldMat; + else if (type == Gfx::TRANSFORM_VIEW) + return m_viewMat; + else if (type == Gfx::TRANSFORM_PROJECTION) + return m_projectionMat; + else + assert(false); return m_worldMat; // to avoid warning } void Gfx::CGLDevice::MultiplyTransform(Gfx::TransformType type, const Math::Matrix &matrix) { - // TODO + if (type == Gfx::TRANSFORM_WORLD) + { + m_worldMat = Math::MultiplyMatrices(m_worldMat, matrix); + m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(m_modelviewMat.Array()); + } + else if (type == Gfx::TRANSFORM_VIEW) + { + m_viewMat = Math::MultiplyMatrices(m_viewMat, matrix); + m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(m_modelviewMat.Array()); + } + else if (type == Gfx::TRANSFORM_PROJECTION) + { + m_projectionMat = Math::MultiplyMatrices(m_projectionMat, matrix); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(m_projectionMat.Array()); + } + else + { + assert(false); + } } -void Gfx::CGLDevice::SetMaterial(const Gfx::Material &material) +void Gfx::CGLDevice::SetMaterial(Gfx::Material &material) { m_material = material; - // TODO + glMaterialfv(GL_AMBIENT, GL_FRONT_AND_BACK, m_material.ambient.Array()); + glMaterialfv(GL_DIFFUSE, GL_FRONT_AND_BACK, m_material.diffuse.Array()); + glMaterialfv(GL_SPECULAR, GL_FRONT_AND_BACK, m_material.specular.Array()); } const Gfx::Material& Gfx::CGLDevice::GetMaterial() @@ -130,14 +264,35 @@ int Gfx::CGLDevice::GetMaxLightCount() return m_lights.size(); } -void Gfx::CGLDevice::SetLight(int index, const Gfx::Light &light) +void Gfx::CGLDevice::SetLight(int index, Gfx::Light &light) { assert(index >= 0); assert(index < (int)m_lights.size()); m_lights[index] = light; - // TODO + // Indexing from GL_LIGHT0 should always work + glLightfv(GL_LIGHT0 + index, GL_AMBIENT, light.ambient.Array()); + glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, light.diffuse.Array()); + glLightfv(GL_LIGHT0 + index, GL_SPECULAR, light.specular.Array()); + + GLfloat position[4] = { light.position.x, light.position.y, light.position.z, 0.0f }; + if (light.type == LIGHT_DIRECTIONAL) + position[3] = 0.0f; + else + position[3] = 1.0f; + glLightfv(GL_LIGHT0 + index, GL_POSITION, position); + + GLfloat direction[4] = { light.direction.x, light.direction.y, light.direction.z, 0.0f }; + glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction); + + glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, light.range); + + // TODO: falloff?, phi?, theta? + + glLightf(GL_LIGHT0 + index, GL_CONSTANT_ATTENUATION, light.attenuation0); + glLightf(GL_LIGHT0 + index, GL_LINEAR_ATTENUATION, light.attenuation1); + glLightf(GL_LIGHT0 + index, GL_QUADRATIC_ATTENUATION, light.attenuation2); } const Gfx::Light& Gfx::CGLDevice::GetLight(int index) @@ -155,7 +310,7 @@ void Gfx::CGLDevice::SetLightEnabled(int index, bool enabled) m_lightsEnabled[index] = enabled; - // TODO + glEnable(GL_LIGHT0 + index); } bool Gfx::CGLDevice::GetLightEnabled(int index) @@ -171,7 +326,7 @@ int Gfx::CGLDevice::GetMaxTextureCount() return m_textures.size(); } -const Gfx::Texture& Gfx::CGLDevice::GetTexture(int index) +Gfx::Texture* Gfx::CGLDevice::GetTexture(int index) { assert(index >= 0); assert(index < (int)m_textures.size()); @@ -179,7 +334,7 @@ const Gfx::Texture& Gfx::CGLDevice::GetTexture(int index) return m_textures[index]; } -void Gfx::CGLDevice::SetTexture(int index, const Gfx::Texture &texture) +void Gfx::CGLDevice::SetTexture(int index, Gfx::Texture *texture) { assert(index >= 0); assert(index < (int)m_textures.size()); @@ -189,23 +344,339 @@ void Gfx::CGLDevice::SetTexture(int index, const Gfx::Texture &texture) // TODO } +void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, Vertex *vertices, int vertexCount) +{ + if (type == Gfx::PRIMITIVE_LINES) + glBegin(GL_LINES); + else if (type == Gfx::PRIMITIVE_TRIANGLES) + glBegin(GL_TRIANGLES); + else if (type == Gfx::PRIMITIVE_TRIANGLE_STRIP) + glBegin(GL_TRIANGLE_STRIP); + + for (int i = 0; i < vertexCount; ++i) + { + glNormal3fv((GLfloat*)vertices[i].normal.Array()); + glTexCoord2fv((GLfloat*)vertices[i].texCoord.Array()); + glVertex3fv((GLfloat*)vertices[i].coord.Array()); + } + + glEnd(); +} + +void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, Gfx::VertexCol *vertices, int vertexCount) +{ + if (type == Gfx::PRIMITIVE_LINES) + glBegin(GL_LINES); + else if (type == Gfx::PRIMITIVE_TRIANGLES) + glBegin(GL_TRIANGLES); + else if (type == Gfx::PRIMITIVE_TRIANGLE_STRIP) + glBegin(GL_TRIANGLE_STRIP); + + for (int i = 0; i < vertexCount; ++i) + { + // TODO: specular? + glColor4fv((GLfloat*)vertices[i].color.Array()); + glTexCoord2fv((GLfloat*)vertices[i].texCoord.Array()); + glVertex3fv((GLfloat*)vertices[i].coord.Array()); + } + + glEnd(); +} + +void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, VertexTex2 *vertices, int vertexCount) +{ + if (type == Gfx::PRIMITIVE_LINES) + glBegin(GL_LINES); + else if (type == Gfx::PRIMITIVE_TRIANGLES) + glBegin(GL_TRIANGLES); + else if (type == Gfx::PRIMITIVE_TRIANGLE_STRIP) + glBegin(GL_TRIANGLE_STRIP); + + for (int i = 0; i < vertexCount; ++i) + { + glNormal3fv((GLfloat*) vertices[i].normal.Array()); + // TODO glMultiTexCoord2fARB(GL_TEXTURE0_ARB, vertices[i].texCoord.x, vertices[i].texCoord.y); + // TODO glMultiTexCoord2fARB(GL_TEXTURE1_ARB, vertices[i].texCoord2.x, vertices[i].texCoord2.y); + glVertex3fv((GLfloat*) vertices[i].coord.Array()); + } + + glEnd(); +} + void Gfx::CGLDevice::SetRenderState(Gfx::RenderState state, bool enabled) { - // TODO + if (state == RENDER_STATE_DEPTH_WRITE) + { + glDepthMask(enabled ? GL_TRUE : GL_FALSE); + return; + } + else if (state == RENDER_STATE_TEXTURING) + { + if (enabled) + { + glEnable(GL_TEXTURE_2D); + // TODO multitexture + } + else + { + glDisable(GL_TEXTURE_2D); + } + return; + } + + GLenum flag = 0; + + switch (state) + { + case Gfx::RENDER_STATE_LIGHTING: flag = GL_DEPTH_WRITEMASK; break; + case Gfx::RENDER_STATE_BLENDING: flag = GL_BLEND; break; + case Gfx::RENDER_STATE_FOG: flag = GL_FOG; break; + case Gfx::RENDER_STATE_DEPTH_TEST: flag = GL_DEPTH_TEST; break; + case Gfx::RENDER_STATE_ALPHA_TEST: flag = GL_ALPHA_TEST; break; + case Gfx::RENDER_STATE_DITHERING: flag = GL_DITHER; break; + default: assert(false); break; + } + + if (enabled) + glEnable(flag); + else + glDisable(flag); } bool Gfx::CGLDevice::GetRenderState(Gfx::RenderState state) { - // TODO - return false; + GLenum flag = 0; + + switch (state) + { + case Gfx::RENDER_STATE_DEPTH_WRITE: flag = GL_DEPTH_WRITEMASK; break; + case Gfx::RENDER_STATE_TEXTURING: flag = GL_TEXTURE_2D; break; + case Gfx::RENDER_STATE_LIGHTING: flag = GL_DEPTH_WRITEMASK; break; + case Gfx::RENDER_STATE_BLENDING: flag = GL_BLEND; break; + case Gfx::RENDER_STATE_FOG: flag = GL_FOG; break; + case Gfx::RENDER_STATE_DEPTH_TEST: flag = GL_DEPTH_TEST; break; + case Gfx::RENDER_STATE_ALPHA_TEST: flag = GL_ALPHA_TEST; break; + case Gfx::RENDER_STATE_DITHERING: flag = GL_DITHER; break; + default: assert(false); break; + } + + GLboolean result = GL_FALSE; + glGetBooleanv(flag, &result); + + return result == GL_TRUE; } -void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType, Vertex *vertices, int vertexCount) +Gfx::CompFunc TranslateGLCompFunc(GLenum flag) { - // TODO + switch (flag) + { + case GL_NEVER: return Gfx::COMP_FUNC_NEVER; + case GL_LESS: return Gfx::COMP_FUNC_LESS; + case GL_EQUAL: return Gfx::COMP_FUNC_EQUAL; + case GL_NOTEQUAL: return Gfx::COMP_FUNC_NOTEQUAL; + case GL_LEQUAL: return Gfx::COMP_FUNC_LEQUAL; + case GL_GREATER: return Gfx::COMP_FUNC_GREATER; + case GL_GEQUAL: return Gfx::COMP_FUNC_GEQUAL; + case GL_ALWAYS: return Gfx::COMP_FUNC_ALWAYS; + default: assert(false); break; + } + return Gfx::COMP_FUNC_NEVER; } -void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType, VertexTex2 *vertices, int vertexCount) +GLenum TranslateGfxCompFunc(Gfx::CompFunc func) { - // TODO + switch (func) + { + case Gfx::COMP_FUNC_NEVER: return GL_NEVER; + case Gfx::COMP_FUNC_LESS: return GL_LESS; + case Gfx::COMP_FUNC_EQUAL: return GL_EQUAL; + case Gfx::COMP_FUNC_NOTEQUAL: return GL_NOTEQUAL; + case Gfx::COMP_FUNC_LEQUAL: return GL_LEQUAL; + case Gfx::COMP_FUNC_GREATER: return GL_GREATER; + case Gfx::COMP_FUNC_GEQUAL: return GL_GEQUAL; + case Gfx::COMP_FUNC_ALWAYS: return GL_ALWAYS; + default: assert(false); break; + } + return 0; +} + +void Gfx::CGLDevice::SetDepthTestFunc(Gfx::CompFunc func) +{ + glDepthFunc(TranslateGfxCompFunc(func)); +} + +Gfx::CompFunc Gfx::CGLDevice::GetDepthTestFunc() +{ + GLenum flag = 0; + glGetIntegerv(GL_DEPTH_FUNC, (GLint*)&flag); + return TranslateGLCompFunc(flag); +} + +void Gfx::CGLDevice::SetDepthBias(float factor) +{ + glPolygonOffset(factor, 0.0f); +} + +float Gfx::CGLDevice::GetDepthBias() +{ + GLfloat result = 0.0f; + glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &result); + return result; +} + +void Gfx::CGLDevice::SetAlphaTestFunc(Gfx::CompFunc func, float refValue) +{ + glAlphaFunc(TranslateGfxCompFunc(func), refValue); +} + +void Gfx::CGLDevice::GetAlphaTestFunc(Gfx::CompFunc &func, float &refValue) +{ + GLenum flag = 0; + glGetIntegerv(GL_ALPHA_TEST_FUNC, (GLint*)&flag); + func = TranslateGLCompFunc(flag); + + glGetFloatv(GL_ALPHA_TEST_REF, (GLfloat*) &refValue); +} + +Gfx::BlendFunc TranslateGLBlendFunc(GLenum flag) +{ + switch (flag) + { + case GL_ZERO: return Gfx::BLEND_ZERO; + case GL_ONE: return Gfx::BLEND_ONE; + case GL_SRC_COLOR: return Gfx::BLEND_SRC_COLOR; + case GL_ONE_MINUS_SRC_COLOR: return Gfx::BLEND_INV_SRC_COLOR; + case GL_DST_COLOR: return Gfx::BLEND_DST_COLOR; + case GL_ONE_MINUS_DST_COLOR: return Gfx::BLEND_INV_DST_COLOR; + case GL_SRC_ALPHA: return Gfx::BLEND_SRC_ALPHA; + case GL_ONE_MINUS_SRC_ALPHA: return Gfx::BLEND_INV_SRC_ALPHA; + case GL_DST_ALPHA: return Gfx::BLEND_DST_ALPHA; + case GL_ONE_MINUS_DST_ALPHA: return Gfx::BLEND_INV_DST_ALPHA; + case GL_SRC_ALPHA_SATURATE: return Gfx::BLEND_SRC_ALPHA_SATURATE; + default: assert(false); break; + } + + return Gfx::BLEND_ZERO; +} + +GLenum TranslateGfxBlendFunc(Gfx::BlendFunc func) +{ + switch (func) + { + case Gfx::BLEND_ZERO: return GL_ZERO; + case Gfx::BLEND_ONE: return GL_ONE; + case Gfx::BLEND_SRC_COLOR: return GL_SRC_COLOR; + case Gfx::BLEND_INV_SRC_COLOR: return GL_ONE_MINUS_SRC_COLOR; + case Gfx::BLEND_DST_COLOR: return GL_DST_COLOR; + case Gfx::BLEND_INV_DST_COLOR: return GL_ONE_MINUS_DST_COLOR; + case Gfx::BLEND_SRC_ALPHA: return GL_SRC_ALPHA; + case Gfx::BLEND_INV_SRC_ALPHA: return GL_ONE_MINUS_SRC_ALPHA; + case Gfx::BLEND_DST_ALPHA: return GL_DST_ALPHA; + case Gfx::BLEND_INV_DST_ALPHA: return GL_ONE_MINUS_DST_ALPHA; + case Gfx::BLEND_SRC_ALPHA_SATURATE: return GL_SRC_ALPHA_SATURATE; + default: assert(false); break; + } + return 0; +} + +void Gfx::CGLDevice::SetBlendFunc(Gfx::BlendFunc srcBlend, Gfx::BlendFunc dstBlend) +{ + glBlendFunc(TranslateGfxBlendFunc(srcBlend), TranslateGfxBlendFunc(dstBlend)); +} + +void Gfx::CGLDevice::GetBlendFunc(Gfx::BlendFunc &srcBlend, Gfx::BlendFunc &dstBlend) +{ + GLenum srcFlag = 0; + glGetIntegerv(GL_ALPHA_TEST_FUNC, (GLint*)&srcFlag); + srcBlend = TranslateGLBlendFunc(srcFlag); + + GLenum dstFlag = 0; + glGetIntegerv(GL_ALPHA_TEST_FUNC, (GLint*)&dstFlag); + dstBlend = TranslateGLBlendFunc(dstFlag); +} + +void Gfx::CGLDevice::SetClearColor(Gfx::Color color) +{ + glClearColor(color.r, color.g, color.b, color.a); +} + +Gfx::Color Gfx::CGLDevice::GetClearColor() +{ + float color[4] = { 0.0f }; + glGetFloatv(GL_COLOR_CLEAR_VALUE, color); + return Gfx::Color(color[0], color[1], color[2], color[3]); +} + +void Gfx::CGLDevice::SetGlobalAmbient(Gfx::Color color) +{ + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color.Array()); +} + +Gfx::Color Gfx::CGLDevice::GetGlobalAmbient() +{ + float color[4] = { 0.0f }; + glGetFloatv(GL_LIGHT_MODEL_AMBIENT, color); + return Gfx::Color(color[0], color[1], color[2], color[3]); +} + +void Gfx::CGLDevice::SetFogParams(Gfx::FogMode mode, Gfx::Color color, float start, float end, float density) +{ + if (mode == Gfx::FOG_LINEAR) glFogi(GL_FOG_MODE, GL_LINEAR); + else if (mode == Gfx::FOG_EXP) glFogi(GL_FOG_MODE, GL_EXP); + else if (mode == Gfx::FOG_EXP2) glFogi(GL_FOG_MODE, GL_EXP2); + else assert(false); + + glFogf(GL_FOG_START, start); + glFogf(GL_FOG_END, end); + glFogf(GL_FOG_DENSITY, density); +} + +void Gfx::CGLDevice::GetFogParams(Gfx::FogMode &mode, Gfx::Color &color, float &start, float &end, float &density) +{ + GLenum flag = 0; + glGetIntegerv(GL_FOG_MODE, (GLint*)&flag); + if (flag == GL_LINEAR) mode = Gfx::FOG_LINEAR; + else if (flag == GL_EXP) mode = Gfx::FOG_EXP; + else if (flag == GL_EXP2) mode = Gfx::FOG_EXP2; + else assert(false); + + glGetFloatv(GL_FOG_START, (GLfloat*)&start); + glGetFloatv(GL_FOG_END, (GLfloat*)&end); + glGetFloatv(GL_FOG_DENSITY, (GLfloat*)&density); +} + +void Gfx::CGLDevice::SetCullMode(Gfx::CullMode mode) +{ + if (mode == Gfx::CULL_CW) glCullFace(GL_CW); + else if (mode == Gfx::CULL_CCW) glCullFace(GL_CCW); + else assert(false); +} + +Gfx::CullMode Gfx::CGLDevice::GetCullMode() +{ + GLenum flag = 0; + glGetIntegerv(GL_CULL_FACE, (GLint*)&flag); + if (flag == GL_CW) return Gfx::CULL_CW; + else if (flag == GL_CCW) return Gfx::CULL_CCW; + else assert(false); + return Gfx::CULL_CW; +} + +void Gfx::CGLDevice::SetFillMode(Gfx::FillMode mode) +{ + if (mode == Gfx::FILL_POINT) glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); + else if (mode == Gfx::FILL_LINES) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else if (mode == Gfx::FILL_FILL) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + else assert(false); +} + +Gfx::FillMode Gfx::CGLDevice::GetFillMode() +{ + GLenum flag = 0; + glGetIntegerv(GL_POLYGON_MODE, (GLint*)&flag); + if (flag == GL_POINT) return Gfx::FILL_POINT; + else if (flag == GL_LINE) return Gfx::FILL_LINES; + else if (flag == GL_FILL) return Gfx::FILL_FILL; + else assert(false); + return Gfx::FILL_POINT; } -- cgit v1.2.3-1-g7c22