1
0
forked from 0ad/0ad

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:
janwas 2005-10-12 04:16:41 +00:00
parent de5361047a
commit 990e343ae6
10 changed files with 109 additions and 51 deletions

View File

@ -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);
}

View File

@ -81,11 +81,11 @@ bool CMaterial::operator ==(const CMaterial &material)
void CMaterial::Bind()
{
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();
}

View File

@ -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);

View File

@ -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);\
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).

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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"
@ -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);

View File

@ -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

View File

@ -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; }

View File

@ -151,11 +151,17 @@ 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;