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 COMPLETED: NULL
DESCRIPTION: Handles rendering all of the player objects. 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" #include "precompiled.h"
@ -17,16 +17,9 @@
#include "Model.h" #include "Model.h"
#include "Game.h" #include "Game.h"
#include "CConsole.h"
extern CConsole *g_Console;
CPlayerRenderer g_PlayerRenderer; CPlayerRenderer g_PlayerRenderer;
//TODO: Clean up code!
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// SortObjectsByDist: sorting class used for back-to-front sort of transparent passes // SortObjectsByDist: sorting class used for back-to-front sort of transparent passes
struct SortObjectsByDist { 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 // Render: render all deferred passes; call Sort before using to ensure passes
// are drawn in correct order // are drawn in correct order
@ -49,116 +75,50 @@ void CPlayerRenderer::Render()
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 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) { // set up texture environment for base pass - modulate texture and primary color
if (!0 || (m_Objects[i].m_Model->GetFlags() & 0)) { glActiveTexture(GL_TEXTURE0);
CModelRData* modeldata=(CModelRData*) m_Objects[i].m_Model->GetRenderData(); 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 // Set the proper LOD bias
PS_uint playerid = m_Objects[i].m_Model->GetPlayerID(); glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
// Get the player color // Render two passes: first, render the unit as normal. Second,
const SPlayerColour& colour = g_Game->GetPlayer( playerid )->GetColour(); // render it again but modulated with the player-colour, using
float color[] = { colour.r, colour.g, colour.b, colour.a }; // 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 glEnableClientState(GL_VERTEX_ARRAY);
glActiveTexture(GL_TEXTURE0); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glEnableClientState(GL_COLOR_ARRAY);
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);
// Set the proper LOD bias glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 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, RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
// 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);
}
}
// Render first pass // Render the second pass
//RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
for (uint i=0;i<m_Objects.size();++i) { // Only render high-alpha parts
if (!0 || (m_Objects[i].m_Model->GetFlags() & 0)) { glEnable(GL_ALPHA_TEST);
CModelRData* modeldata=(CModelRData*) m_Objects[i].m_Model->GetRenderData(); glAlphaFunc(GL_GREATER,0.5f);
// Get the models player ID RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0, true);
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 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 // Restore states
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
@ -269,24 +229,35 @@ void CPlayerRenderer::Add(CModel* model)
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
// RenderObjectsStreams: render given streams on all objects // RenderObjectsStreams: render given streams on all objects
//void CPlayerRenderer::RenderObjectsStreams(u32 streamflags,u32 mflags) void CPlayerRenderer::RenderObjectsStreams(u32 streamflags, bool iscolorpass, u32 mflags)
//{ {
// for (uint i=0;i<m_Objects.size();++i) { for (uint i=0;i<m_Objects.size();++i) {
// if (!mflags || (m_Objects[i].m_Model->GetFlags() & mflags)) { if (!mflags || (m_Objects[i].m_Model->GetFlags() & mflags)) {
// CModelRData* modeldata=(CModelRData*) m_Objects[i].m_Model->GetRenderData(); CModelRData* modeldata=(CModelRData*) m_Objects[i].m_Model->GetRenderData();
//
// // Get the models player ID // Setup the render states to apply the second texture ( i.e. player color )
// PS_uint playerid = m_Objects[i].m_Model->GetPlayerID(); if (iscolorpass)
// {
// // Get the player color // I, John Mena, don't think that both passes need a color applied.
// const SPlayerColour& colour = g_Game->GetPlayer( playerid )->GetColour(); // If I am wrong, then just move everything except for the
// float color[] = { colour.r, colour.g, colour.b, colour.a }; // SetupColorRenderStates() below this if statement.
//
// // Set the texture environment color the player color // Get the models player ID
// glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color); PS_uint playerid = m_Objects[i].m_Model->GetPlayerID();
//
// // Render the model // Get the player color
// modeldata->RenderStreams(streamflags, true); 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: private:
// render given streams on all objects // 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 // list of transparent objects to render
std::vector<SObject> m_Objects; std::vector<SObject> m_Objects;
}; };