renderer: load/unload water textures (similar to alpha maps); do that in delay load and avoid leaking them.
GUIrenderer: add oglSquelchError lib.h: add feq() (checks for floating point equality); remove redundant if from SAFE_DELETE maths: use new feq() Model*RData, VertexArray: fix trivial warnings This was SVN commit r2904.
This commit is contained in:
parent
de5361047a
commit
990e343ae6
@ -129,6 +129,7 @@ void CGameView::RegisterInit(CGameAttributes *pAttribs)
|
||||
RegMemFun(g_TexMan.GetSingletonPtr(), &CTextureManager::LoadTerrainTextures, L"LoadTerrainTextures", 15);
|
||||
RegMemFun(g_ObjMan.GetSingletonPtr(), &CObjectManager::LoadObjects, L"LoadObjects", 1);
|
||||
RegMemFun(g_Renderer.GetSingletonPtr(), &CRenderer::LoadAlphaMaps, L"LoadAlphaMaps", 45);
|
||||
RegMemFun(g_Renderer.GetSingletonPtr(), &CRenderer::LoadWaterTextures, L"LoadWaterTextures", 100);
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,11 +81,11 @@ bool CMaterial::operator ==(const CMaterial &material)
|
||||
|
||||
void CMaterial::Bind()
|
||||
{
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, &m_Diffuse.r);
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, m_SpecularPower);
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, &m_Diffuse.r);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, &m_Ambient.r);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, &m_Specular.r);
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, &m_Emissive.r);
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, m_SpecularPower);
|
||||
|
||||
oglCheck();
|
||||
}
|
||||
|
@ -261,10 +261,6 @@ public:
|
||||
// the number of times the following code is called - it looks like
|
||||
// a rather worrying amount of work for rendering a single button...
|
||||
|
||||
// Also TODO: DOT3_RGB requires GL_(EXT|ARB)_texture_env_dot3. What should
|
||||
// we do if that's not supported? (Probable answer: blindly ignore the problem,
|
||||
// since it's only relevant for TNT2 / RAGE 128 / etc.)
|
||||
|
||||
// Texture unit 0:
|
||||
|
||||
ogl_tex_bind(tex, 0);
|
||||
@ -297,6 +293,16 @@ public:
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
|
||||
|
||||
// GL_DOT3_RGB requires GL_(EXT|ARB)_texture_env_dot3.
|
||||
// We currently don't bother implementing a fallback because it's
|
||||
// only lacking on Riva-class HW, but at least want the rest of the
|
||||
// game to run there without errors. Therefore, squelch the
|
||||
// OpenGL error that's raised if they aren't actually present.
|
||||
// Note: higher-level code checks for this extension, but
|
||||
// allows users the choice of continuing even if not present.
|
||||
oglSquelchError(GL_INVALID_ENUM);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
|
||||
|
@ -53,6 +53,7 @@ scope
|
||||
#define LIB_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <math.h> // fabsf
|
||||
|
||||
|
||||
#include "config.h"
|
||||
@ -213,11 +214,8 @@ STMT(\
|
||||
|
||||
#define SAFE_DELETE(p)\
|
||||
STMT(\
|
||||
if((p))\
|
||||
{\
|
||||
delete (p);\
|
||||
(p) = 0;\
|
||||
}\
|
||||
delete (p); /* if p == 0, delete is a no-op */ \
|
||||
(p) = 0;\
|
||||
)
|
||||
|
||||
|
||||
@ -423,6 +421,16 @@ extern u32 u64_lo(u64 x);
|
||||
extern u64 u64_from_u32(u32 hi, u32 lo);
|
||||
|
||||
|
||||
inline bool feq(float f1, float f2)
|
||||
{
|
||||
// the requisite value will change with the magnitude of f1 and f2!
|
||||
// this is a sane default, but don't use this routine for very
|
||||
// large/small comparands.
|
||||
const float epsilon = 0.00001f;
|
||||
return fabsf(f1 - f2) < epsilon;
|
||||
}
|
||||
|
||||
|
||||
extern u16 fp_to_u16(double in);
|
||||
|
||||
// return random integer in [0, limit).
|
||||
|
@ -539,7 +539,7 @@ static void test_inverse()
|
||||
for (int y = 0; y < 4; ++y)
|
||||
{
|
||||
float expected = (x==y)? 1.0f : 0.0f; // identity should have 1s on diagonal
|
||||
TEST(fabs(m(x,y) - expected) < 0.0001f);
|
||||
TEST(feq(m(x,y), expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -559,19 +559,18 @@ static void test_quats()
|
||||
q.ToMatrix(m);
|
||||
CQuaternion q2 = m.GetRotation();
|
||||
|
||||
float epsilon = 0.0001f;
|
||||
// I hope there's a good reason why they're sometimes negated, and
|
||||
// it's not just a bug...
|
||||
bool ok_oneway =
|
||||
fabs(q2.m_W - q.m_W) < epsilon &&
|
||||
fabs(q2.m_V.X - q.m_V.X) < epsilon &&
|
||||
fabs(q2.m_V.Y - q.m_V.Y) < epsilon &&
|
||||
fabs(q2.m_V.Z - q.m_V.Z) < epsilon;
|
||||
feq(q2.m_W, q.m_W) &&
|
||||
feq(q2.m_V.X, q.m_V.X) &&
|
||||
feq(q2.m_V.Y, q.m_V.Y) &&
|
||||
feq(q2.m_V.Z, q.m_V.Z);
|
||||
bool ok_otherway =
|
||||
fabs(q2.m_W + q.m_W) < epsilon &&
|
||||
fabs(q2.m_V.X + q.m_V.X) < epsilon &&
|
||||
fabs(q2.m_V.Y + q.m_V.Y) < epsilon &&
|
||||
fabs(q2.m_V.Z + q.m_V.Z) < epsilon;
|
||||
feq(q2.m_W, -q.m_W) &&
|
||||
feq(q2.m_V.X, -q.m_V.X) &&
|
||||
feq(q2.m_V.Y, -q.m_V.Y) &&
|
||||
feq(q2.m_V.Z, -q.m_V.Z);
|
||||
TEST(ok_oneway ^ ok_otherway);
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ void CModelDefRData::PrepareStream(uint streamflags)
|
||||
return;
|
||||
|
||||
u8* base = m_Array.Bind();
|
||||
size_t stride = m_Array.GetStride();
|
||||
GLsizei stride = (GLsizei)m_Array.GetStride();
|
||||
|
||||
glTexCoordPointer(2, GL_FLOAT, stride, base + m_UV.offset);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include "MathUtil.h"
|
||||
#include "lib/ogl.h"
|
||||
#include "lib/res/graphics/ogl_tex.h"
|
||||
#include "lib/res/graphics/ogl_shader.h"
|
||||
#include "Renderer.h"
|
||||
@ -284,7 +285,7 @@ void CModelRData::FinishRender(u32 streamflags)
|
||||
// Try to use RenderModels instead wherever possible.
|
||||
// Must be bracketed by calls to CModelRData::SetupRender/FinishRender
|
||||
void CModelRData::RenderStreams(u32 streamflags, int tmus)
|
||||
{
|
||||
{
|
||||
CModelDefPtr mdldef=m_Model->GetModelDef();
|
||||
|
||||
if (streamflags & STREAM_UV0)
|
||||
@ -299,7 +300,7 @@ void CModelRData::RenderStreams(u32 streamflags, int tmus)
|
||||
}
|
||||
|
||||
u8* base = m_DynamicArray.Bind();
|
||||
size_t stride = m_DynamicArray.GetStride();
|
||||
GLsizei stride = (GLsizei)m_DynamicArray.GetStride();
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, stride, base + m_Position.offset);
|
||||
if (streamflags & STREAM_COLOR)
|
||||
@ -432,7 +433,7 @@ void CModelRData::RenderModels(u32 streamflags, u32 flags)
|
||||
CModelDefPtr mdldef = modeldata->GetModel()->GetModelDef();
|
||||
|
||||
u8* base = modeldata->m_DynamicArray.Bind();
|
||||
size_t stride = modeldata->m_DynamicArray.GetStride();
|
||||
GLsizei stride = (GLsizei)modeldata->m_DynamicArray.GetStride();
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, stride,
|
||||
base + modeldata->m_Position.offset);
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "lib/res/file/file.h"
|
||||
#include "lib/res/graphics/tex.h"
|
||||
#include "lib/res/graphics/ogl_tex.h"
|
||||
#include "lib/res/file/vfs.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "renderer/RenderPathVertexShader.h"
|
||||
@ -74,13 +75,13 @@ CRenderer::CRenderer()
|
||||
m_ActiveTextures[i]=0;
|
||||
}
|
||||
|
||||
// water
|
||||
m_RenderWater = true;
|
||||
m_WaterHeight = 5.0f;
|
||||
m_WaterColor = CColor(0.3f, 0.35f, 0.7f, 1.0f);
|
||||
m_WaterFullDepth = 4.0f;
|
||||
m_WaterMaxAlpha = 0.85f;
|
||||
m_WaterAlphaOffset = -0.05f;
|
||||
|
||||
m_SWaterTrans=0;
|
||||
m_TWaterTrans=0;
|
||||
m_SWaterSpeed=0.0015f;
|
||||
@ -89,20 +90,6 @@ CRenderer::CRenderer()
|
||||
m_TWaterScrollCounter=0;
|
||||
m_WaterCurrentTex=0;
|
||||
|
||||
for (int x=0; x<60; x++)
|
||||
{
|
||||
char waterName[1000];
|
||||
sprintf(waterName, "art/textures/terrain/types/water/animation2/water%02d.dds", x+1);
|
||||
m_WaterTexture[x]=ogl_tex_load(waterName);
|
||||
if (m_WaterTexture[x] <= 0)
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "LoadTexture failed on \"%s\"", waterName);
|
||||
ogl_tex_free(m_WaterTexture[x]);
|
||||
}
|
||||
else
|
||||
ogl_tex_upload(m_WaterTexture[x]);
|
||||
}
|
||||
|
||||
ONCE( ScriptingInit(); );
|
||||
}
|
||||
|
||||
@ -112,6 +99,9 @@ CRenderer::~CRenderer()
|
||||
{
|
||||
delete m_VertexShader;
|
||||
m_VertexShader = 0;
|
||||
|
||||
UnloadAlphaMaps();
|
||||
UnloadWaterTextures();
|
||||
}
|
||||
|
||||
|
||||
@ -737,6 +727,7 @@ void CRenderer::RenderShadowMap()
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
oglSquelchError(GL_INVALID_ENUM);
|
||||
|
||||
// Set the proper LOD bias
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, m_Options.m_LodBias);
|
||||
@ -1377,7 +1368,7 @@ int CRenderer::LoadAlphaMaps()
|
||||
{
|
||||
(void)pp_append_file(&pp, fnames[i]);
|
||||
textures[i] = ogl_tex_load(pp.path);
|
||||
WARN_ERR(textures[i]);
|
||||
RETURN_ERR(textures[i]);
|
||||
|
||||
// get its size and make sure they are all equal.
|
||||
// (the packing algo assumes this)
|
||||
@ -1452,10 +1443,10 @@ int CRenderer::LoadAlphaMaps()
|
||||
m_hCompositeAlphaMap = ogl_tex_wrap(&t, "(alpha map composite)");
|
||||
(void)ogl_tex_set_filter(m_hCompositeAlphaMap, GL_LINEAR);
|
||||
(void)ogl_tex_set_wrap (m_hCompositeAlphaMap, GL_CLAMP_TO_EDGE);
|
||||
(void)ogl_tex_upload(m_hCompositeAlphaMap, 0, 0, GL_INTENSITY);
|
||||
int ret = ogl_tex_upload(m_hCompositeAlphaMap, 0, 0, GL_INTENSITY);
|
||||
delete[] data;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1466,6 +1457,45 @@ void CRenderer::UnloadAlphaMaps()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int CRenderer::LoadWaterTextures()
|
||||
{
|
||||
int i;
|
||||
|
||||
// initialize to 0 in case something fails below
|
||||
// (we then abort the loop, but don't want undefined values in here)
|
||||
for (i = 0; i < ARRAY_SIZE(m_WaterTexture); i++)
|
||||
m_WaterTexture[i] = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(m_WaterTexture); i++)
|
||||
{
|
||||
char waterName[VFS_MAX_PATH];
|
||||
// TODO: add a member variable and setter for this. (can't make this
|
||||
// a parameter because this function is called via delay-load code)
|
||||
const char* water_type = "animation2";
|
||||
snprintf(waterName, ARRAY_SIZE(waterName), "art/textures/terrain/types/water/%s/water%02d.dds", water_type, i+1);
|
||||
Handle ht = ogl_tex_load(waterName);
|
||||
if (ht <= 0)
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "LoadWaterTextures failed on \"%s\"", waterName);
|
||||
return ht;
|
||||
}
|
||||
m_WaterTexture[i]=ht;
|
||||
RETURN_ERR(ogl_tex_upload(ht));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CRenderer::UnloadWaterTextures()
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(m_WaterTexture); i++)
|
||||
ogl_tex_free(m_WaterTexture[i]);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Scripting Interface
|
||||
|
||||
|
@ -246,11 +246,18 @@ public:
|
||||
// query transparency of given texture
|
||||
bool IsTextureTransparent(CTexture* texture);
|
||||
|
||||
// load the default set of alphamaps; return false if any alphamap fails to load, true otherwise
|
||||
// load the default set of alphamaps.
|
||||
// return a negative error code if anything along the way fails.
|
||||
// called via delay-load mechanism.
|
||||
int LoadAlphaMaps();
|
||||
|
||||
void UnloadAlphaMaps();
|
||||
|
||||
// load textures for the active water type.
|
||||
// return a negative error code if anything along the way fails.
|
||||
// called via delay-load mechanism.
|
||||
int LoadWaterTextures();
|
||||
void UnloadWaterTextures();
|
||||
|
||||
// return stats accumulated for current frame
|
||||
const Stats& GetStats() { return m_Stats; }
|
||||
|
||||
|
@ -151,13 +151,19 @@ void VertexArray::Layout()
|
||||
continue;
|
||||
|
||||
size_t attrSize = 0;
|
||||
|
||||
switch(attr->type) {
|
||||
case GL_UNSIGNED_BYTE: attrSize = sizeof(GLubyte); break;
|
||||
case GL_FLOAT: attrSize = sizeof(GLfloat); break;
|
||||
default: debug_warn("Bad AttributeInfo::Type"); break;
|
||||
switch(attr->type)
|
||||
{
|
||||
case GL_UNSIGNED_BYTE:
|
||||
attrSize = sizeof(GLubyte);
|
||||
break;
|
||||
case GL_FLOAT:
|
||||
attrSize = sizeof(GLfloat);
|
||||
break;
|
||||
default:
|
||||
attrSize = 0;
|
||||
debug_warn("Bad AttributeInfo::Type"); break;
|
||||
}
|
||||
|
||||
|
||||
attrSize *= attr->elems;
|
||||
|
||||
attr->offset = m_Stride;
|
||||
|
Loading…
Reference in New Issue
Block a user