forked from 0ad/0ad
This was SVN commit r1803.
This commit is contained in:
parent
0e39146eb4
commit
761dfde0c5
@ -5,6 +5,7 @@
|
|||||||
#include "res/ogl_tex.h"
|
#include "res/ogl_tex.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "TransparencyRenderer.h"
|
#include "TransparencyRenderer.h"
|
||||||
|
#include "PlayerRenderer.h"
|
||||||
#include "ModelRData.h"
|
#include "ModelRData.h"
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
#include "ModelDef.h"
|
#include "ModelDef.h"
|
||||||
@ -49,7 +50,9 @@ void CModelRData::Build()
|
|||||||
/*if (g_Renderer.IsTextureTransparent(m_Model->GetTexture())) {
|
/*if (g_Renderer.IsTextureTransparent(m_Model->GetTexture())) {
|
||||||
m_Flags|=MODELRDATA_FLAG_TRANSPARENT;
|
m_Flags|=MODELRDATA_FLAG_TRANSPARENT;
|
||||||
}*/
|
}*/
|
||||||
if(m_Model->GetMaterial().UsesAlpha())
|
if(m_Model->GetPlayerID() + 1)
|
||||||
|
m_Flags |= MODELRDATA_FLAG_PLAYERCOLOR;
|
||||||
|
else if(m_Model->GetMaterial().UsesAlpha())
|
||||||
m_Flags |= MODELRDATA_FLAG_TRANSPARENT;
|
m_Flags |= MODELRDATA_FLAG_TRANSPARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,13 +179,17 @@ void CModelRData::BuildVertices()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CModelRData::RenderStreams(u32 streamflags)
|
void CModelRData::RenderStreams(u32 streamflags, bool isplayer)
|
||||||
{
|
{
|
||||||
CModelDefPtr mdldef=m_Model->GetModelDef();
|
CModelDefPtr mdldef=m_Model->GetModelDef();
|
||||||
|
|
||||||
if (streamflags & STREAM_UV0)
|
if (streamflags & STREAM_UV0)
|
||||||
{
|
{
|
||||||
m_Model->GetMaterial().Bind();
|
if(!isplayer)
|
||||||
|
m_Model->GetMaterial().Bind();
|
||||||
|
else
|
||||||
|
g_Renderer.SetTexture(1,m_Model->GetTexture());
|
||||||
|
|
||||||
g_Renderer.SetTexture(0,m_Model->GetTexture());
|
g_Renderer.SetTexture(0,m_Model->GetTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,8 +206,8 @@ void CModelRData::RenderStreams(u32 streamflags)
|
|||||||
// glDrawRangeElements(GL_TRIANGLES,0,mdldef->GetNumVertices(),numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
// glDrawRangeElements(GL_TRIANGLES,0,mdldef->GetNumVertices(),numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
||||||
glDrawElements(GL_TRIANGLES,numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
glDrawElements(GL_TRIANGLES,numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
||||||
|
|
||||||
if(streamflags & STREAM_UV0)
|
if(streamflags & STREAM_UV0 & !isplayer)
|
||||||
m_Model->GetMaterial().Unbind();
|
m_Model->GetMaterial().Unbind();
|
||||||
|
|
||||||
// bump stats
|
// bump stats
|
||||||
g_Renderer.m_Stats.m_DrawCalls++;
|
g_Renderer.m_Stats.m_DrawCalls++;
|
||||||
@ -330,7 +337,7 @@ void CModelRData::RenderModels(u32 streamflags,u32 flags)
|
|||||||
// TODO: If not doing player-colours, only bind this to
|
// TODO: If not doing player-colours, only bind this to
|
||||||
// the first texture unit
|
// the first texture unit
|
||||||
g_Renderer.BindTexture(0,tex_id(batch->m_Texture));
|
g_Renderer.BindTexture(0,tex_id(batch->m_Texture));
|
||||||
g_Renderer.BindTexture(1,tex_id(batch->m_Texture));
|
//g_Renderer.BindTexture(1,tex_id(batch->m_Texture));
|
||||||
}
|
}
|
||||||
for (uint j=0;j<batch->m_IndexData.size();j++) {
|
for (uint j=0;j<batch->m_IndexData.size();j++) {
|
||||||
glDrawElements(GL_TRIANGLES,(GLsizei)batch->m_IndexData[j].first,GL_UNSIGNED_SHORT,batch->m_IndexData[j].second);
|
glDrawElements(GL_TRIANGLES,(GLsizei)batch->m_IndexData[j].first,GL_UNSIGNED_SHORT,batch->m_IndexData[j].second);
|
||||||
@ -370,6 +377,9 @@ void CModelRData::Submit(CModel* model)
|
|||||||
// add this mode to the transparency renderer for later processing - calculate
|
// add this mode to the transparency renderer for later processing - calculate
|
||||||
// transform matrix
|
// transform matrix
|
||||||
g_TransparencyRenderer.Add(model);
|
g_TransparencyRenderer.Add(model);
|
||||||
|
} else if (data->GetFlags() & MODELRDATA_FLAG_PLAYERCOLOR) {
|
||||||
|
// add this model to the player renderer
|
||||||
|
g_PlayerRenderer.Add(model);
|
||||||
} else {
|
} else {
|
||||||
// add to regular model list
|
// add to regular model list
|
||||||
m_Models.push_back(model);
|
m_Models.push_back(model);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "RenderableObject.h"
|
#include "RenderableObject.h"
|
||||||
|
|
||||||
#define MODELRDATA_FLAG_TRANSPARENT (1<<0)
|
#define MODELRDATA_FLAG_TRANSPARENT (1<<0)
|
||||||
|
#define MODELRDATA_FLAG_PLAYERCOLOR (1<<1)
|
||||||
|
|
||||||
class CModel;
|
class CModel;
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ public:
|
|||||||
~CModelRData();
|
~CModelRData();
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
void RenderStreams(u32 streamflags);
|
void RenderStreams(u32 streamflags, bool isplayer = false);
|
||||||
|
|
||||||
// return render flags for this model
|
// return render flags for this model
|
||||||
u32 GetFlags() const { return m_Flags; }
|
u32 GetFlags() const { return m_Flags; }
|
||||||
|
241
source/renderer/PlayerRenderer.cpp
Normal file
241
source/renderer/PlayerRenderer.cpp
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/***************************************************************************************
|
||||||
|
AUTHOR: John M. Mena
|
||||||
|
EMAIL: JohnMMena@hotmail.com
|
||||||
|
FILE: CConsole.h
|
||||||
|
CREATED: 1/23/05
|
||||||
|
COMPLETED: NULL
|
||||||
|
|
||||||
|
DESCRIPTION: Handles rendering all of the player objects.
|
||||||
|
The structure was inherited from Rich Cross' Transparency Renderer.
|
||||||
|
****************************************************************************************/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "PlayerRenderer.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
|
|
||||||
|
CPlayerRenderer g_PlayerRenderer;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// SortObjectsByDist: sorting class used for back-to-front sort of transparent passes
|
||||||
|
struct SortObjectsByDist {
|
||||||
|
typedef CPlayerRenderer::SObject SortObj;
|
||||||
|
|
||||||
|
bool operator()(const SortObj& lhs,const SortObj& rhs) {
|
||||||
|
return lhs.m_Dist>rhs.m_Dist? true : false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Render first pass
|
||||||
|
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Only render high-alpha parts
|
||||||
|
glEnable(GL_ALPHA_TEST);
|
||||||
|
glAlphaFunc(GL_GREATER,0.5f);
|
||||||
|
|
||||||
|
// Render second pass
|
||||||
|
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||||
|
|
||||||
|
// Restore states
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
// switch off client states
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
|
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
|
||||||
|
// switch wireframe off again
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||||
|
} else if (g_Renderer.m_ModelRenderMode==EDGED_FACES) {
|
||||||
|
// edged faces: need to make a second pass over the data:
|
||||||
|
// first switch on wireframe
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||||
|
|
||||||
|
// setup some renderstate ..
|
||||||
|
glDepthMask(0);
|
||||||
|
g_Renderer.SetTexture(0,0);
|
||||||
|
glColor4f(1,1,1,0.75f);
|
||||||
|
glLineWidth(1.0f);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
// .. and some client states
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
|
// render each model
|
||||||
|
RenderObjectsStreams(STREAM_POS);
|
||||||
|
|
||||||
|
// .. and switch off the client states
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
|
// .. and restore the renderstates
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glDepthMask(1);
|
||||||
|
|
||||||
|
// restore fill mode, and we're done
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPlayerRenderer::Clear()
|
||||||
|
{
|
||||||
|
// all transparent objects rendered; release them
|
||||||
|
m_Objects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPlayerRenderer::Add(CModel* model)
|
||||||
|
{
|
||||||
|
// resize array, get last object in list
|
||||||
|
m_Objects.resize(m_Objects.size()+1);
|
||||||
|
|
||||||
|
SObject& obj=m_Objects.back();
|
||||||
|
obj.m_Model=model;
|
||||||
|
|
||||||
|
// build transform from object to camera space
|
||||||
|
CMatrix3D objToCam,invcam;
|
||||||
|
g_Renderer.m_Camera.m_Orientation.GetInverse(objToCam);
|
||||||
|
objToCam*=model->GetTransform();
|
||||||
|
|
||||||
|
// resort model indices from back to front, according to camera position - and store
|
||||||
|
// the returned sqrd distance to the centre of the nearest triangle
|
||||||
|
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||||
|
obj.m_Dist=modeldata->BackToFrontIndexSort(objToCam);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Correctly implement shadows for the players
|
||||||
|
//void CPlayerRenderer::RenderShadows()
|
||||||
|
//{
|
||||||
|
// if (m_Objects.size()==0) return;
|
||||||
|
//
|
||||||
|
// // switch on client states
|
||||||
|
// glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
//
|
||||||
|
// glDepthMask(0);
|
||||||
|
//
|
||||||
|
// glEnable(GL_BLEND);
|
||||||
|
// glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
//
|
||||||
|
// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||||
|
// glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||||
|
// 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_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||||
|
// glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||||
|
// glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||||
|
//
|
||||||
|
// // Set the proper LOD bias
|
||||||
|
// glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
|
||||||
|
//
|
||||||
|
// RenderObjectsStreams(STREAM_POS|STREAM_UV0,MODELFLAG_CASTSHADOWS);
|
||||||
|
//
|
||||||
|
// glDepthMask(1);
|
||||||
|
// glDisable(GL_BLEND);
|
||||||
|
//
|
||||||
|
// // switch off client states
|
||||||
|
// glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
//}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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
|
||||||
|
const 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
source/renderer/PlayerRenderer.h
Normal file
48
source/renderer/PlayerRenderer.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/***************************************************************************************
|
||||||
|
AUTHOR: John M. Mena
|
||||||
|
EMAIL: JohnMMena@hotmail.com
|
||||||
|
FILE: CConsole.h
|
||||||
|
CREATED: 1/23/05
|
||||||
|
COMPLETED: NULL
|
||||||
|
|
||||||
|
DESCRIPTION: Handles rendering all of the player objects.
|
||||||
|
The structure was inherited from Rich Cross' Transparency Renderer.
|
||||||
|
****************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __PLAYERRENDERER_H
|
||||||
|
#define __PLAYERRENDERER_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class CModel;
|
||||||
|
|
||||||
|
class CPlayerRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct SObject {
|
||||||
|
// the transparent model
|
||||||
|
CModel* m_Model;
|
||||||
|
// sqrd distance from camera to centre of nearest triangle
|
||||||
|
float m_Dist;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
// add object to render in deferred transparency pass
|
||||||
|
void Add(CModel* model);
|
||||||
|
// render all deferred objects
|
||||||
|
void Render();
|
||||||
|
// render shadows from all deferred objects
|
||||||
|
void RenderShadows();
|
||||||
|
// empty object list
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// render given streams on all objects
|
||||||
|
void RenderObjectsStreams(u32 streamflags,u32 mflags=0);
|
||||||
|
// list of transparent objects to render
|
||||||
|
std::vector<SObject> m_Objects;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CPlayerRenderer g_PlayerRenderer;
|
||||||
|
|
||||||
|
#endif
|
@ -19,6 +19,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "TransparencyRenderer.h"
|
#include "TransparencyRenderer.h"
|
||||||
|
#include "PlayerRenderer.h"
|
||||||
#include "Terrain.h"
|
#include "Terrain.h"
|
||||||
#include "Matrix3D.h"
|
#include "Matrix3D.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
@ -798,109 +799,27 @@ void CRenderer::RenderModelSubmissions()
|
|||||||
// Set the proper LOD bias
|
// Set the proper LOD bias
|
||||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, m_Options.m_LodBias);
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, m_Options.m_LodBias);
|
||||||
|
|
||||||
// TODO: do this properly
|
// pass one through as alpha; transparent textures handled specially by CTransparencyRenderer
|
||||||
const bool playercolor=true;
|
// (gl_constant means the colour comes from the gl_texture_env_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);
|
||||||
|
|
||||||
if (! playercolor)
|
float color[] = { 1.0, 1.0, 1.0, 1.0 };
|
||||||
{
|
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
|
||||||
|
|
||||||
// pass one through as alpha; transparent textures handled specially by CTransparencyRenderer
|
// setup client states
|
||||||
// (gl_constant means the colour comes from the gl_texture_env_color)
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_CONSTANT);
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
|
||||||
|
|
||||||
float color[] = { 1.0, 1.0, 1.0, 1.0 };
|
// render models
|
||||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
|
CModelRData::RenderModels(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||||
|
|
||||||
// setup client states
|
// switch off client states
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
// render models
|
|
||||||
CModelRData::RenderModels(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
|
||||||
|
|
||||||
// switch off client states
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
float color[] = { 1.0, 0.0, 0.0, 1.0 };
|
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
|
||||||
|
|
||||||
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 first pass
|
|
||||||
CModelRData::RenderModels(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
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 second pass
|
|
||||||
CModelRData::RenderModels(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
|
||||||
|
|
||||||
// Restore states
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glDisable(GL_ALPHA_TEST);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
// switch off client states
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::RenderModels()
|
void CRenderer::RenderModels()
|
||||||
@ -990,6 +909,10 @@ void CRenderer::FlushFrame()
|
|||||||
RenderPatches();
|
RenderPatches();
|
||||||
oglCheck();
|
oglCheck();
|
||||||
|
|
||||||
|
MICROLOG(L"render player models");
|
||||||
|
g_PlayerRenderer.Render();
|
||||||
|
oglCheck();
|
||||||
|
|
||||||
MICROLOG(L"render models");
|
MICROLOG(L"render models");
|
||||||
RenderModels();
|
RenderModels();
|
||||||
oglCheck();
|
oglCheck();
|
||||||
@ -1009,6 +932,7 @@ void CRenderer::FlushFrame()
|
|||||||
// empty lists
|
// empty lists
|
||||||
MICROLOG(L"empty lists");
|
MICROLOG(L"empty lists");
|
||||||
g_TransparencyRenderer.Clear();
|
g_TransparencyRenderer.Clear();
|
||||||
|
g_PlayerRenderer.Clear();
|
||||||
CPatchRData::ClearSubmissions();
|
CPatchRData::ClearSubmissions();
|
||||||
CModelRData::ClearSubmissions();
|
CModelRData::ClearSubmissions();
|
||||||
}
|
}
|
||||||
|
@ -221,6 +221,7 @@ protected:
|
|||||||
friend class CPatchRData;
|
friend class CPatchRData;
|
||||||
friend class CModelRData;
|
friend class CModelRData;
|
||||||
friend class CTransparencyRenderer;
|
friend class CTransparencyRenderer;
|
||||||
|
friend class CPlayerRenderer;
|
||||||
|
|
||||||
// update renderdata of everything submitted
|
// update renderdata of everything submitted
|
||||||
void UpdateSubmittedObjectData();
|
void UpdateSubmittedObjectData();
|
||||||
|
@ -154,7 +154,7 @@ public:
|
|||||||
void SetPlayer(CPlayer *pPlayer);
|
void SetPlayer(CPlayer *pPlayer);
|
||||||
|
|
||||||
// Retrieve the player associated with this entity
|
// Retrieve the player associated with this entity
|
||||||
inline CPlayer* GetPlayer() { return m_player; }
|
CPlayer* GetPlayer() { return m_player; }
|
||||||
|
|
||||||
// Process damage
|
// Process damage
|
||||||
void Damage( CDamageType& damage, CEntity* inflictor = NULL );
|
void Damage( CDamageType& damage, CEntity* inflictor = NULL );
|
||||||
|
Loading…
Reference in New Issue
Block a user