This was SVN commit r1809.

This commit is contained in:
NoMonkey 2005-01-25 03:12:04 +00:00
parent 12bbe9cda1
commit f96b676fc9
2 changed files with 102 additions and 129 deletions

View File

@ -6,7 +6,7 @@
COMPLETED: NULL
DESCRIPTION: Handles rendering all of the player objects.
The structure was inherited from Rich Cross' Transparency Renderer.
The structure and overall design was inherited from Rich Cross' Transparency Renderer.
****************************************************************************************/
#include "precompiled.h"
@ -17,16 +17,9 @@
#include "Model.h"
#include "Game.h"
#include "CConsole.h"
extern CConsole *g_Console;
CPlayerRenderer g_PlayerRenderer;
//TODO: Clean up code!
///////////////////////////////////////////////////////////////////////////////////////////////////
// SortObjectsByDist: sorting class used for back-to-front sort of transparent passes
struct SortObjectsByDist {
@ -37,6 +30,39 @@ struct SortObjectsByDist {
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// SetupColorRenderStates: setup the render states for the player color pass.
void CPlayerRenderer::SetupColorRenderStates()
{
// Set up second pass: first texture unit carries on doing texture*lighting,
// but passes alpha through inverted; the second texture unit modulates
// with the player colour.
glActiveTexture(GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
// t1 = t0 * playercolor
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
// Continue passing through alpha from texture
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Render: render all deferred passes; call Sort before using to ensure passes
// are drawn in correct order
@ -49,116 +75,50 @@ void CPlayerRenderer::Render()
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
}
//TODO: Possibly remove render states from the loop that don't need to be
// initialized for each model. Also, possibly combine the loops.
for (uint i=0;i<m_Objects.size();++i) {
if (!0 || (m_Objects[i].m_Model->GetFlags() & 0)) {
CModelRData* modeldata=(CModelRData*) m_Objects[i].m_Model->GetRenderData();
// set up texture environment for base pass - modulate texture and primary color
glActiveTexture(GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
// Get the models player ID
PS_uint playerid = m_Objects[i].m_Model->GetPlayerID();
// Set the proper LOD bias
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
// Get the player color
const SPlayerColour& colour = g_Game->GetPlayer( playerid )->GetColour();
float color[] = { colour.r, colour.g, colour.b, colour.a };
// Render two passes: first, render the unit as normal. Second,
// render it again but modulated with the player-colour, using
// the alpha channel as a mask.
// EDIT: The second pass resides in SetupColorRenderStates() [John M. Mena]
//
// Assume the alpha channel is 1-bit, so there's no need for blending.
//
// This probably ought to be done in a single pass on hardware that
// supports register combiners / fragment programs / etc.
// set up texture environment for base pass - modulate texture and primary color
glActiveTexture(GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
// Set the proper LOD bias
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
glDisable(GL_ALPHA_TEST);
// Render two passes: first, render the unit as normal. Second,
// render it again but modulated with the player-colour, using
// the alpha channel as a mask.
//
// Assume the alpha channel is 1-bit, so there's no need for blending.
//
// This probably ought to be done in a single pass on hardware that
// supports register combiners / fragment programs / etc.
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
// Set the texture environment color the player color
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
glDisable(GL_ALPHA_TEST);
// Render the model
modeldata->RenderStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0, true);
}
}
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
// Render first pass
//RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
// Render the second pass
for (uint i=0;i<m_Objects.size();++i) {
if (!0 || (m_Objects[i].m_Model->GetFlags() & 0)) {
CModelRData* modeldata=(CModelRData*) m_Objects[i].m_Model->GetRenderData();
// Only render high-alpha parts
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER,0.5f);
// Get the models player ID
PS_uint playerid = m_Objects[i].m_Model->GetPlayerID();
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0, true);
// Get the player color
const SPlayerColour& colour = g_Game->GetPlayer( playerid )->GetColour();
float color[] = { colour.r, colour.g, colour.b, colour.a };
// Set up second pass: first texture unit carries on doing texture*lighting,
// but passes alpha through inverted; the second texture unit modulates
// with the player colour.
glActiveTexture(GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
// t1 = t0 * playercolor
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
// Set the texture environment color the player color
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
// Continue passing through alpha from texture
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
// Only render high-alpha parts
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER,0.5f);
// Render the model
modeldata->RenderStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0, true);
}
}
// Render second pass
//RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
// Restore states
glActiveTexture(GL_TEXTURE1);
@ -269,24 +229,35 @@ void CPlayerRenderer::Add(CModel* model)
///////////////////////////////////////////////////////////////////////////////////////////////
// RenderObjectsStreams: render given streams on all objects
//void CPlayerRenderer::RenderObjectsStreams(u32 streamflags,u32 mflags)
//{
// for (uint i=0;i<m_Objects.size();++i) {
// if (!mflags || (m_Objects[i].m_Model->GetFlags() & mflags)) {
// CModelRData* modeldata=(CModelRData*) m_Objects[i].m_Model->GetRenderData();
//
// // Get the models player ID
// PS_uint playerid = m_Objects[i].m_Model->GetPlayerID();
//
// // Get the player color
// const SPlayerColour& colour = g_Game->GetPlayer( playerid )->GetColour();
// float color[] = { colour.r, colour.g, colour.b, colour.a };
//
// // Set the texture environment color the player color
// glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
//
// // Render the model
// modeldata->RenderStreams(streamflags, true);
// }
// }
//}
void CPlayerRenderer::RenderObjectsStreams(u32 streamflags, bool iscolorpass, u32 mflags)
{
for (uint i=0;i<m_Objects.size();++i) {
if (!mflags || (m_Objects[i].m_Model->GetFlags() & mflags)) {
CModelRData* modeldata=(CModelRData*) m_Objects[i].m_Model->GetRenderData();
// Setup the render states to apply the second texture ( i.e. player color )
if (iscolorpass)
{
// I, John Mena, don't think that both passes need a color applied.
// If I am wrong, then just move everything except for the
// SetupColorRenderStates() below this if statement.
// Get the models player ID
PS_uint playerid = m_Objects[i].m_Model->GetPlayerID();
// Get the player color
const SPlayerColour& colour = g_Game->GetPlayer( playerid )->GetColour();
float color[] = { colour.r, colour.g, colour.b, colour.a };
// Just like it says, Sets up the player color render states
SetupColorRenderStates();
// Set the texture environment color the player color
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
}
// Render the model
modeldata->RenderStreams(streamflags, iscolorpass);
}
}
}

View File

@ -38,7 +38,9 @@ public:
private:
// render given streams on all objects
//void RenderObjectsStreams(u32 streamflags,u32 mflags=0);
void RenderObjectsStreams(u32 streamflags, bool iscolorpass=false, u32 mflags=0);
// setup the second pass for the player color
void SetupColorRenderStates();
// list of transparent objects to render
std::vector<SObject> m_Objects;
};