Added experimental support for dynamic shadows (shadow mapping)
parent
1e3c2cc2df
commit
0b2f00530b
|
@ -123,6 +123,7 @@ enum PerformanceCounter
|
|||
PCNT_RENDER_TERRAIN, //! < rendering the terrain
|
||||
PCNT_RENDER_OBJECTS, //! < rendering the 3D objects
|
||||
PCNT_RENDER_INTERFACE, //! < rendering 2D interface
|
||||
PCNT_RENDER_SHADOW_MAP, //! < rendering shadow map
|
||||
|
||||
PCNT_ALL, //! < all counters together
|
||||
|
||||
|
|
|
@ -91,8 +91,7 @@ enum TransformType
|
|||
{
|
||||
TRANSFORM_WORLD,
|
||||
TRANSFORM_VIEW,
|
||||
TRANSFORM_PROJECTION,
|
||||
TRANSFORM_TEXTURE
|
||||
TRANSFORM_PROJECTION
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -107,7 +106,8 @@ enum RenderState
|
|||
RENDER_STATE_DEPTH_TEST,
|
||||
RENDER_STATE_DEPTH_WRITE,
|
||||
RENDER_STATE_ALPHA_TEST,
|
||||
RENDER_STATE_CULLING
|
||||
RENDER_STATE_CULLING,
|
||||
RENDER_STATE_DEPTH_BIAS
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -276,6 +276,8 @@ public:
|
|||
virtual Texture CreateTexture(CImage *image, const TextureCreateParams ¶ms) = 0;
|
||||
//! Creates a texture from raw image data; image data can be freed after that
|
||||
virtual Texture CreateTexture(ImageData *data, const TextureCreateParams ¶ms) = 0;
|
||||
//! Creates a depth texture with specific dimensions and depth
|
||||
virtual Texture CreateDepthTexture(int width, int height, int depth) = 0;
|
||||
//! Deletes a given texture, freeing it from video memory
|
||||
virtual void DestroyTexture(const Texture &texture) = 0;
|
||||
//! Deletes all textures created so far
|
||||
|
@ -296,6 +298,12 @@ public:
|
|||
//! Sets only the texture wrap modes (for faster than thru stage params)
|
||||
virtual void SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT) = 0;
|
||||
|
||||
//! Sets the texture coordinate generation mode for given texture unit
|
||||
virtual void SetTextureCoordGeneration(int index, TextureGenerationParams ¶ms) = 0;
|
||||
|
||||
//! Sets texture coordinate transform matrix
|
||||
virtual void SetTextureMatrix(int index, Math::Matrix& matrix) = 0;
|
||||
|
||||
//! Renders primitive composed of vertices with single texture
|
||||
virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount,
|
||||
Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) = 0;
|
||||
|
@ -333,14 +341,20 @@ public:
|
|||
//! Returns a mask of frustum planes for which the test is positive
|
||||
virtual int ComputeSphereVisibility(const Math::Vector ¢er, float radius) = 0;
|
||||
|
||||
//! Changes rendering viewport
|
||||
virtual void SetViewport(int x, int y, int width, int height) = 0;
|
||||
|
||||
//! Enables/disables the given render state
|
||||
virtual void SetRenderState(RenderState state, bool enabled) = 0;
|
||||
|
||||
//! Sets the color mask
|
||||
virtual void SetColorMask(bool red, bool green, bool blue, bool alpha) = 0;
|
||||
|
||||
//! Sets the function of depth test
|
||||
virtual void SetDepthTestFunc(CompFunc func) = 0;
|
||||
|
||||
//! Sets the depth bias (constant value added to Z-coords)
|
||||
virtual void SetDepthBias(float factor) = 0;
|
||||
virtual void SetDepthBias(float factor, float units) = 0;
|
||||
|
||||
//! Sets the alpha test function and reference value
|
||||
virtual void SetAlphaTestFunc(CompFunc func, float refValue) = 0;
|
||||
|
@ -366,6 +380,9 @@ public:
|
|||
//! Sets the current fill mode
|
||||
virtual void SetFillMode(FillMode mode) = 0;
|
||||
|
||||
//! Copies content of framebuffer to texture
|
||||
virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) = 0;
|
||||
|
||||
//! Returns the pixels of the entire screen
|
||||
virtual void* GetFrameBufferPixels() const = 0;
|
||||
};
|
||||
|
|
|
@ -128,6 +128,13 @@ Texture CNullDevice::CreateTexture(ImageData *data, const TextureCreateParams &p
|
|||
return tex;
|
||||
}
|
||||
|
||||
Texture CNullDevice::CreateDepthTexture(int width, int height, int depth)
|
||||
{
|
||||
Texture tex;
|
||||
tex.id = 1; // tex.id = 0 => invalid texture
|
||||
return tex;
|
||||
}
|
||||
|
||||
void CNullDevice::DestroyTexture(const Texture &texture)
|
||||
{
|
||||
}
|
||||
|
@ -171,6 +178,14 @@ void CNullDevice::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode
|
|||
{
|
||||
}
|
||||
|
||||
void CNullDevice::SetTextureCoordGeneration(int index, TextureGenerationParams ¶ms)
|
||||
{
|
||||
}
|
||||
|
||||
void CNullDevice::SetTextureMatrix(int index, Math::Matrix& matrix)
|
||||
{
|
||||
}
|
||||
|
||||
TextureStageParams CNullDevice::GetTextureStageParams(int index)
|
||||
{
|
||||
return TextureStageParams();
|
||||
|
@ -230,6 +245,10 @@ int CNullDevice::ComputeSphereVisibility(const Math::Vector ¢er, float radiu
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CNullDevice::SetViewport(int x, int y, int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
void CNullDevice::SetRenderState(RenderState state, bool enabled)
|
||||
{
|
||||
}
|
||||
|
@ -239,6 +258,10 @@ bool CNullDevice::GetRenderState(RenderState state)
|
|||
return false;
|
||||
}
|
||||
|
||||
void CNullDevice::SetColorMask(bool red, bool green, bool blue, bool alpha)
|
||||
{
|
||||
}
|
||||
|
||||
void CNullDevice::SetDepthTestFunc(CompFunc func)
|
||||
{
|
||||
}
|
||||
|
@ -248,7 +271,7 @@ CompFunc CNullDevice::GetDepthTestFunc()
|
|||
return COMP_FUNC_NEVER;
|
||||
}
|
||||
|
||||
void CNullDevice::SetDepthBias(float factor)
|
||||
void CNullDevice::SetDepthBias(float factor, float units)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -332,6 +355,10 @@ FillMode CNullDevice::GetFillMode()
|
|||
return FILL_POINT;
|
||||
}
|
||||
|
||||
void CNullDevice::CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
void* CNullDevice::GetFrameBufferPixels() const
|
||||
{
|
||||
return nullptr;
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
|
||||
virtual Texture CreateTexture(CImage *image, const TextureCreateParams ¶ms);
|
||||
virtual Texture CreateTexture(ImageData *data, const TextureCreateParams ¶ms);
|
||||
virtual Texture CreateDepthTexture(int width, int height, int depth);
|
||||
virtual void DestroyTexture(const Texture &texture);
|
||||
virtual void DestroyAllTextures();
|
||||
|
||||
|
@ -81,6 +82,8 @@ public:
|
|||
virtual TextureStageParams GetTextureStageParams(int index);
|
||||
|
||||
virtual void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT);
|
||||
virtual void SetTextureCoordGeneration(int index, TextureGenerationParams ¶ms);
|
||||
virtual void SetTextureMatrix(int index, Math::Matrix& matrix);
|
||||
|
||||
virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount,
|
||||
Color color = Color(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
@ -98,14 +101,18 @@ public:
|
|||
virtual void DestroyStaticBuffer(unsigned int bufferId);
|
||||
|
||||
virtual int ComputeSphereVisibility(const Math::Vector ¢er, float radius);
|
||||
|
||||
virtual void SetViewport(int x, int y, int width, int height);
|
||||
|
||||
virtual void SetRenderState(RenderState state, bool enabled);
|
||||
virtual bool GetRenderState(RenderState state);
|
||||
|
||||
virtual void SetColorMask(bool red, bool green, bool blue, bool alpha);
|
||||
|
||||
virtual void SetDepthTestFunc(CompFunc func);
|
||||
virtual CompFunc GetDepthTestFunc();
|
||||
|
||||
virtual void SetDepthBias(float factor);
|
||||
virtual void SetDepthBias(float factor, float units);
|
||||
virtual float GetDepthBias();
|
||||
|
||||
virtual void SetAlphaTestFunc(CompFunc func, float refValue);
|
||||
|
@ -131,6 +138,8 @@ public:
|
|||
|
||||
virtual void SetFillMode(FillMode mode) ;
|
||||
virtual FillMode GetFillMode();
|
||||
|
||||
virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height);
|
||||
|
||||
virtual void* GetFrameBufferPixels() const;
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ enum TexMagFilter
|
|||
enum TexWrapMode
|
||||
{
|
||||
TEX_WRAP_CLAMP,
|
||||
TEX_WRAP_CLAMP_TO_BORDER,
|
||||
TEX_WRAP_REPEAT
|
||||
};
|
||||
|
||||
|
@ -215,6 +216,54 @@ struct TextureStageParams
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct TexGenMode
|
||||
* \brief Texture generation mode
|
||||
*/
|
||||
enum TexGenMode
|
||||
{
|
||||
//! No texture generation
|
||||
TEX_GEN_NONE,
|
||||
//! Object linear mode
|
||||
TEX_GEN_OBJECT_LINEAR,
|
||||
//! Eye linear mode
|
||||
TEX_GEN_EYE_LINEAR,
|
||||
//! Spherical mapping mode
|
||||
TEX_GEN_SPHERE_MAP,
|
||||
//! Normal mapping mode
|
||||
TEX_GEN_NORMAL_MAP,
|
||||
//! Reflection mapping mode
|
||||
TEX_GEN_REFLECTION_MAP
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct TextureGenerationParams
|
||||
* \brief Parameters for texture coordinate generation
|
||||
*
|
||||
* These params define the generation of texture coordinate for given texture unit.
|
||||
*/
|
||||
struct TextureGenerationParams
|
||||
{
|
||||
struct
|
||||
{
|
||||
TexGenMode mode;
|
||||
float plane[4];
|
||||
} coords[4];
|
||||
|
||||
TextureGenerationParams()
|
||||
{
|
||||
LoadDefault();
|
||||
}
|
||||
|
||||
inline void LoadDefault()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
coords[i].mode = TEX_GEN_NONE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct Texture
|
||||
* \brief Info about a texture
|
||||
|
|
|
@ -116,6 +116,8 @@ CEngine::CEngine(CApplication *app)
|
|||
m_textureQuality = 1;
|
||||
m_textureMipmapLevel = 1;
|
||||
m_textureAnisotropy = 1;
|
||||
m_shadowMapping = false;
|
||||
m_npotShadowMap = false;
|
||||
m_totoMode = true;
|
||||
m_lensMode = true;
|
||||
m_waterMode = true;
|
||||
|
@ -181,6 +183,12 @@ CEngine::CEngine(CApplication *app)
|
|||
m_textureAnisotropy = value;
|
||||
}
|
||||
|
||||
if (CProfile::GetInstance().GetIntProperty("Setup", "ShadowMapping", value))
|
||||
{
|
||||
m_shadowMapping = (value > 0);
|
||||
m_npotShadowMap = (value > 1);
|
||||
}
|
||||
|
||||
m_defaultTexParams.format = TEX_IMG_AUTO;
|
||||
m_defaultTexParams.mipmap = mipmaps;
|
||||
m_defaultTexParams.filter = filter;
|
||||
|
@ -188,6 +196,13 @@ CEngine::CEngine(CApplication *app)
|
|||
m_terrainTexParams.format = TEX_IMG_AUTO;
|
||||
m_terrainTexParams.mipmap = mipmaps;
|
||||
m_terrainTexParams.filter = filter;
|
||||
|
||||
// Compute bias matrix for shadow mapping
|
||||
Math::Matrix temp1, temp2;
|
||||
Math::LoadScaleMatrix(temp1, Math::Vector(0.5f, 0.5f, 0.5f));
|
||||
Math::LoadTranslationMatrix(temp2, Math::Vector(1.0f, 1.0f, 1.0f));
|
||||
//m_shadowBias = Math::MultiplyMatrices(m_shadowBias, temporary);
|
||||
m_shadowBias = Math::MultiplyMatrices(temp1, temp2);
|
||||
}
|
||||
|
||||
CEngine::~CEngine()
|
||||
|
@ -2965,6 +2980,16 @@ int CEngine::GetTextureAnisotropyLevel()
|
|||
return m_textureAnisotropy;
|
||||
}
|
||||
|
||||
void CEngine::SetShadowMapping(bool value)
|
||||
{
|
||||
m_shadowMapping = value;
|
||||
}
|
||||
|
||||
bool CEngine::GetShadowMapping()
|
||||
{
|
||||
return m_shadowMapping;
|
||||
}
|
||||
|
||||
void CEngine::SetTotoMode(bool present)
|
||||
{
|
||||
m_totoMode = present;
|
||||
|
@ -3165,6 +3190,9 @@ void CEngine::Render()
|
|||
// Begin the scene
|
||||
m_device->BeginScene();
|
||||
|
||||
if (m_shadowMapping)
|
||||
RenderShadowMap();
|
||||
|
||||
if (m_drawWorld)
|
||||
Draw3DScene();
|
||||
|
||||
|
@ -3207,6 +3235,38 @@ void CEngine::Draw3DScene()
|
|||
|
||||
m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN);
|
||||
|
||||
// Enable shadow mapping
|
||||
if (m_shadowMapping)
|
||||
{
|
||||
m_device->SetTextureEnabled(2, true);
|
||||
m_device->SetTexture(2, m_shadowMap);
|
||||
m_device->SetTextureMatrix(2, m_shadowTextureMat);
|
||||
|
||||
Math::Matrix identity;
|
||||
identity.LoadIdentity();
|
||||
m_device->SetTransform(TRANSFORM_WORLD, identity);
|
||||
|
||||
TextureStageParams params;
|
||||
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
||||
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
|
||||
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
|
||||
m_device->SetTextureStageParams(2, params);
|
||||
|
||||
TextureGenerationParams genParams;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
genParams.coords[i].mode = TEX_GEN_EYE_LINEAR;
|
||||
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
genParams.coords[i].plane[j] = (i == j ? 1.0f : 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
m_device->SetTextureCoordGeneration(2, genParams);
|
||||
}
|
||||
|
||||
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
||||
{
|
||||
if (! m_objects[objRank].used)
|
||||
|
@ -3260,6 +3320,24 @@ void CEngine::Draw3DScene()
|
|||
}
|
||||
}
|
||||
|
||||
// Disable shadow mapping
|
||||
if (m_shadowMapping)
|
||||
{
|
||||
Math::Matrix identity;
|
||||
identity.LoadIdentity();
|
||||
|
||||
m_device->SetTexture(2, 0);
|
||||
m_device->SetTextureEnabled(2, false);
|
||||
m_device->SetTextureMatrix(2, identity);
|
||||
|
||||
TextureGenerationParams params;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
params.coords[i].mode = TEX_GEN_NONE;
|
||||
|
||||
m_device->SetTextureCoordGeneration(2, params);
|
||||
}
|
||||
|
||||
// Draws the shadows , if shadows enabled
|
||||
if (m_shadowVisible)
|
||||
DrawShadow();
|
||||
|
@ -3431,6 +3509,154 @@ void CEngine::Draw3DScene()
|
|||
if (! m_overFront) DrawOverColor(); // draws the foreground color
|
||||
}
|
||||
|
||||
void CEngine::RenderShadowMap()
|
||||
{
|
||||
if (!m_shadowMapping) return;
|
||||
|
||||
m_app->StartPerformanceCounter(PCNT_RENDER_SHADOW_MAP);
|
||||
|
||||
m_device->Clear();
|
||||
|
||||
// If no shadow map texture exists, create it
|
||||
if (m_shadowMap.id == 0)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
int depth = m_app->GetInstance().GetVideoConfig().depthSize;
|
||||
|
||||
if (m_npotShadowMap)
|
||||
{
|
||||
width = height = Math::Min(m_size.x, m_size.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
int min = Math::Min(m_size.x, m_size.y);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (min < (1 << i)) break;
|
||||
|
||||
width = height = 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
m_shadowMap = m_device->CreateDepthTexture(width, height, depth);
|
||||
|
||||
GetLogger()->Info("Created shadow map texture: %dx%d, depth %d\n", width, height, depth);
|
||||
}
|
||||
|
||||
// change state to rendering shadow maps
|
||||
m_device->SetColorMask(false, false, false, false);
|
||||
//m_device->SetDepthTestFunc(COMP_FUNC_LEQUAL);
|
||||
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, true);
|
||||
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, true);
|
||||
m_device->SetRenderState(RENDER_STATE_BLENDING, false);
|
||||
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
||||
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
||||
m_device->SetRenderState(RENDER_STATE_CULLING, false);
|
||||
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, true);
|
||||
|
||||
m_device->SetViewport(0, 0, m_shadowMap.size.x, m_shadowMap.size.y);
|
||||
|
||||
// recompute matrices
|
||||
Math::Vector worldUp(1.0f, 0.0f, 0.0f);
|
||||
Math::Vector dir = m_lookatPt - m_eyePt;
|
||||
float change = Math::Max(1.0f, dir.Length() / 25.0f);
|
||||
dir.Normalize();
|
||||
Math::Vector pos = m_lookatPt + 40.0f * dir;
|
||||
|
||||
Math::Vector lightPos = pos + Math::Vector(3.0f, 30.0f, 3.0f);
|
||||
Math::Vector lookAt = pos + Math::Vector(0.0, 100.0f, 0.0f);
|
||||
|
||||
float dist = 75.0f; // *change;
|
||||
|
||||
Math::LoadOrthoProjectionMatrix(m_shadowProjMat, -dist, dist, -dist, dist, -50.0f, 50.0f);
|
||||
Math::LoadViewMatrix(m_shadowViewMat, lightPos, lookAt, worldUp);
|
||||
|
||||
Math::Matrix temporary = Math::MultiplyMatrices(m_shadowProjMat, m_shadowViewMat);
|
||||
m_shadowTextureMat = Math::MultiplyMatrices(m_shadowBias, temporary);
|
||||
|
||||
m_device->SetTransform(TRANSFORM_PROJECTION, m_shadowProjMat);
|
||||
m_device->SetTransform(TRANSFORM_VIEW, m_shadowViewMat);
|
||||
|
||||
m_device->SetTexture(0, 0);
|
||||
m_device->SetTexture(1, 0);
|
||||
|
||||
//m_device->SetCullMode(CULL_CW);
|
||||
//m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, true);
|
||||
//m_device->SetDepthBias(2.0f, 4.0f);
|
||||
|
||||
// render objects into shadow map
|
||||
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
||||
{
|
||||
if (!m_objects[objRank].used)
|
||||
continue;
|
||||
|
||||
if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN)
|
||||
continue;
|
||||
|
||||
//if (!m_objects[objRank].drawWorld)
|
||||
// continue;
|
||||
|
||||
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||
|
||||
// TODO: check proper object filtering
|
||||
if (!IsVisible(objRank))
|
||||
continue;
|
||||
|
||||
int baseObjRank = m_objects[objRank].baseObjRank;
|
||||
if (baseObjRank == -1)
|
||||
continue;
|
||||
|
||||
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
|
||||
|
||||
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
||||
if (!p1.used)
|
||||
continue;
|
||||
|
||||
//m_lightMan->UpdateDeviceLights(m_objects[objRank].type);
|
||||
|
||||
for (int l2 = 0; l2 < static_cast<int>(p1.next.size()); l2++)
|
||||
{
|
||||
EngineBaseObjTexTier& p2 = p1.next[l2];
|
||||
|
||||
for (int l3 = 0; l3 < static_cast<int>(p2.next.size()); l3++)
|
||||
{
|
||||
EngineBaseObjLODTier& p3 = p2.next[l3];
|
||||
|
||||
if (!IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
||||
continue;
|
||||
|
||||
for (int l4 = 0; l4 < static_cast<int>(p3.next.size()); l4++)
|
||||
{
|
||||
EngineBaseObjDataTier& p4 = p3.next[l4];
|
||||
|
||||
//if (m_objects[objRank].transparency != 0.0f) // transparent ?
|
||||
// continue;
|
||||
|
||||
DrawObject(p4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_device->SetCullMode(CULL_CCW);
|
||||
m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, false);
|
||||
|
||||
// copy depth buffer to shadow map
|
||||
m_device->CopyFramebufferToTexture(m_shadowMap, 0, 0, 0, 0, m_shadowMap.size.x, m_shadowMap.size.y);
|
||||
|
||||
// restore default state
|
||||
m_device->SetViewport(0, 0, m_size.x, m_size.y);
|
||||
|
||||
m_device->SetColorMask(true, true, true, true);
|
||||
m_device->Clear();
|
||||
|
||||
m_app->StopPerformanceCounter(PCNT_RENDER_SHADOW_MAP);
|
||||
|
||||
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false);
|
||||
}
|
||||
|
||||
void CEngine::DrawObject(const EngineBaseObjDataTier& p4)
|
||||
{
|
||||
if (p4.staticBufferId != 0)
|
||||
|
@ -4406,8 +4632,8 @@ void CEngine::DrawStats()
|
|||
if (!m_showStats)
|
||||
return;
|
||||
|
||||
float height = m_text->GetAscent(FONT_COLOBOT, 12.0f);
|
||||
float width = 0.2f;
|
||||
float height = m_text->GetAscent(FONT_COLOBOT, 13.0f);
|
||||
float width = 0.25f;
|
||||
|
||||
Math::Point pos(0.04f, 0.04f + 20 * height);
|
||||
|
||||
|
@ -4510,12 +4736,19 @@ void CEngine::DrawStats()
|
|||
|
||||
pos.y -= height;
|
||||
|
||||
str.str("");
|
||||
str << "Shadow map render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_SHADOW_MAP);
|
||||
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
pos.y -= height;
|
||||
|
||||
float otherRender = m_app->GetPerformanceCounterData(PCNT_RENDER_ALL) -
|
||||
m_app->GetPerformanceCounterData(PCNT_RENDER_PARTICLE) -
|
||||
m_app->GetPerformanceCounterData(PCNT_RENDER_WATER) -
|
||||
m_app->GetPerformanceCounterData(PCNT_RENDER_TERRAIN) -
|
||||
m_app->GetPerformanceCounterData(PCNT_RENDER_OBJECTS) -
|
||||
m_app->GetPerformanceCounterData(PCNT_RENDER_INTERFACE);
|
||||
m_app->GetPerformanceCounterData(PCNT_RENDER_INTERFACE) -
|
||||
m_app->GetPerformanceCounterData(PCNT_RENDER_SHADOW_MAP);
|
||||
|
||||
str.str("");
|
||||
str << "Other render: " << std::fixed << std::setprecision(2) << otherRender;
|
||||
|
|
|
@ -1134,6 +1134,12 @@ public:
|
|||
int GetTextureAnisotropyLevel();
|
||||
//@}
|
||||
|
||||
//@{
|
||||
//! Management of shadow mapping
|
||||
void SetShadowMapping(bool value);
|
||||
bool GetShadowMapping();
|
||||
//@}
|
||||
|
||||
//@{
|
||||
//! Management mode of toto
|
||||
void SetTotoMode(bool present);
|
||||
|
@ -1227,6 +1233,8 @@ public:
|
|||
protected:
|
||||
//! Prepares the interface for 3D scene
|
||||
void Draw3DScene();
|
||||
//! Renders shadow map
|
||||
void RenderShadowMap();
|
||||
//! Draw 3D object
|
||||
void DrawObject(const EngineBaseObjDataTier& p4);
|
||||
//! Draws the user interface over the scene
|
||||
|
@ -1339,6 +1347,15 @@ protected:
|
|||
//! Camera angle for 3D scene
|
||||
float m_focus;
|
||||
|
||||
//! Projection matrix for rendering shadow maps
|
||||
Math::Matrix m_shadowProjMat;
|
||||
//! View matrix for rendering shadow maps
|
||||
Math::Matrix m_shadowViewMat;
|
||||
//! Texture matrix for rendering shadow maps
|
||||
Math::Matrix m_shadowTextureMat;
|
||||
//! Texture bias for sampling shadow maps
|
||||
Math::Matrix m_shadowBias;
|
||||
|
||||
//! World matrix for 2D interface
|
||||
Math::Matrix m_matWorldInterface;
|
||||
//! Projection matrix for 2D interface
|
||||
|
@ -1416,6 +1433,8 @@ protected:
|
|||
int m_editIndentValue;
|
||||
float m_tracePrecision;
|
||||
|
||||
Texture m_shadowMap;
|
||||
|
||||
//! Ranks of highlighted objects
|
||||
int m_highlightRank[100];
|
||||
//! Highlight visible?
|
||||
|
@ -1436,6 +1455,10 @@ protected:
|
|||
int m_textureMipmapLevel;
|
||||
//! Requested texture anisotropy level
|
||||
int m_textureAnisotropy;
|
||||
//! true if shadow mapping enabled
|
||||
bool m_shadowMapping;
|
||||
//! Override for NPOT shadow map texture
|
||||
bool m_npotShadowMap;
|
||||
|
||||
//! Map of loaded textures (by name)
|
||||
std::map<std::string, Texture> m_texNameMap;
|
||||
|
|
|
@ -59,8 +59,8 @@ void GLDeviceConfig::LoadDefault()
|
|||
vboMode = VBO_MODE_AUTO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLuint textureCoordinates[] = { GL_S, GL_T, GL_R, GL_Q };
|
||||
GLuint textureCoordGen[] = { GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_T, GL_TEXTURE_GEN_R, GL_TEXTURE_GEN_Q };
|
||||
|
||||
CGLDevice::CGLDevice(const GLDeviceConfig &config)
|
||||
{
|
||||
|
@ -72,6 +72,9 @@ CGLDevice::CGLDevice(const GLDeviceConfig &config)
|
|||
m_vertexBufferType = VBT_DISPLAY_LIST;
|
||||
m_anisotropyAvailable = false;
|
||||
m_maxAnisotropy = 1;
|
||||
m_glMajor = 1;
|
||||
m_glMinor = 1;
|
||||
m_shadowMappingSupport = SMS_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -204,10 +207,33 @@ bool CGLDevice::Create()
|
|||
return false;
|
||||
}
|
||||
|
||||
// Extract OpenGL version
|
||||
const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
sscanf(version, "%d.%d", &m_glMajor, &m_glMinor);
|
||||
GetLogger()->Info("OpenGL %d.%d\n", m_glMajor, m_glMinor);
|
||||
|
||||
// Detect multitexture support
|
||||
m_multitextureAvailable = glewIsSupported("GL_ARB_multitexture GL_ARB_texture_env_combine");
|
||||
if (!m_multitextureAvailable)
|
||||
GetLogger()->Warn("GLEW reports multitexturing not supported - graphics quality will be degraded!\n");
|
||||
|
||||
// Detect Shadow mapping support
|
||||
if (m_glMajor >= 2 || m_glMinor >= 4) // Core depth texture+shadow, OpenGL 1.4+
|
||||
{
|
||||
m_shadowMappingSupport = SMS_CORE;
|
||||
GetLogger()->Info("Shadow mapping available (core)\n");
|
||||
}
|
||||
else if (glewIsSupported("GL_ARB_depth_texture GL_ARB_shadow")) // ARB depth texture + shadow
|
||||
{
|
||||
m_shadowMappingSupport = SMS_ARB;
|
||||
GetLogger()->Info("Shadow mapping available (ARB)\n");
|
||||
}
|
||||
else // No Shadow mapping
|
||||
{
|
||||
m_shadowMappingSupport = SMS_NONE;
|
||||
GetLogger()->Info("Shadow mapping not available\n");
|
||||
}
|
||||
|
||||
// Detect support of anisotropic filtering
|
||||
m_anisotropyAvailable = glewIsSupported("GL_EXT_texture_filter_anisotropic");
|
||||
if(m_anisotropyAvailable)
|
||||
|
@ -239,30 +265,24 @@ bool CGLDevice::Create()
|
|||
{
|
||||
GetLogger()->Info("Auto-detecting VBO support\n");
|
||||
|
||||
// extracting OpenGL version
|
||||
const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
int major = 0, minor = 0;
|
||||
|
||||
sscanf(version, "%d.%d", &major, &minor);
|
||||
|
||||
// detecting VBO ARB extension
|
||||
bool vboARB = glewIsSupported("GL_ARB_vertex_buffer_object");
|
||||
|
||||
// VBO is core OpenGL feature since 1.5
|
||||
// everything below 1.5 means no VBO support
|
||||
if(major > 1 || minor > 4)
|
||||
if (m_glMajor > 1 || m_glMinor > 4)
|
||||
{
|
||||
GetLogger()->Info("OpenGL %d.%d, VBO supported\n", major, minor);
|
||||
GetLogger()->Info("Core VBO supported\n", m_glMajor, m_glMinor);
|
||||
SetVertexBufferType(VBT_VBO_CORE);
|
||||
}
|
||||
else if(vboARB) // VBO ARB extension available
|
||||
{
|
||||
GetLogger()->Info("OpenGL %d.%d with GL_ARB_vertex_buffer_object, VBO supported\n", major, minor);
|
||||
GetLogger()->Info("ARB VBO supported\n");
|
||||
SetVertexBufferType(VBT_VBO_ARB);
|
||||
}
|
||||
else // no VBO support
|
||||
{
|
||||
GetLogger()->Info("OpenGL %d.%d without GL_ARB_vertex_buffer_object, VBO not supported\n", major, minor);
|
||||
GetLogger()->Info("VBO not supported\n");
|
||||
SetVertexBufferType(VBT_DISPLAY_LIST);
|
||||
}
|
||||
}
|
||||
|
@ -275,9 +295,10 @@ bool CGLDevice::Create()
|
|||
|
||||
// To avoid problems with scaling & lighting
|
||||
glEnable(GL_RESCALE_NORMAL);
|
||||
//glEnable(GL_NORMALIZE); // this needs some testing
|
||||
|
||||
// Minimal depth bias to avoid Z-fighting
|
||||
SetDepthBias(0.001f);
|
||||
//SetDepthBias(0.001f);
|
||||
|
||||
// Set just to be sure
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
@ -380,12 +401,6 @@ void CGLDevice::SetTransform(TransformType type, const Math::Matrix &matrix)
|
|||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(m_projectionMat.Array());
|
||||
}
|
||||
else if (type == TRANSFORM_TEXTURE)
|
||||
{
|
||||
m_textureMat = matrix;
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(m_textureMat.Array());
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
|
@ -412,9 +427,9 @@ void CGLDevice::SetMaterial(const Material &material)
|
|||
{
|
||||
m_material = material;
|
||||
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, m_material.ambient.Array());
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, m_material.diffuse.Array());
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, m_material.specular.Array());
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m_material.ambient.Array());
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m_material.diffuse.Array());
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m_material.specular.Array());
|
||||
}
|
||||
|
||||
int CGLDevice::GetMaxLightCount()
|
||||
|
@ -715,6 +730,81 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par
|
|||
return result;
|
||||
}
|
||||
|
||||
Texture CGLDevice::CreateDepthTexture(int width, int height, int depth)
|
||||
{
|
||||
Texture result;
|
||||
|
||||
if (m_shadowMappingSupport == SMS_NONE)
|
||||
{
|
||||
result.id = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
result.alpha = false;
|
||||
result.size.x = width;
|
||||
result.size.y = height;
|
||||
|
||||
// Use & enable 1st texture stage
|
||||
if (m_multitextureAvailable)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glGenTextures(1, &result.id);
|
||||
glBindTexture(GL_TEXTURE_2D, result.id);
|
||||
|
||||
GLuint format = GL_DEPTH_COMPONENT;
|
||||
|
||||
if (m_shadowMappingSupport == SMS_CORE)
|
||||
{
|
||||
switch (depth)
|
||||
{
|
||||
case 16:
|
||||
format = GL_DEPTH_COMPONENT16;
|
||||
break;
|
||||
case 24:
|
||||
format = GL_DEPTH_COMPONENT24;
|
||||
break;
|
||||
case 32:
|
||||
format = GL_DEPTH_COMPONENT32;
|
||||
break;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_DEPTH_COMPONENT, GL_INT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (depth)
|
||||
{
|
||||
case 16:
|
||||
format = GL_DEPTH_COMPONENT16_ARB;
|
||||
break;
|
||||
case 24:
|
||||
format = GL_DEPTH_COMPONENT24_ARB;
|
||||
break;
|
||||
case 32:
|
||||
format = GL_DEPTH_COMPONENT32_ARB;
|
||||
break;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_DEPTH_COMPONENT, GL_INT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||
}
|
||||
|
||||
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 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);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CGLDevice::DestroyTexture(const Texture &texture)
|
||||
{
|
||||
// Unbind the texture if in use anywhere
|
||||
|
@ -833,6 +923,60 @@ void CGLDevice::SetTextureStageParams(int index, const TextureStageParams ¶m
|
|||
UpdateTextureParams(index);
|
||||
}
|
||||
|
||||
void CGLDevice::SetTextureCoordGeneration(int index, TextureGenerationParams ¶ms)
|
||||
{
|
||||
if (!m_multitextureAvailable && index != 0)
|
||||
return;
|
||||
|
||||
if (m_multitextureAvailable)
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
GLuint texCoordGen = textureCoordGen[i];
|
||||
GLuint texCoord = textureCoordinates[i];
|
||||
|
||||
if (params.coords[i].mode == TEX_GEN_NONE)
|
||||
{
|
||||
glDisable(texCoordGen);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(texCoordGen);
|
||||
|
||||
switch (params.coords[i].mode)
|
||||
{
|
||||
case TEX_GEN_OBJECT_LINEAR:
|
||||
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
|
||||
glTexGenfv(texCoord, GL_OBJECT_PLANE, params.coords[i].plane);
|
||||
break;
|
||||
case TEX_GEN_EYE_LINEAR:
|
||||
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
|
||||
glTexGenfv(texCoord, GL_EYE_PLANE, params.coords[i].plane);
|
||||
break;
|
||||
case TEX_GEN_SPHERE_MAP:
|
||||
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
||||
break;
|
||||
case TEX_GEN_NORMAL_MAP:
|
||||
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
|
||||
break;
|
||||
case TEX_GEN_REFLECTION_MAP:
|
||||
glTexGeni(texCoord, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGLDevice::SetTextureMatrix(int index, Math::Matrix& matrix)
|
||||
{
|
||||
if (!m_multitextureAvailable && index != 0)
|
||||
return;
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(matrix.Array());
|
||||
}
|
||||
|
||||
void CGLDevice::UpdateTextureParams(int index)
|
||||
{
|
||||
assert(index >= 0 && index < static_cast<int>( m_currentTextures.size() ));
|
||||
|
@ -851,12 +995,16 @@ void CGLDevice::UpdateTextureParams(int index)
|
|||
|
||||
if (params.wrapS == TEX_WRAP_CLAMP)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
else if (params.wrapS == TEX_WRAP_CLAMP_TO_BORDER)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
else if (params.wrapS == TEX_WRAP_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
else assert(false);
|
||||
|
||||
if (params.wrapT == TEX_WRAP_CLAMP)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
else if (params.wrapT == TEX_WRAP_CLAMP_TO_BORDER)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
else if (params.wrapT == TEX_WRAP_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
else assert(false);
|
||||
|
@ -987,15 +1135,19 @@ void CGLDevice::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wr
|
|||
|
||||
if (m_multitextureAvailable)
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
|
||||
|
||||
if (wrapS == TEX_WRAP_CLAMP)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
else if (wrapS == TEX_WRAP_CLAMP_TO_BORDER)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
else if (wrapS == TEX_WRAP_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
else assert(false);
|
||||
|
||||
if (wrapT == TEX_WRAP_CLAMP)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
else if (wrapT == TEX_WRAP_CLAMP_TO_BORDER)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
else if (wrapT == TEX_WRAP_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
else assert(false);
|
||||
|
@ -1546,6 +1698,11 @@ int CGLDevice::ComputeSphereVisibility(const Math::Vector ¢er, float radius)
|
|||
return result;
|
||||
}
|
||||
|
||||
void CGLDevice::SetViewport(int x, int y, int width, int height)
|
||||
{
|
||||
glViewport(x, y, width, height);
|
||||
}
|
||||
|
||||
void CGLDevice::SetRenderState(RenderState state, bool enabled)
|
||||
{
|
||||
if (state == RENDER_STATE_DEPTH_WRITE)
|
||||
|
@ -1580,6 +1737,7 @@ void CGLDevice::SetRenderState(RenderState state, bool enabled)
|
|||
case RENDER_STATE_DEPTH_TEST: flag = GL_DEPTH_TEST; break;
|
||||
case RENDER_STATE_ALPHA_TEST: flag = GL_ALPHA_TEST; break;
|
||||
case RENDER_STATE_CULLING: flag = GL_CULL_FACE; break;
|
||||
case RENDER_STATE_DEPTH_BIAS: flag = GL_POLYGON_OFFSET_FILL; break;
|
||||
default: assert(false); break;
|
||||
}
|
||||
|
||||
|
@ -1623,14 +1781,19 @@ GLenum TranslateGfxCompFunc(CompFunc func)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CGLDevice::SetColorMask(bool red, bool green, bool blue, bool alpha)
|
||||
{
|
||||
glColorMask(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
void CGLDevice::SetDepthTestFunc(CompFunc func)
|
||||
{
|
||||
glDepthFunc(TranslateGfxCompFunc(func));
|
||||
}
|
||||
|
||||
void CGLDevice::SetDepthBias(float factor)
|
||||
void CGLDevice::SetDepthBias(float factor, float units)
|
||||
{
|
||||
glPolygonOffset(factor, 0.0f);
|
||||
glPolygonOffset(factor, units);
|
||||
}
|
||||
|
||||
void CGLDevice::SetAlphaTestFunc(CompFunc func, float refValue)
|
||||
|
@ -1731,6 +1894,21 @@ void CGLDevice::SetFillMode(FillMode mode)
|
|||
else assert(false);
|
||||
}
|
||||
|
||||
void CGLDevice::CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height)
|
||||
{
|
||||
if (texture.id == 0) return;
|
||||
|
||||
// Use & enable 1st texture stage
|
||||
if (m_multitextureAvailable)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height);
|
||||
|
||||
// Restore previous texture
|
||||
glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
|
||||
}
|
||||
|
||||
void* CGLDevice::GetFrameBufferPixels()const{
|
||||
|
||||
GLubyte* pixels = new GLubyte[4 * m_config.size.x * m_config.size.y];
|
||||
|
|
|
@ -58,6 +58,13 @@ enum VertexBufferType
|
|||
VBT_VBO_ARB //! use ARB extension VBOs
|
||||
};
|
||||
|
||||
enum ShadowMappingSupport
|
||||
{
|
||||
SMS_NONE, //! No support for depth textures
|
||||
SMS_ARB, //! ARB extension
|
||||
SMS_CORE //! Core support
|
||||
};
|
||||
|
||||
/**
|
||||
\struct GLDeviceConfig
|
||||
\brief Additional config with OpenGL-specific settings */
|
||||
|
@ -132,6 +139,7 @@ public:
|
|||
|
||||
virtual Texture CreateTexture(CImage *image, const TextureCreateParams ¶ms) OVERRIDE;
|
||||
virtual Texture CreateTexture(ImageData *data, const TextureCreateParams ¶ms) OVERRIDE;
|
||||
virtual Texture CreateDepthTexture(int width, int height, int depth) OVERRIDE;
|
||||
virtual void DestroyTexture(const Texture &texture) OVERRIDE;
|
||||
virtual void DestroyAllTextures() OVERRIDE;
|
||||
|
||||
|
@ -143,6 +151,8 @@ public:
|
|||
virtual void SetTextureStageParams(int index, const TextureStageParams ¶ms) OVERRIDE;
|
||||
|
||||
virtual void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) OVERRIDE;
|
||||
virtual void SetTextureCoordGeneration(int index, TextureGenerationParams ¶ms) OVERRIDE;
|
||||
virtual void SetTextureMatrix(int index, Math::Matrix& matrix) OVERRIDE;
|
||||
|
||||
virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount,
|
||||
Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) OVERRIDE;
|
||||
|
@ -161,11 +171,15 @@ public:
|
|||
|
||||
virtual int ComputeSphereVisibility(const Math::Vector ¢er, float radius) OVERRIDE;
|
||||
|
||||
virtual void SetViewport(int x, int y, int width, int height) OVERRIDE;
|
||||
|
||||
virtual void SetRenderState(RenderState state, bool enabled) OVERRIDE;
|
||||
|
||||
virtual void SetColorMask(bool red, bool green, bool blue, bool alpha) OVERRIDE;
|
||||
|
||||
virtual void SetDepthTestFunc(CompFunc func) OVERRIDE;
|
||||
|
||||
virtual void SetDepthBias(float factor) OVERRIDE;
|
||||
virtual void SetDepthBias(float factor, float units) OVERRIDE;
|
||||
|
||||
virtual void SetAlphaTestFunc(CompFunc func, float refValue) OVERRIDE;
|
||||
|
||||
|
@ -181,7 +195,9 @@ public:
|
|||
|
||||
virtual void SetShadeModel(ShadeModel model) OVERRIDE;
|
||||
|
||||
virtual void SetFillMode(FillMode mode) OVERRIDE;
|
||||
virtual void SetFillMode(FillMode mode) OVERRIDE;
|
||||
|
||||
virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) OVERRIDE;
|
||||
|
||||
virtual void* GetFrameBufferPixels() const OVERRIDE;
|
||||
|
||||
|
@ -205,8 +221,6 @@ private:
|
|||
Math::Matrix m_modelviewMat;
|
||||
//! Current projection matrix
|
||||
Math::Matrix m_projectionMat;
|
||||
//! Current texture matrix
|
||||
Math::Matrix m_textureMat;
|
||||
|
||||
//! The current material
|
||||
Material m_material;
|
||||
|
@ -245,6 +259,11 @@ private:
|
|||
int vertexCount;
|
||||
};
|
||||
|
||||
//! Detected capabilities
|
||||
//! OpenGL version
|
||||
int m_glMajor, m_glMinor;
|
||||
//! Depth texture support
|
||||
ShadowMappingSupport m_shadowMappingSupport;
|
||||
//! Whether to use multitexturing
|
||||
bool m_multitextureAvailable;
|
||||
//! Whether to use VBOs or display lists
|
||||
|
|
Loading…
Reference in New Issue