forked from 0ad/0ad
This was SVN commit r1809.
This commit is contained in:
parent
12bbe9cda1
commit
f96b676fc9
@ -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 {
|
||||||
@ -38,85 +31,9 @@ struct SortObjectsByDist {
|
|||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Render: render all deferred passes; call Sort before using to ensure passes
|
// SetupColorRenderStates: setup the render states for the player color pass.
|
||||||
// are drawn in correct order
|
void CPlayerRenderer::SetupColorRenderStates()
|
||||||
void CPlayerRenderer::Render()
|
|
||||||
{
|
{
|
||||||
if (m_Objects.size()==0) return;
|
|
||||||
|
|
||||||
// switch on wireframe if we need it
|
|
||||||
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
|
|
||||||
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();
|
|
||||||
|
|
||||||
// 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 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);
|
|
||||||
|
|
||||||
// Set the proper LOD bias
|
|
||||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Render first pass
|
|
||||||
//RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
// 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 up second pass: first texture unit carries on doing texture*lighting,
|
// Set up second pass: first texture unit carries on doing texture*lighting,
|
||||||
// but passes alpha through inverted; the second texture unit modulates
|
// but passes alpha through inverted; the second texture unit modulates
|
||||||
// with the player colour.
|
// with the player colour.
|
||||||
@ -139,26 +56,69 @@ void CPlayerRenderer::Render()
|
|||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT);
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
|
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
|
// Continue passing through alpha from texture
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
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_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
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
|
||||||
|
void CPlayerRenderer::Render()
|
||||||
|
{
|
||||||
|
if (m_Objects.size()==0) return;
|
||||||
|
|
||||||
|
// switch on wireframe if we need it
|
||||||
|
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Set the proper LOD bias
|
||||||
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||||
|
|
||||||
|
|
||||||
|
// Render the second pass
|
||||||
|
|
||||||
// Only render high-alpha parts
|
// Only render high-alpha parts
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
glAlphaFunc(GL_GREATER,0.5f);
|
glAlphaFunc(GL_GREATER,0.5f);
|
||||||
|
|
||||||
// Render the model
|
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0, true);
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user