tge/engine/interior/interiorRender.cc
2025-02-17 23:17:30 -06:00

1543 lines
54 KiB
C++
Executable File

//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "interior/interior.h"
#include "sceneGraph/sceneState.h"
#include "sceneGraph/sceneGraph.h"
#include "sceneGraph/lightManager.h"
#include "dgl/dgl.h"
#include "dgl/gBitmap.h"
#include "dgl/gTexManager.h"
#include "math/mMatrix.h"
#include "math/mRect.h"
#include "dgl/materialList.h"
#include "dgl/materialPropertyMap.h"
#include "interior/interiorSubObject.h"
#include "core/bitVector.h"
#include "dgl/stripCache.h"
#include "platform/profiler.h"
//!!!!!!!TBD -- there should be a platform fn called memMove!
#include <string.h>
extern bool sgFogActive;
extern U16* sgActivePolyList;
extern U32 sgActivePolyListSize;
extern U16* sgFogPolyList;
extern U32 sgFogPolyListSize;
extern U16* sgEnvironPolyList;
extern U32 sgEnvironPolyListSize;
Point3F sgOSCamPosition;
#include "interior/itf.h" // render data structs and processing fns.
OutputPoint sgRenderBuffer[512];
U32 sgRenderIndices[2048];
U32 csgNumAllowedPoints = 256;
extern "C" {
F32 texGen0[8];
F32 texGen1[8];
Point2F *fogCoordinatePointer;
}
void emitPrimitive(OutputPoint* renderBuffer,
U32* renderIndices,
const U32* winding,
const U32 numPoints,
const U32 offset,
ItrPaddedPoint* srcPoints)
{
U32 currIndex = 0;
U32 last = 2;
while (last < numPoints)
{
// First
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 0;
last++;
if (last == numPoints)
break;
// Second
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 0;
last++;
}
processTriFan(renderBuffer,
srcPoints,
winding,
numPoints);
}
void emitPrimitiveFC_VB(OutputPointFC_VB* renderBuffer,
U32* renderIndices,
const U32* winding,
const U32 numPoints,
const U32 offset,
ItrPaddedPoint* srcPoints)
{
U32 currIndex = 0;
U32 last = 2;
while (last < numPoints)
{
// First
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 0;
last++;
if (last == numPoints)
break;
// Second
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 0;
last++;
}
processTriFanFC_VB(renderBuffer,
srcPoints,
winding,
numPoints);
}
void emitPrimitiveSP(OutputPoint* renderBuffer,
U32* renderIndices,
const U32* winding,
const U32 numPoints,
const U32 offset,
ItrPaddedPoint* srcPoints,
const ColorI* srcColors)
{
U32 currIndex = 0;
U32 last = 2;
while (last < numPoints)
{
// First
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 0;
last++;
if (last == numPoints)
break;
// Second
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 0;
last++;
}
processTriFanSP(renderBuffer,
srcPoints,
winding, numPoints,
srcColors);
}
void emitPrimitiveVC_TF(OutputPoint* renderBuffer,
U32* renderIndices,
const U32* winding,
const U32 numPoints,
const U32 offset,
ItrPaddedPoint* srcPoints,
const ColorI* srcColors)
{
U32 currIndex = 0;
U32 last = 2;
while (last < numPoints)
{
// First
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 0;
last++;
if (last == numPoints)
break;
// Second
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 0;
last++;
}
processTriFanVC_TF(renderBuffer,
srcPoints,
winding,
numPoints,
srcColors);
}
void emitPrimitiveSP_FC(OutputPoint* renderBuffer,
U32* renderIndices,
const U32* winding,
const U32 numPoints,
const U32 offset,
ItrPaddedPoint* srcPoints,
const ColorI* srcColors)
{
U32 currIndex = 0;
U32 last = 2;
while (last < numPoints)
{
// First
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 0;
last++;
if (last == numPoints)
break;
// Second
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 0;
last++;
}
processTriFanSP_FC(renderBuffer,
srcPoints,
winding, numPoints,
srcColors);
}
void emitPrimitiveSP_FC_VB(OutputPointSP_FC_VB* renderBuffer,
U32* renderIndices,
const U32* winding,
const U32 numPoints,
const U32 offset,
ItrPaddedPoint* srcPoints,
const ColorI* srcColors)
{
U32 currIndex = 0;
U32 last = 2;
while (last < numPoints)
{
// First
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 0;
last++;
if (last == numPoints)
break;
// Second
renderIndices[currIndex++] = offset + last - 1;
renderIndices[currIndex++] = offset + last - 2;
renderIndices[currIndex++] = offset + last - 0;
last++;
}
processTriFanSP_FC_VB(renderBuffer,
srcPoints,
winding,
numPoints,
srcColors);
}
void flushPrimitives(const U32* indices,
const U32 count,
const U32 vcount)
{
if (count == 0)
return;
if (Interior::smLockArrays && dglDoesSupportCompiledVertexArray())
{
glLockArraysEXT(0, vcount);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, indices);
glUnlockArraysEXT();
} else {
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, indices);
}
}
void flushPrimitivesVB(const U32* indices,
const U32 count,
const U32 vcount,
const S32 handle)
{
if (count == 0)
return;
glSetVertexBufferEXT(handle);
if (Interior::smLockArrays && dglDoesSupportCompiledVertexArray())
{
glLockArraysEXT(0, vcount);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, indices);
glUnlockArraysEXT();
} else {
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, indices);
}
}
//} // namespace {}
//--------------------------------------------------------------------------
void Interior::setupFog(SceneState* state)
{
if (sgFogActive)
{
if (useFogCoord())
{
glEnable(GL_FOG);
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
GLfloat fogColor[4];
fogColor[0] = state->getFogColor().red;
fogColor[1] = state->getFogColor().green;
fogColor[2] = state->getFogColor().blue;
fogColor[3] = 1.0f;
glFogfv(GL_FOG_COLOR, fogColor);
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, 0.0f);
glFogf(GL_FOG_END, 1.0f);
}
}
}
void Interior::clearFog()
{
if (sgFogActive)
{
if (useFogCoord())
{
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
glDisable(GL_FOG);
}
}
}
void Interior::setOSCamPosition(const Point3F& pos)
{
sgOSCamPosition = pos;
}
//------------------------------------------------------------------------------
void Interior::render(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE instanceHandle,
const Vector<ColorI>* normalVLights,
const Vector<ColorI>* alarmVLights)
{
if (smRenderMode != 0)
{
PROFILE_START(IRO_DebugRender);
debugRender(pMaterials, instanceHandle);
PROFILE_END();
return;
}
if (dglDoesSupportARBMultitexture())
{
if (smUseVertexLighting == false)
{
if (useFogCoord())
{
PROFILE_START(IRO_RenderARB_FC);
renderARB_FC(useAlarmLighting, pMaterials, instanceHandle);
PROFILE_END();
}
else
{
PROFILE_START(IRO_RenderARB);
renderARB(useAlarmLighting, pMaterials, instanceHandle);
PROFILE_END();
}
}
else
{
if (useFogCoord())
{
PROFILE_START(IRO_Render_VC_FC);
render_vc_fc(useAlarmLighting, pMaterials, instanceHandle, normalVLights, alarmVLights);
PROFILE_END();
}
else
{
PROFILE_START(IRO_Render_VC_TF);
render_vc_tf(useAlarmLighting, pMaterials, instanceHandle, normalVLights, alarmVLights);
PROFILE_END();
}
}
}
else
{
if (useFogCoord())
{
PROFILE_START(IRO_Render_VC_FC);
render_vc_fc(useAlarmLighting, pMaterials, instanceHandle, normalVLights, alarmVLights);
PROFILE_END();
}
else
{
PROFILE_START(Render_VC_TF);
render_vc_tf(useAlarmLighting, pMaterials, instanceHandle, normalVLights, alarmVLights);
PROFILE_END();
}
}
}
//------------------------------------------------------------------------------
void Interior::render_vc_tf(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE,
const Vector<ColorI>* normalVLights,
const Vector<ColorI>* alarmVLights)
{
const Vector<ColorI>* pVertexColors = useAlarmLighting ? alarmVLights : normalVLights;
OutputPoint* pFirstOutputPoint = (OutputPoint*)sgRenderBuffer;
U32 currRenderBufferPoint = 0;
U32 currIndexPoint = 0;
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_ONE, GL_ZERO);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->point);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->texCoord);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(OutputPoint), &pFirstOutputPoint->fogColor[0]);
// Ok, our verts are set up, draw our polys.
U32 currentlyBound = U32(-1);
U32 currentTexGen = U32(-1);
// Draw the polys!
U32 i;
for (i = 0; i < sgActivePolyListSize; i++) {
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
// Setup the base texture...
U32 baseName = pMaterials->getMaterial(rSurface.textureIndex).getGLName();
if (baseName != currentlyBound) {
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound = baseName;
}
if (currRenderBufferPoint + rSurface.windingCount >= 512 ||
currIndexPoint + (rSurface.windingCount - 2) * 3 >= 2048) {
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
}
if (rSurface.texGenIndex != currentTexGen)
{
currentTexGen = rSurface.texGenIndex;
memcpy(texGen0, &mTexGenEQs[rSurface.texGenIndex], sizeof(F32)*8);
}
emitPrimitiveSP(&sgRenderBuffer[currRenderBufferPoint],
&sgRenderIndices[currIndexPoint],
&mWindings[rSurface.windingStart],
rSurface.windingCount,
currRenderBufferPoint,
&mPoints[0],
&((*pVertexColors)[rSurface.windingStart]));
currRenderBufferPoint += rSurface.windingCount;
currIndexPoint += (rSurface.windingCount - 2) * 3;
AssertFatal(currRenderBufferPoint < 512 && currIndexPoint < 2048, "Aw, crap.1");
}
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
glDisableClientState(GL_COLOR_ARRAY);
if (sgFogActive) {
extern Point2F* sgFogTexCoords;
glVertexPointer(3, GL_FLOAT, sizeof(ItrPaddedPoint), &mPoints[0].point);
glTexCoordPointer(2, GL_FLOAT, sizeof(Point2F), sgFogTexCoords);
glBindTexture(GL_TEXTURE_2D, gClientSceneGraph->getFogTexture().getGLName());
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
extern ColorF gInteriorFogColor;
glColor4f(gInteriorFogColor.red,
gInteriorFogColor.green,
gInteriorFogColor.blue,
1);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1,-1);
if (dglDoesSupportCompiledVertexArray())
glLockArraysEXT(0, mPoints.size());
for (U32 i = 0; i < sgActivePolyListSize; i++) {
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
glDrawElements(GL_TRIANGLE_STRIP, rSurface.windingCount, GL_UNSIGNED_INT, &mWindings[rSurface.windingStart]);
}
if (dglDoesSupportCompiledVertexArray())
glUnlockArraysEXT();
glDisable(GL_POLYGON_OFFSET_FILL);
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
}
//------------------------------------------------------------------------------
void Interior::render_vc_fc(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE,
const Vector<ColorI>* normalVLights,
const Vector<ColorI>* alarmVLights)
{
const Vector<ColorI>* pVertexColors = useAlarmLighting ? alarmVLights : normalVLights;
OutputPoint* pFirstOutputPoint = (OutputPoint*)sgRenderBuffer;
U32 currRenderBufferPoint = 0;
U32 currIndexPoint = 0;
bool supportBuffers;
GLint bufferHandle;
OutputPointSP_FC_VB *vertexBuffer = NULL;
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_ONE, GL_ZERO);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->point);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->texCoord);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(OutputPoint), &pFirstOutputPoint->fogColor[0]);
if (sgFogActive) {
// Need the fog coord pointer enabled here...
glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
glFogCoordPointerEXT(GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->lmCoord.x);
}
// Ok, our verts are set up, draw our polys.
U32 currentlyBound = U32(-1);
U32 currentTexGen = U32(-1);
if ((supportBuffers = dglDoesSupportVertexBuffer()) == true)
{
bufferHandle = gInteriorLMManager.getVertexBuffer(GL_V12FTVFMT_EXT);
// guess we ran out of video memory
if (bufferHandle == -1)
supportBuffers = false;
}
// Draw the polys!
U32 i;
for (i = 0; i < sgActivePolyListSize; i++) {
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
// Setup the base texture...
U32 baseName = pMaterials->getMaterial(rSurface.textureIndex).getGLName();
if (baseName != currentlyBound) {
if (supportBuffers)
{
if (vertexBuffer)
glUnlockVertexBufferEXT(bufferHandle);
flushPrimitivesVB(sgRenderIndices, currIndexPoint, currRenderBufferPoint, bufferHandle);
vertexBuffer = (OutputPointSP_FC_VB *) glLockVertexBufferEXT(bufferHandle,512);
}
else
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound = baseName;
}
if (currRenderBufferPoint + rSurface.windingCount >= 512 ||
currIndexPoint + (rSurface.windingCount - 2) * 3 >= 2048) {
if (supportBuffers)
{
if (vertexBuffer)
glUnlockVertexBufferEXT(bufferHandle);
flushPrimitivesVB(sgRenderIndices, currIndexPoint, currRenderBufferPoint, bufferHandle);
vertexBuffer = (OutputPointSP_FC_VB *) glLockVertexBufferEXT(bufferHandle,512);
}
else
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
}
if (rSurface.texGenIndex != currentTexGen)
{
currentTexGen = rSurface.texGenIndex;
memcpy(texGen0, &mTexGenEQs[rSurface.texGenIndex], sizeof(F32)*8);
}
if (supportBuffers)
emitPrimitiveSP_FC_VB(&vertexBuffer[currRenderBufferPoint],
&sgRenderIndices[currIndexPoint],
&mWindings[rSurface.windingStart],
rSurface.windingCount,
currRenderBufferPoint,
&mPoints[0],
&((*pVertexColors)[rSurface.windingStart]));
else
emitPrimitiveSP_FC(&sgRenderBuffer[currRenderBufferPoint],
&sgRenderIndices[currIndexPoint],
&mWindings[rSurface.windingStart],
rSurface.windingCount,
currRenderBufferPoint,
&mPoints[0],
&((*pVertexColors)[rSurface.windingStart]));
currRenderBufferPoint += rSurface.windingCount;
currIndexPoint += (rSurface.windingCount - 2) * 3;
AssertFatal(currRenderBufferPoint < 512 && currIndexPoint < 2048, "Aw, crap.2");
}
if (supportBuffers)
{
if (vertexBuffer)
glUnlockVertexBufferEXT(bufferHandle);
flushPrimitivesVB(sgRenderIndices, currIndexPoint, currRenderBufferPoint, bufferHandle);
}
else
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
if (sgFogActive) {
// Need the fog coord pointer enabled here...
glDisableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
}
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
}
void Interior::renderARB_vc_tf(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE,
const Vector<ColorI>* normalVLights,
const Vector<ColorI>* alarmVLights)
{
// DMMNOTE: NON-FUNCTIONAL ON THE GEFORCE! DO NOT PUT IN RENDER FUNCTION!!!
// DMMNOTE: NON-FUNCTIONAL ON THE GEFORCE! DO NOT PUT IN RENDER FUNCTION!!!
// DMMNOTE: NON-FUNCTIONAL ON THE GEFORCE! DO NOT PUT IN RENDER FUNCTION!!!
U32 i;
const Vector<ColorI>* pVertexColors = useAlarmLighting ? alarmVLights : normalVLights;
extern Point2F* sgFogTexCoords;
fogCoordinatePointer = sgFogTexCoords;
OutputPoint* pFirstOutputPoint = (OutputPoint*)sgRenderBuffer;
U32 currRenderBufferPoint = 0;
U32 currIndexPoint = 0;
// Base textures
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, gClientSceneGraph->getFogTexture().getGLName());
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->point);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(OutputPoint), &pFirstOutputPoint->fogColor[0]);
// // Fog texture
// if (sgFogActive)
// {
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->texCoord);
// glClientActiveTextureARB(GL_TEXTURE0_ARB);
// }
// else
// {
// glActiveTextureARB(GL_TEXTURE1_ARB);
// glDisable(GL_TEXTURE_2D);
// glClientActiveTextureARB(GL_TEXTURE1_ARB);
// glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// }
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->lmCoord);
// Misc setup
glBlendFunc(GL_ONE, GL_ZERO);
glActiveTextureARB(GL_TEXTURE0_ARB);
// Ok, our verts are set up, draw our polys.
U32 currentlyBound = U32(-1);
U32 currentTexGen = U32(-1);
// Draw the polys!
glColor4f(1, 1, 1, 1);
for (i = 0; i < sgActivePolyListSize; i++) {
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
// Setup the base texture...
U32 baseName = pMaterials->getMaterial(rSurface.textureIndex).getGLName();
if (baseName != currentlyBound) {
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound = baseName;
}
if (currRenderBufferPoint + rSurface.windingCount >= 512 ||
currIndexPoint + (rSurface.windingCount - 2) * 3 >= 2048) {
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
}
if (rSurface.texGenIndex != currentTexGen)
{
currentTexGen = rSurface.texGenIndex;
memcpy(texGen0, &mTexGenEQs[rSurface.texGenIndex], sizeof(F32)*8);
}
emitPrimitiveVC_TF(&sgRenderBuffer[currRenderBufferPoint],
&sgRenderIndices[currIndexPoint],
&mWindings[rSurface.windingStart],
rSurface.windingCount,
currRenderBufferPoint,
&mPoints[0],
&((*pVertexColors)[rSurface.windingStart]));
currRenderBufferPoint += rSurface.windingCount;
currIndexPoint += (rSurface.windingCount - 2) * 3;
AssertFatal(currRenderBufferPoint < 512 && currIndexPoint < 2048, "Aw, crap.3");
}
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
}
/*void Interior::renderSimple(MaterialList* pMaterials)
{
U32 i;
OutputPoint* pFirstOutputPoint = (OutputPoint*)sgRenderBuffer;
U32 currRenderBufferPoint = 0;
U32 currIndexPoint = 0;
// Set up texturing
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Set up our pointers...
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->point);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->texCoord);
// Ok, our verts are set up, draw our polys.
U32 currentlyBound0 = U32(-1);
U32 currentlyBound1 = U32(-1);
U32 currentTexGen = U32(-1);
// Draw the polys!
glColor4f(1, 1, 1, 1);
for (i = 0; i < sgActivePolyListSize; i++)
{
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
// Setup the base material...
U32 baseName = pMaterials->getMaterial(rSurface.textureIndex).getGLName();
if (baseName != currentlyBound1)
{
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
currentlyBound1 = baseName;
glBindTexture(GL_TEXTURE_2D, baseName);
}
if (currRenderBufferPoint + rSurface.windingCount >= 512 ||
currIndexPoint + (rSurface.windingCount - 2) * 3 >= 2048)
{
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
}
if (rSurface.texGenIndex != currentTexGen)
{
currentTexGen = rSurface.texGenIndex;
dMemcpy(texGen0, &mTexGenEQs[rSurface.texGenIndex], sizeof(F32)*8);
}
dMemcpy(texGen1, &mLMTexGenEQs[sgActivePolyList[i]], sizeof(F32)*8);
emitPrimitive(&sgRenderBuffer[currRenderBufferPoint],
&sgRenderIndices[currIndexPoint],
&mWindings[rSurface.windingStart],
rSurface.windingCount,
currRenderBufferPoint,
&mPoints[0]);
currRenderBufferPoint += rSurface.windingCount;
currIndexPoint += (rSurface.windingCount - 2) * 3;
AssertFatal(currRenderBufferPoint < 512 && currIndexPoint < 2048, "Aw, crap.4");
}
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
if (sgFogActive)
{
// Set up our pointers.
extern Point2F* sgFogTexCoords;
glVertexPointer(3, GL_FLOAT, sizeof(ItrPaddedPoint), &mPoints[0].point);
glTexCoordPointer(2, GL_FLOAT, sizeof(Point2F), sgFogTexCoords);
// Put the fog texture on.
glBindTexture(GL_TEXTURE_2D, gClientSceneGraph->getFogTexture().getGLName());
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
extern ColorF gInteriorFogColor;
glColor4f( gInteriorFogColor.red,
gInteriorFogColor.green,
gInteriorFogColor.blue,
1.0);
if (dglDoesSupportCompiledVertexArray())
glLockArraysEXT(0, mPoints.size());
for (U32 i = 0; i < sgActivePolyListSize; i++)
{
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
glDrawElements(GL_TRIANGLE_STRIP, rSurface.windingCount, GL_UNSIGNED_INT, &mWindings[rSurface.windingStart]);
}
if (dglDoesSupportCompiledVertexArray())
glUnlockArraysEXT();
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
}
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
} */
void Interior::renderARB(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE instanceHandle)
{
U32 i;
Vector<U8>* pLMapIndices = useAlarmLighting ? &mAlarmLMapIndices : &mNormalLMapIndices;
OutputPoint* pFirstOutputPoint = (OutputPoint*)sgRenderBuffer;
U32 currRenderBufferPoint = 0;
U32 currIndexPoint = 0;
// Lightmaps
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Base textures
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// Misc setup
glBlendFunc(GL_ONE, GL_ZERO);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->point);
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->texCoord);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->lmCoord);
// Ok, our verts are set up, draw our polys.
U32 currentlyBound0 = U32(-1);
U32 currentlyBound1 = U32(-1);
U32 currentTexGen = U32(-1);
// Draw the polys!
glColor4f(1, 1, 1, 1);
for (i = 0; i < sgActivePolyListSize; i++) {
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
// Setup the base texture...
U32 baseName = pMaterials->getMaterial(rSurface.textureIndex).getGLName();
if (baseName != currentlyBound1) {
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound1 = baseName;
glActiveTextureARB(GL_TEXTURE0_ARB);
}
// Setup the lightmap
baseName = (*pLMapIndices)[sgActivePolyList[i]];
if (baseName != currentlyBound0) {
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
U32 glName = gInteriorLMManager.getHandle(mLMHandle, instanceHandle, baseName)->getGLName();
AssertFatal(glName, "Interior::renderARB: invalid glName for texture handle");
glBindTexture(GL_TEXTURE_2D, glName);
currentlyBound0 = baseName;
}
if (currRenderBufferPoint + rSurface.windingCount >= 512 ||
currIndexPoint + (rSurface.windingCount - 2) * 3 >= 2048) {
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
}
if (rSurface.texGenIndex != currentTexGen)
{
currentTexGen = rSurface.texGenIndex;
memcpy(texGen0, &mTexGenEQs[rSurface.texGenIndex], sizeof(F32)*8);
}
memcpy(texGen1, &mLMTexGenEQs[sgActivePolyList[i]], sizeof(F32)*8);
emitPrimitive(&sgRenderBuffer[currRenderBufferPoint],
&sgRenderIndices[currIndexPoint],
&mWindings[rSurface.windingStart],
rSurface.windingCount,
currRenderBufferPoint,
&mPoints[0]);
currRenderBufferPoint += rSurface.windingCount;
currIndexPoint += (rSurface.windingCount - 2) * 3;
AssertFatal(currRenderBufferPoint < 512 && currIndexPoint < 2048, "Aw, crap.4");
}
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
if (sgFogActive) {
glVertexPointer(3, GL_FLOAT, sizeof(ItrPaddedPoint), &mPoints[0].point);
extern Point2F* sgFogTexCoords;
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glTexCoordPointer(2, GL_FLOAT, sizeof(Point2F), sgFogTexCoords);
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, gClientSceneGraph->getFogTexture().getGLName());
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
extern ColorF gInteriorFogColor;
glColor4f(gInteriorFogColor.red,
gInteriorFogColor.green,
gInteriorFogColor.blue,
1);
if (dglDoesSupportCompiledVertexArray())
glLockArraysEXT(0, mPoints.size());
for (U32 i = 0; i < sgActivePolyListSize; i++) {
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
glDrawElements(GL_TRIANGLE_STRIP, rSurface.windingCount, GL_UNSIGNED_INT, &mWindings[rSurface.windingStart]);
}
if (dglDoesSupportCompiledVertexArray())
glUnlockArraysEXT();
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
}
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
// Render environment maps...
if (smRenderEnvironmentMaps && sgEnvironPolyListSize) {
currentlyBound1 = (U32)-1;
currentlyBound0 = (U32)-1;
// Base textures
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// Envmaps textures
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Misc setup
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTextureARB(GL_TEXTURE0_ARB);
for (i = 0; i < sgEnvironPolyListSize; i++) {
const Surface& rSurface = mSurfaces[sgEnvironPolyList[i]];
// Setup the base texture...
U32 baseName = mMaterialList->getMaterial(rSurface.textureIndex).getGLName();
if (baseName != currentlyBound0) {
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound0 = baseName;
}
// Setup the environment map...
baseName = mEnvironMaps[rSurface.textureIndex]->getGLName();
if (baseName != currentlyBound1) {
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound1 = baseName;
glActiveTextureARB(GL_TEXTURE0_ARB);
}
const PlaneF& plane = getPlane(rSurface.planeIndex);
Point3F normal = plane;
if (planeIsFlipped(rSurface.planeIndex))
normal.neg();
// And the colors...
F32 baseLevel = mEnvironFactors[rSurface.textureIndex];
glBegin(GL_TRIANGLE_STRIP);
for (U32 j = rSurface.windingStart; j < rSurface.windingStart + rSurface.windingCount; j++) {
F32 s = mTexGenEQs[rSurface.texGenIndex].planeX.distToPlane(mPoints[mWindings[j]].point);
F32 t = mTexGenEQs[rSurface.texGenIndex].planeY.distToPlane(mPoints[mWindings[j]].point);
Point3F u = mPoints[mWindings[j]].point - sgOSCamPosition;
Point3F r = u;
F32 dot = mDot(normal, u) * 2.0f;
u = normal * dot;
r -= u;
F32 m = 2 * mSqrt(r.x*r.x + r.y*r.y + (r.z+1)*(r.z+1));
glColor4f(1, 1, 1, baseLevel);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, s, t);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, r.x/m + 0.5,
r.y/m + 0.5);
glVertex3fv(mPoints[mWindings[j]].point);
}
glEnd();
}
} // if (environment render on);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
}
void Interior::renderARB_FC(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE instanceHandle)
{
U32 i;
Vector<U8>* pLMapIndices = useAlarmLighting ? &mAlarmLMapIndices : &mNormalLMapIndices;
OutputPoint* pFirstOutputPoint = (OutputPoint*)sgRenderBuffer;
U32 currRenderBufferPoint = 0;
U32 currIndexPoint = 0;
bool supportBuffers;
GLint bufferHandle;
OutputPointFC_VB *vertexBuffer = NULL;
// Lightmaps
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Base textures
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// Misc setup
glBlendFunc(GL_ONE, GL_ZERO);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->point);
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->texCoord);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->lmCoord);
if (sgFogActive)
{
// Need the fog coord pointer enabled here...
glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
glFogCoordPointerEXT(GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->fogCoord);
}
// Ok, our verts are set up, draw our polys.
U32 currentlyBound0 = U32(-1);
U32 currentlyBound1 = U32(-1);
U32 currentTexGen = U32(-1);
if ((supportBuffers = dglDoesSupportVertexBuffer()) == true)
{
bufferHandle = gInteriorLMManager.getVertexBuffer(GL_V12FMTVFMT_EXT);
// guess we ran out of video memory
if (bufferHandle == -1)
supportBuffers = false;
}
// Draw the polys!
glColor4f(1, 1, 1, 1);
for (i = 0; i < sgActivePolyListSize; i++) {
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
// Setup the base texture...
U32 baseName = pMaterials->getMaterial(rSurface.textureIndex).getGLName();
if (baseName != currentlyBound1) {
if (supportBuffers)
{
if (vertexBuffer)
glUnlockVertexBufferEXT(bufferHandle);
flushPrimitivesVB(sgRenderIndices, currIndexPoint, currRenderBufferPoint, bufferHandle);
vertexBuffer = (OutputPointFC_VB *) glLockVertexBufferEXT(bufferHandle,512);
}
else
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound1 = baseName;
glActiveTextureARB(GL_TEXTURE0_ARB);
}
// Setup the lightmap
baseName = (*pLMapIndices)[sgActivePolyList[i]];
if (baseName != currentlyBound0) {
if (supportBuffers)
{
if (vertexBuffer)
glUnlockVertexBufferEXT(bufferHandle);
flushPrimitivesVB(sgRenderIndices, currIndexPoint, currRenderBufferPoint, bufferHandle);
vertexBuffer = (OutputPointFC_VB *) glLockVertexBufferEXT(bufferHandle,512);
}
else
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
U32 glName = gInteriorLMManager.getHandle(mLMHandle, instanceHandle, baseName)->getGLName();
AssertFatal(glName, "Interior::renderARB_FC: invalid glName for texture handle");
glBindTexture(GL_TEXTURE_2D, glName);
currentlyBound0 = baseName;
}
if (currRenderBufferPoint + rSurface.windingCount >= 512 ||
currIndexPoint + (rSurface.windingCount - 2) * 3 >= 2048) {
if (supportBuffers)
{
if (vertexBuffer)
glUnlockVertexBufferEXT(bufferHandle);
flushPrimitivesVB(sgRenderIndices, currIndexPoint, currRenderBufferPoint, bufferHandle);
vertexBuffer = (OutputPointFC_VB *) glLockVertexBufferEXT(bufferHandle,512);
}
else
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
}
if (rSurface.texGenIndex != currentTexGen)
{
currentTexGen = rSurface.texGenIndex;
memcpy(texGen0, &mTexGenEQs[rSurface.texGenIndex], sizeof(F32)*8);
}
memcpy(texGen1, &mLMTexGenEQs[sgActivePolyList[i]], sizeof(F32)*8);
if (supportBuffers)
emitPrimitiveFC_VB(&vertexBuffer[currRenderBufferPoint],
&sgRenderIndices[currIndexPoint],
&mWindings[rSurface.windingStart],
rSurface.windingCount,
currRenderBufferPoint,
&mPoints[0]);
else
emitPrimitive(&sgRenderBuffer[currRenderBufferPoint],
&sgRenderIndices[currIndexPoint],
&mWindings[rSurface.windingStart],
rSurface.windingCount,
currRenderBufferPoint,
&mPoints[0]);
currRenderBufferPoint += rSurface.windingCount;
currIndexPoint += (rSurface.windingCount - 2) * 3;
AssertFatal(currRenderBufferPoint < 512 && currIndexPoint < 2048, "Aw, crap.5");
}
if (supportBuffers)
{
if (vertexBuffer)
glUnlockVertexBufferEXT(bufferHandle);
flushPrimitivesVB(sgRenderIndices, currIndexPoint, currRenderBufferPoint, bufferHandle);
}
else
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
if (sgFogActive)
glDisableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
// Render environment maps...
if (smRenderEnvironmentMaps && sgEnvironPolyListSize) {
glDisable(GL_FOG);
currentlyBound1 = (U32)-1;
currentlyBound0 = (U32)-1;
// Base textures
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// Envmaps textures
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Misc setup
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1,-1);
for (i = 0; i < sgEnvironPolyListSize; i++) {
const Surface& rSurface = mSurfaces[sgEnvironPolyList[i]];
// Setup the base texture...
U32 baseName = mMaterialList->getMaterial(rSurface.textureIndex).getGLName();
if (baseName != currentlyBound0) {
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound0 = baseName;
}
// Setup the environment map...
baseName = mEnvironMaps[rSurface.textureIndex]->getGLName();
if (baseName != currentlyBound1) {
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound1 = baseName;
glActiveTextureARB(GL_TEXTURE0_ARB);
}
const PlaneF& plane = getPlane(rSurface.planeIndex);
Point3F normal = plane;
if (planeIsFlipped(rSurface.planeIndex))
normal.neg();
// And the colors...
F32 baseLevel = mEnvironFactors[rSurface.textureIndex];
glBegin(GL_TRIANGLE_STRIP);
for (U32 j = rSurface.windingStart; j < rSurface.windingStart + rSurface.windingCount; j++) {
F32 s = mTexGenEQs[rSurface.texGenIndex].planeX.distToPlane(mPoints[mWindings[j]].point);
F32 t = mTexGenEQs[rSurface.texGenIndex].planeY.distToPlane(mPoints[mWindings[j]].point);
Point3F u = mPoints[mWindings[j]].point - sgOSCamPosition;
Point3F r = u;
F32 dot = mDot(normal, u) * 2.0f;
u = normal * dot;
r -= u;
F32 m = 2 * mSqrt(r.x*r.x + r.y*r.y + (r.z+1)*(r.z+1));
glColor4f(1, 1, 1, baseLevel * (1.0 - mPoints[mWindings[j]].fogCoord));
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, s, t);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, r.x/m + 0.5,
r.y/m + 0.5);
glVertex3fv(mPoints[mWindings[j]].point);
}
glEnd();
}
glDisable(GL_POLYGON_OFFSET_FILL);
} // if (environment render on);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
}
void Interior::renderLights(LightInfo* pInfo,
const MatrixF& transform,
const Point3F& scale,
U32* lightSurfaces,
U32 numLightSurfaces)
{
Point3F lightPoint = pInfo->mPos;
transform.mulP(lightPoint);
lightPoint.convolveInverse(scale);
if (dglDoesSupportARBMultitexture())
{
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mLightFalloff->getGLName());
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1,-1);
for (U32 i = 0; i < numLightSurfaces; i++)
{
const Surface& rSurface = mSurfaces[lightSurfaces[i]];
const PlaneF& plane = getPlane(rSurface.planeIndex);
Point3F centerPoint;
F32 d = plane.distToPlane(lightPoint);
centerPoint = lightPoint - plane * d;
d = mFabs(d);
if (d >= pInfo->mRadius)
continue;
F32 mr = mSqrt(pInfo->mRadius*pInfo->mRadius - d*d);
Point3F normalS;
Point3F normalT;
if (mFabs(plane.z) < 0.9)
mCross(plane, Point3F(0, 0, 1), &normalS);
else
mCross(plane, Point3F(0, 1, 0), &normalS);
mCross(plane, normalS, &normalT);
normalS.normalize();
normalT.normalize();
PlaneF splane(centerPoint, normalS);
PlaneF tplane(centerPoint, normalT);
F32 factor = (pInfo->mRadius - d) / pInfo->mRadius;
glColor4f(pInfo->mColor.red, pInfo->mColor.green, pInfo->mColor.blue, factor);
glBegin(GL_TRIANGLE_STRIP);
for (U32 j = rSurface.windingStart; j < rSurface.windingStart + rSurface.windingCount; j++)
{
const Point3F& rPoint = mPoints[mWindings[j]].point;
glTexCoord2f(((splane.distToPlane(rPoint) / mr) + 1.0) / 2.0,
((tplane.distToPlane(rPoint) / mr) + 1.0) / 2.0);
glVertex3fv(mPoints[mWindings[j]].point);
}
glEnd();
}
glDisable(GL_POLYGON_OFFSET_FILL);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
}
void Interior::renderAsShape()
{
OutputPoint* pFirstOutputPoint = (OutputPoint*)sgRenderBuffer;
U32 currRenderBufferPoint = 0;
U32 currIndexPoint = 0;
glEnable(GL_LIGHTING);
ColorF foo(1,1,1,0);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, foo);
// Base texture:
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_ONE, GL_ZERO);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->point);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->texCoord);
if (sgFogActive) {
// Need the fog coord pointer enabled here...
glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
glFogCoordPointerEXT(GL_FLOAT, sizeof(OutputPoint), &pFirstOutputPoint->fogCoord);
}
// Ok, our verts are set up, draw our polys.
U32 currentlyBound0 = U32(-1);
U32 currentlyBound1 = U32(-1);
U32 currentTexGen = U32(-1);
// Draw the polys!
glColor4f(1, 1, 1, 1);
for (S32 i = 0; i < mSurfaces.size(); i++)
{
const Surface& rSurface = mSurfaces[i];
glNormal3fv(getPlane(rSurface.planeIndex));
// Setup the base texture...
U32 baseName = mMaterialList->getMaterial(rSurface.textureIndex).getGLName();
// Always flush.
currIndexPoint = 0;
currRenderBufferPoint = 0;
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
if (baseName != currentlyBound1)
{
glBindTexture(GL_TEXTURE_2D, baseName);
currentlyBound1 = baseName;
}
if (rSurface.texGenIndex != currentTexGen)
{
currentTexGen = rSurface.texGenIndex;
memcpy(texGen0, &mTexGenEQs[rSurface.texGenIndex], sizeof(F32)*8);
}
emitPrimitive(&sgRenderBuffer[currRenderBufferPoint],
&sgRenderIndices[currIndexPoint],
&mWindings[rSurface.windingStart],
rSurface.windingCount,
currRenderBufferPoint,
&mPoints[0]);
currRenderBufferPoint += rSurface.windingCount;
currIndexPoint += (rSurface.windingCount - 2) * 3;
flushPrimitives(sgRenderIndices, currIndexPoint, currRenderBufferPoint);
currIndexPoint = 0;
currRenderBufferPoint = 0;
AssertFatal(currRenderBufferPoint < 512 && currIndexPoint < 2048, "Aw, crap.");
}
currIndexPoint = 0;
currRenderBufferPoint = 0;
glDisable(GL_LIGHTING);
if (sgFogActive) {
glDisableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
}
if (sgFogActive && false)
{
glVertexPointer(3, GL_FLOAT, sizeof(ItrPaddedPoint), &mPoints[0].point);
extern Point2F* sgFogTexCoords;
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glTexCoordPointer(2, GL_FLOAT, sizeof(Point2F), sgFogTexCoords);
glBindTexture(GL_TEXTURE_2D, gClientSceneGraph->getFogTexture().getGLName());
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
extern ColorF gInteriorFogColor;
glColor4f(gInteriorFogColor.red,
gInteriorFogColor.green,
gInteriorFogColor.blue,
1);
if (dglDoesSupportCompiledVertexArray())
glLockArraysEXT(0, mPoints.size());
for (U32 i = 0; i < sgActivePolyListSize; i++)
{
const Surface& rSurface = mSurfaces[sgActivePolyList[i]];
glDrawElements(GL_TRIANGLE_STRIP, rSurface.windingCount, GL_UNSIGNED_INT, &mWindings[rSurface.windingStart]);
}
if (dglDoesSupportCompiledVertexArray())
glUnlockArraysEXT();
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
}
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_LIGHTING);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
}