229 lines
6.2 KiB
C++
Executable File
229 lines
6.2 KiB
C++
Executable File
//-----------------------------------------------
|
|
// Synapse Gaming - Lighting System
|
|
// Copyright © Synapse Gaming 2003
|
|
// Written by John Kabus
|
|
//-----------------------------------------------
|
|
#include "lightingSystem/sgLighting.h"
|
|
#include "game/fx/particleEngine.h"
|
|
#include "console/consoleTypes.h"
|
|
#include "core/bitStream.h"
|
|
#include "game/gameConnection.h"
|
|
#include "sceneGraph/sceneGraph.h"
|
|
#include "sim/netConnection.h"
|
|
#include "dgl/materialPropertyMap.h"
|
|
#include "lightingSystem/sgDetailMapping.h"
|
|
|
|
|
|
void sgDetailMapping::sgInitDetailMapping(MaterialList *materials)
|
|
{
|
|
sgClearDetailMapping();
|
|
|
|
// need this for DX to GL switch...
|
|
sgMaterialsCache = materials;
|
|
|
|
if(!LightManager::sgAllowDetailMaps())
|
|
return;
|
|
|
|
GBitmap *b = new GBitmap(2, 2);
|
|
U8 *bits = b->getWritableBits();
|
|
dMemset(bits, 127, b->byteSize);
|
|
sgWhiteTexture = new TextureHandle(NULL, b);
|
|
|
|
|
|
MaterialPropertyMap *materialprops = static_cast<MaterialPropertyMap *>(Sim::findObject("MaterialPropertyMap"));
|
|
sgDetailMaps.setSize(materials->getMaterialCount());
|
|
|
|
for(U32 i=0; i<materials->getMaterialCount(); i++)
|
|
{
|
|
const char* name = materials->getMaterialName(i);
|
|
const MaterialPropertyMap::MapEntry* entry = materialprops->getMapEntry(name);
|
|
|
|
// init this to NULL...
|
|
sgDetailMaps[i] = NULL;
|
|
|
|
// try to fill it out now...
|
|
if((entry == NULL) || (entry->detailMapName == NULL))
|
|
continue;
|
|
|
|
// we're doing this by hand - Torque gives you no contol over mipmaps...
|
|
// load the texture...
|
|
GBitmap *bitmap = TextureManager::loadBitmapInstance(entry->detailMapName);
|
|
if(!bitmap)
|
|
continue;
|
|
|
|
// make a deletable copy and use it to create the texture...
|
|
// need to do this because BitmapTexture doesn't create mips (so refresh fails)...
|
|
//GBitmap *bitmapcopy = new GBitmap(*bitmap);
|
|
//TextureHandle *texture = new TextureHandle(NULL, bitmapcopy, DetailTexture);
|
|
//TextureHandle *texture = new TextureHandle(NULL, bitmap);
|
|
|
|
// manually extrude the original...
|
|
bitmap->extrudeMipLevels();
|
|
|
|
// fix the levels...
|
|
F32 scale = (2.0f / F32(bitmap->getNumMipLevels()));
|
|
F32 currentscale = 1.0f;
|
|
for(U32 m=0; m<bitmap->getNumMipLevels(); m++)
|
|
{
|
|
for(U32 y=0; y<bitmap->getHeight(m); y++)
|
|
{
|
|
for(U32 x=0; x<bitmap->getWidth(m); x++)
|
|
{
|
|
// this is ugly, but it only happens on load...
|
|
U8 *bits = bitmap->getAddress(x, y, m);
|
|
|
|
F32 bit = bits[0];
|
|
bits[0] = U8(((bit - 127.0f) * currentscale) + 127.0f);
|
|
|
|
bit = bits[1];
|
|
bits[1] = U8(((bit - 127.0f) * currentscale) + 127.0f);
|
|
|
|
bit = bits[2];
|
|
bits[2] = U8(((bit - 127.0f) * currentscale) + 127.0f);
|
|
}
|
|
}
|
|
currentscale -= scale;
|
|
currentscale = mClampF(currentscale, 0.0f, 1.0f);
|
|
}
|
|
|
|
// assign the bitmap...
|
|
//TextureObject *obj = *texture;
|
|
//obj->bitmap = bitmap;
|
|
|
|
//obj->type = DetailTexture;
|
|
|
|
// refresh...
|
|
//texture->refresh();
|
|
TextureHandle *texture = new TextureHandle(NULL, bitmap);
|
|
|
|
// unlink and delete...
|
|
//obj->bitmap = NULL;
|
|
//delete bitmap;
|
|
|
|
// keep link and set to keep texture (for DX/GL switch)...
|
|
//obj->type = BitmapKeepTexture;
|
|
|
|
// finally done...
|
|
sgDetailMaps[i] = texture;
|
|
}
|
|
}
|
|
|
|
void sgDetailMapping::sgBindDetailMap(U32 surfaceindex)
|
|
{
|
|
if(!LightManager::sgAllowDetailMaps())
|
|
return;
|
|
|
|
// DX to GL switch?
|
|
if((sgDetailMaps.size() == 0) && (sgMaterialsCache))
|
|
{
|
|
sgInitDetailMapping(sgMaterialsCache);
|
|
// don't want to go through that again...
|
|
sgMaterialsCache = NULL;
|
|
}
|
|
|
|
// bailout...
|
|
if(sgDetailMaps.size() <= surfaceindex)
|
|
return;
|
|
|
|
AssertFatal((sgDetailMaps.size() > surfaceindex), "Invalid surface index while detail mapping.");
|
|
TextureHandle *texture = sgDetailMaps[surfaceindex];
|
|
|
|
glActiveTextureARB(GL_TEXTURE2_ARB);
|
|
if(!texture)
|
|
glBindTexture(GL_TEXTURE_2D, sgWhiteTexture->getGLName());
|
|
else
|
|
glBindTexture(GL_TEXTURE_2D, texture->getGLName());
|
|
|
|
glActiveTextureARB(GL_TEXTURE3_ARB);
|
|
if(!texture)
|
|
glBindTexture(GL_TEXTURE_2D, sgWhiteTexture->getGLName());
|
|
else
|
|
glBindTexture(GL_TEXTURE_2D, texture->getGLName());
|
|
}
|
|
|
|
void sgDetailMapping::sgClearDetailMapping()
|
|
{
|
|
sgMaterialsCache = NULL;
|
|
|
|
if(sgWhiteTexture)
|
|
{
|
|
delete sgWhiteTexture;
|
|
sgWhiteTexture = NULL;
|
|
}
|
|
for(U32 i=0; i<sgDetailMaps.size(); i++)
|
|
delete sgDetailMaps[i];
|
|
sgDetailMaps.clear();
|
|
}
|
|
|
|
void sgDetailMapping::sgEnableDetailMapping(void *buffer, U32 elementsize)
|
|
{
|
|
if(!LightManager::sgAllowDetailMaps())
|
|
return;
|
|
|
|
const F32 scale[16] = {4.0, 0.0, 0.0, 0.0,
|
|
0.0, 4.0, 0.0, 0.0,
|
|
0.0, 0.0, 4.0, 0.0,
|
|
0.0, 0.0, 0.0, 1.0};
|
|
|
|
const F32 scaleX4[16] = {8.0, 0.0, 0.0, 0.0,
|
|
0.0, 8.0, 0.0, 0.0,
|
|
0.0, 0.0, 8.0, 0.0,
|
|
0.0, 0.0, 0.0, 1.0};
|
|
|
|
glActiveTextureARB(GL_TEXTURE2_ARB);
|
|
glEnable(GL_TEXTURE_2D);
|
|
LightManager::sgSetupExposureRendering();
|
|
glMatrixMode(GL_TEXTURE);
|
|
glPushMatrix();
|
|
glMultMatrixf(scale);
|
|
|
|
glActiveTextureARB(GL_TEXTURE3_ARB);
|
|
//glDisable(GL_TEXTURE_2D);
|
|
glEnable(GL_TEXTURE_2D);
|
|
LightManager::sgSetupExposureRendering();
|
|
glMatrixMode(GL_TEXTURE);
|
|
glPushMatrix();
|
|
glMultMatrixf(scaleX4);
|
|
|
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
|
|
|
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glTexCoordPointer(2, GL_FLOAT, elementsize, buffer);
|
|
|
|
glClientActiveTextureARB(GL_TEXTURE3_ARB);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glTexCoordPointer(2, GL_FLOAT, elementsize, buffer);
|
|
|
|
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
|
}
|
|
|
|
void sgDetailMapping::sgDisableDetailMapping()
|
|
{
|
|
if(!LightManager::sgAllowDetailMaps())
|
|
return;
|
|
|
|
glClientActiveTextureARB(GL_TEXTURE3_ARB);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
|
|
|
glActiveTextureARB(GL_TEXTURE3_ARB);
|
|
glMatrixMode(GL_TEXTURE);
|
|
glPopMatrix();
|
|
LightManager::sgResetExposureRendering();
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glActiveTextureARB(GL_TEXTURE2_ARB);
|
|
glMatrixMode(GL_TEXTURE);
|
|
glPopMatrix();
|
|
LightManager::sgResetExposureRendering();
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
|
}
|
|
|