2009-04-18 19:00:33 +02:00
|
|
|
/* Copyright (C) 2009 Wildfire Games.
|
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
|
|
|
* =========================================================================
|
|
|
|
* File : TransparencyRenderer.h
|
|
|
|
* Project : Pyrogenesis
|
2006-01-07 02:04:26 +01:00
|
|
|
* Description : ModelRenderer implementation that sorts models and/or
|
|
|
|
* : polygons based on distance from viewer, for transparency
|
2005-11-06 00:15:23 +01:00
|
|
|
* : rendering.
|
2005-10-25 03:43:07 +02:00
|
|
|
* =========================================================================
|
|
|
|
*/
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2004-06-03 20:38:14 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
2004-05-30 02:46:58 +02:00
|
|
|
#include <algorithm>
|
2005-10-25 03:43:07 +02:00
|
|
|
#include <vector>
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "lib/ogl.h"
|
|
|
|
#include "maths/MathUtil.h"
|
|
|
|
#include "maths/Vector3D.h"
|
|
|
|
#include "maths/Vector4D.h"
|
2005-10-25 03:43:07 +02:00
|
|
|
|
2006-03-26 01:54:20 +01:00
|
|
|
#include "graphics/LightEnv.h"
|
2005-10-25 03:43:07 +02:00
|
|
|
#include "graphics/Model.h"
|
|
|
|
#include "graphics/ModelDef.h"
|
|
|
|
|
|
|
|
#include "ps/Profile.h"
|
|
|
|
|
|
|
|
#include "renderer/Renderer.h"
|
2006-03-26 01:54:20 +01:00
|
|
|
#include "renderer/ShadowMap.h"
|
2005-10-25 03:43:07 +02:00
|
|
|
#include "renderer/TransparencyRenderer.h"
|
|
|
|
#include "renderer/VertexArray.h"
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2005-11-06 00:15:23 +01:00
|
|
|
// PolygonSortModelRenderer implementation
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
/**
|
2005-11-06 00:15:23 +01:00
|
|
|
* Struct PSModelDef: Per-CModelDef data for the polygon sort vertex renderer
|
2005-10-25 03:43:07 +02:00
|
|
|
*/
|
2005-11-06 00:15:23 +01:00
|
|
|
struct PSModelDef : public CModelDefRPrivate
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2008-07-17 16:23:51 +02:00
|
|
|
PSModelDef(const CModelDefPtr& mdef);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/// Static vertex array
|
|
|
|
VertexArray m_Array;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/// UV is static
|
|
|
|
VertexArray::Attribute m_UV;
|
|
|
|
};
|
|
|
|
|
2008-07-17 16:23:51 +02:00
|
|
|
PSModelDef::PSModelDef(const CModelDefPtr& mdef)
|
2005-10-25 03:43:07 +02:00
|
|
|
: m_Array(false)
|
|
|
|
{
|
|
|
|
m_UV.type = GL_FLOAT;
|
|
|
|
m_UV.elems = 2;
|
|
|
|
m_Array.AddAttribute(&m_UV);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
m_Array.SetNumVertices(mdef->GetNumVertices());
|
|
|
|
m_Array.Layout();
|
|
|
|
|
|
|
|
VertexArrayIterator<float[2]> UVit = m_UV.GetIterator<float[2]>();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
ModelRenderer::BuildUV(mdef, UVit);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
m_Array.Upload();
|
|
|
|
m_Array.FreeBackingStore();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2005-11-06 00:15:23 +01:00
|
|
|
* Struct PSModel: Per-CModel data for the polygon sorting renderer
|
2005-10-25 03:43:07 +02:00
|
|
|
*/
|
2005-11-06 00:15:23 +01:00
|
|
|
struct PSModel
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
PSModel(CModel* model);
|
|
|
|
~PSModel();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
|
|
|
* BackToFrontIndexSort: Sort polygons by distance to camera for
|
|
|
|
* transparency rendering and fill the indices array appropriately.
|
|
|
|
*
|
|
|
|
* @param worldToCam World to camera coordinate space transform
|
|
|
|
*
|
|
|
|
* @return Square of the estimated distance to the nearest triangle.
|
|
|
|
*/
|
|
|
|
float BackToFrontIndexSort(const CMatrix3D& objToCam);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
/// Back-link to the model
|
|
|
|
CModel* m_Model;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/// Dynamic per-CModel vertex array
|
|
|
|
VertexArray m_Array;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/// Position and lighting are recalculated on CPU every frame
|
|
|
|
VertexArray::Attribute m_Position;
|
|
|
|
VertexArray::Attribute m_Color;
|
|
|
|
|
|
|
|
/// Indices array (sorted on CPU based on distance to camera)
|
|
|
|
u16* m_Indices;
|
|
|
|
};
|
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
PSModel::PSModel(CModel* model)
|
|
|
|
: m_Model(model), m_Array(true)
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
CModelDefPtr mdef = m_Model->GetModelDef();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
m_Position.type = GL_FLOAT;
|
|
|
|
m_Position.elems = 3;
|
|
|
|
m_Array.AddAttribute(&m_Position);
|
|
|
|
|
|
|
|
m_Color.type = GL_UNSIGNED_BYTE;
|
|
|
|
m_Color.elems = 4;
|
|
|
|
m_Array.AddAttribute(&m_Color);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
m_Array.SetNumVertices(mdef->GetNumVertices());
|
|
|
|
m_Array.Layout();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
m_Indices = new u16[mdef->GetNumFaces()*3];
|
|
|
|
}
|
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
PSModel::~PSModel()
|
|
|
|
{
|
|
|
|
delete[] m_Indices;
|
|
|
|
}
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
typedef std::pair<int,float> IntFloatPair;
|
|
|
|
|
|
|
|
struct SortFacesByDist {
|
|
|
|
bool operator()(const IntFloatPair& lhs,const IntFloatPair& rhs) {
|
|
|
|
return lhs.second>rhs.second ? true : false;
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
float PSModel::BackToFrontIndexSort(const CMatrix3D& worldToCam)
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2005-10-25 03:43:07 +02:00
|
|
|
static std::vector<IntFloatPair> IndexSorter;
|
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
CModelDefPtr mdef = m_Model->GetModelDef();
|
2005-10-25 03:43:07 +02:00
|
|
|
size_t numFaces = mdef->GetNumFaces();
|
|
|
|
const SModelFace* faces = mdef->GetFaces();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
if (IndexSorter.size() < numFaces)
|
|
|
|
IndexSorter.resize(numFaces);
|
|
|
|
|
|
|
|
VertexArrayIterator<CVector3D> Position = m_Position.GetIterator<CVector3D>();
|
|
|
|
CVector3D tmpvtx;
|
|
|
|
|
|
|
|
for(size_t i = 0; i < numFaces; ++i)
|
|
|
|
{
|
|
|
|
tmpvtx = Position[faces[i].m_Verts[0]];
|
|
|
|
tmpvtx += Position[faces[i].m_Verts[1]];
|
|
|
|
tmpvtx += Position[faces[i].m_Verts[2]];
|
|
|
|
tmpvtx *= 1.0f/3.0f;
|
|
|
|
|
|
|
|
tmpvtx = worldToCam.Transform(tmpvtx);
|
|
|
|
float distsqrd = SQR(tmpvtx.X)+SQR(tmpvtx.Y)+SQR(tmpvtx.Z);
|
|
|
|
|
2005-10-31 17:26:51 +01:00
|
|
|
IndexSorter[i].first = (int)i;
|
2005-10-25 03:43:07 +02:00
|
|
|
IndexSorter[i].second = distsqrd;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::sort(IndexSorter.begin(),IndexSorter.begin()+numFaces,SortFacesByDist());
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// now build index list
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
size_t idxidx = 0;
|
2005-10-25 03:43:07 +02:00
|
|
|
for (size_t i = 0; i < numFaces; ++i) {
|
|
|
|
const SModelFace& face = faces[IndexSorter[i].first];
|
|
|
|
m_Indices[idxidx++] = (u16)(face.m_Verts[0]);
|
|
|
|
m_Indices[idxidx++] = (u16)(face.m_Verts[1]);
|
|
|
|
m_Indices[idxidx++] = (u16)(face.m_Verts[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return IndexSorter[0].second;
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
/**
|
2005-11-06 00:15:23 +01:00
|
|
|
* Struct PolygonSortModelRendererInternals: Internal data structure of
|
|
|
|
* PolygonSortModelRenderer
|
2005-10-25 03:43:07 +02:00
|
|
|
*/
|
2005-11-06 00:15:23 +01:00
|
|
|
struct PolygonSortModelRendererInternals
|
|
|
|
{
|
|
|
|
/// Scratch space for normal vector calculation
|
|
|
|
std::vector<CVector3D> normals;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Construction / Destruction
|
|
|
|
PolygonSortModelRenderer::PolygonSortModelRenderer()
|
|
|
|
{
|
|
|
|
m = new PolygonSortModelRendererInternals;
|
|
|
|
}
|
|
|
|
|
|
|
|
PolygonSortModelRenderer::~PolygonSortModelRenderer()
|
|
|
|
{
|
|
|
|
delete m;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create per-CModel data for the model (and per-CModelDef data if necessary)
|
|
|
|
void* PolygonSortModelRenderer::CreateModelData(CModel* model)
|
|
|
|
{
|
|
|
|
CModelDefPtr mdef = model->GetModelDef();
|
|
|
|
PSModelDef* psmdef = (PSModelDef*)mdef->GetRenderData(m);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
if (!psmdef)
|
|
|
|
{
|
|
|
|
psmdef = new PSModelDef(mdef);
|
|
|
|
mdef->SetRenderData(m, psmdef);
|
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
return new PSModel(model);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Updated transforms
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void PolygonSortModelRenderer::UpdateModelData(CModel* model, void* data, int updateflags)
|
2005-11-06 00:15:23 +01:00
|
|
|
{
|
|
|
|
PSModel* psmdl = (PSModel*)data;
|
|
|
|
|
2006-02-15 01:45:16 +01:00
|
|
|
if (updateflags & (RENDERDATA_UPDATE_VERTICES|RENDERDATA_UPDATE_COLOR))
|
2005-11-06 00:15:23 +01:00
|
|
|
{
|
|
|
|
CModelDefPtr mdef = model->GetModelDef();
|
|
|
|
size_t numVertices = mdef->GetNumVertices();
|
|
|
|
|
|
|
|
// build vertices
|
|
|
|
if (m->normals.size() < numVertices)
|
|
|
|
m->normals.resize(numVertices);
|
|
|
|
|
|
|
|
VertexArrayIterator<CVector3D> Position = psmdl->m_Position.GetIterator<CVector3D>();
|
|
|
|
VertexArrayIterator<CVector3D> Normal = VertexArrayIterator<CVector3D>((char*)&m->normals[0], sizeof(CVector3D));
|
|
|
|
|
|
|
|
ModelRenderer::BuildPositionAndNormals(model, Position, Normal);
|
|
|
|
|
|
|
|
VertexArrayIterator<SColor4ub> Color = psmdl->m_Color.GetIterator<SColor4ub>();
|
|
|
|
|
2006-03-26 01:54:20 +01:00
|
|
|
ModelRenderer::BuildColor4ub(model, Normal, Color, false);
|
2005-11-06 00:15:23 +01:00
|
|
|
|
|
|
|
// upload everything to vertex buffer
|
|
|
|
psmdl->m_Array.Upload();
|
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2006-01-22 20:12:30 +01:00
|
|
|
// resort model indices from back to front, according to the view camera position - and store
|
2005-11-06 00:15:23 +01:00
|
|
|
// the returned sqrd distance to the centre of the nearest triangle
|
2006-01-22 20:12:30 +01:00
|
|
|
// Use the view camera instead of the cull camera because:
|
|
|
|
// a) polygon sorting implicitly uses the view camera (and changing that would be costly)
|
|
|
|
// b) using the cull camera is likely not interesting from a debugging POV
|
2005-11-06 00:15:23 +01:00
|
|
|
PROFILE_START( "sorting transparent" );
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
CMatrix3D worldToCam;
|
2006-01-22 20:12:30 +01:00
|
|
|
g_Renderer.GetViewCamera().m_Orientation.GetInverse(worldToCam);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
psmdl->BackToFrontIndexSort(worldToCam);
|
|
|
|
PROFILE_END( "sorting transparent" );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Cleanup per-CModel data
|
|
|
|
void PolygonSortModelRenderer::DestroyModelData(CModel* UNUSED(model), void* data)
|
|
|
|
{
|
|
|
|
PSModel* psmdl = (PSModel*)data;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
delete psmdl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Prepare for one rendering pass
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void PolygonSortModelRenderer::BeginPass(int streamflags, const CMatrix3D* texturematrix)
|
2005-11-06 00:15:23 +01:00
|
|
|
{
|
2007-02-09 18:04:55 +01:00
|
|
|
debug_assert(streamflags == (streamflags & (STREAM_POS|STREAM_COLOR|STREAM_UV0|STREAM_TEXGENTOUV1)));
|
2006-03-26 01:54:20 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
|
|
|
|
if (streamflags & STREAM_UV0) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
if (streamflags & STREAM_COLOR) glEnableClientState(GL_COLOR_ARRAY);
|
2007-02-09 18:04:55 +01:00
|
|
|
if (streamflags & STREAM_TEXGENTOUV1)
|
|
|
|
{
|
|
|
|
pglActiveTextureARB(GL_TEXTURE1);
|
|
|
|
pglClientActiveTextureARB(GL_TEXTURE1);
|
|
|
|
|
|
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadMatrixf(&texturematrix->_11);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
|
|
|
|
pglActiveTextureARB(GL_TEXTURE0);
|
|
|
|
pglClientActiveTextureARB(GL_TEXTURE0);
|
|
|
|
}
|
2005-11-06 00:15:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Cleanup rendering
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void PolygonSortModelRenderer::EndPass(int streamflags)
|
2005-11-06 00:15:23 +01:00
|
|
|
{
|
|
|
|
if (streamflags & STREAM_UV0) glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
if (streamflags & STREAM_COLOR) glDisableClientState(GL_COLOR_ARRAY);
|
2007-02-09 18:04:55 +01:00
|
|
|
if (streamflags & STREAM_TEXGENTOUV1)
|
|
|
|
{
|
|
|
|
pglActiveTextureARB(GL_TEXTURE1);
|
|
|
|
pglClientActiveTextureARB(GL_TEXTURE1);
|
|
|
|
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
|
|
|
|
pglActiveTextureARB(GL_TEXTURE0);
|
|
|
|
pglClientActiveTextureARB(GL_TEXTURE0);
|
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Prepare for rendering models using this CModelDef
|
2008-07-17 16:23:51 +02:00
|
|
|
void PolygonSortModelRenderer::PrepareModelDef(int streamflags, const CModelDefPtr& def)
|
2005-11-06 00:15:23 +01:00
|
|
|
{
|
|
|
|
if (streamflags & STREAM_UV0)
|
|
|
|
{
|
|
|
|
PSModelDef* psmdef = (PSModelDef*)def->GetRenderData(m);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
debug_assert(psmdef);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
u8* base = psmdef->m_Array.Bind();
|
|
|
|
GLsizei stride = (GLsizei)psmdef->m_Array.GetStride();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
glTexCoordPointer(2, GL_FLOAT, stride, base + psmdef->m_UV.offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Render one model
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void PolygonSortModelRenderer::RenderModel(int streamflags, CModel* model, void* data)
|
2004-06-11 00:24:03 +02:00
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
CModelDefPtr mdef = model->GetModelDef();
|
|
|
|
PSModel* psmdl = (PSModel*)data;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
// Setup per-CModel arrays
|
|
|
|
u8* base = psmdl->m_Array.Bind();
|
|
|
|
GLsizei stride = (GLsizei)psmdl->m_Array.GetStride();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
glVertexPointer(3, GL_FLOAT, stride, base + psmdl->m_Position.offset);
|
|
|
|
if (streamflags & STREAM_COLOR)
|
2006-01-07 02:04:26 +01:00
|
|
|
glColorPointer(3, psmdl->m_Color.type, stride, base + psmdl->m_Color.offset);
|
2007-02-09 18:04:55 +01:00
|
|
|
if (streamflags & STREAM_TEXGENTOUV1)
|
|
|
|
{
|
|
|
|
pglClientActiveTextureARB(GL_TEXTURE1);
|
|
|
|
pglActiveTextureARB(GL_TEXTURE1);
|
|
|
|
glTexCoordPointer(3, GL_FLOAT, stride, base + psmdl->m_Position.offset);
|
|
|
|
pglClientActiveTextureARB(GL_TEXTURE0);
|
|
|
|
pglActiveTextureARB(GL_TEXTURE0);
|
|
|
|
}
|
2005-11-06 00:15:23 +01:00
|
|
|
|
|
|
|
// render the lot
|
|
|
|
size_t numFaces = mdef->GetNumFaces();
|
|
|
|
|
2006-09-23 18:04:54 +02:00
|
|
|
if (!g_Renderer.m_SkipSubmit) {
|
|
|
|
pglDrawRangeElementsEXT(GL_TRIANGLES, 0, (GLuint)mdef->GetNumVertices(),
|
|
|
|
(GLsizei)numFaces*3, GL_UNSIGNED_SHORT, psmdl->m_Indices);
|
|
|
|
}
|
|
|
|
|
|
|
|
// bump stats
|
2005-11-06 00:15:23 +01:00
|
|
|
g_Renderer.m_Stats.m_DrawCalls++;
|
|
|
|
g_Renderer.m_Stats.m_ModelTris += numFaces;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// SortModelRenderer implementation
|
2005-05-20 19:09:47 +02:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
/**
|
|
|
|
* Struct SModel: Per-CModel data for the model-sorting renderer
|
|
|
|
*/
|
|
|
|
struct SModel : public CModelRData
|
|
|
|
{
|
|
|
|
SModel(SortModelRendererInternals* tri, CModel* model);
|
|
|
|
~SModel();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
// Back-link to the Model renderer
|
|
|
|
SortModelRendererInternals* m_SMRI;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
// Private data of the ModelVertexRenderer
|
|
|
|
void* m_Data;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
// Distance to camera (for sorting)
|
|
|
|
float m_Distance;
|
2005-10-25 03:43:07 +02:00
|
|
|
};
|
2004-06-07 21:53:58 +02:00
|
|
|
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
2005-11-06 00:15:23 +01:00
|
|
|
* Struct SortModelRendererInternals: Internal data structure of SortModelRenderer
|
2005-10-25 03:43:07 +02:00
|
|
|
*/
|
2005-11-06 00:15:23 +01:00
|
|
|
struct SortModelRendererInternals
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
/// Vertex renderer used for transform and lighting
|
|
|
|
ModelVertexRendererPtr vertexRenderer;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
/// List of submitted models.
|
|
|
|
std::vector<SModel*> models;
|
2005-10-25 03:43:07 +02:00
|
|
|
};
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
|
|
|
|
SModel::SModel(SortModelRendererInternals* smri, CModel* model)
|
|
|
|
: CModelRData(smri, model), m_SMRI(smri)
|
|
|
|
{
|
|
|
|
m_Data = m_SMRI->vertexRenderer->CreateModelData(model);
|
|
|
|
m_Distance = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SModel::~SModel()
|
|
|
|
{
|
|
|
|
m_SMRI->vertexRenderer->DestroyModelData(GetModel(), m_Data);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// Construction / Destruction
|
2005-11-06 00:15:23 +01:00
|
|
|
SortModelRenderer::SortModelRenderer(ModelVertexRendererPtr vertexRenderer)
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
m = new SortModelRendererInternals;
|
|
|
|
m->vertexRenderer = vertexRenderer;
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
SortModelRenderer::~SortModelRenderer()
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
|
|
|
delete m;
|
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// Submit a model: Create, but don't fill in, our own Model and ModelDef structures
|
2005-11-06 00:15:23 +01:00
|
|
|
void SortModelRenderer::Submit(CModel* model)
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
|
|
|
CModelRData* rdata = (CModelRData*)model->GetRenderData();
|
2005-11-06 00:15:23 +01:00
|
|
|
SModel* smdl;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
if (rdata && rdata->GetKey() == m)
|
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
smdl = (SModel*)rdata;
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
smdl = new SModel(m, model);
|
|
|
|
rdata = smdl;
|
2005-10-25 03:43:07 +02:00
|
|
|
model->SetRenderData(rdata);
|
2005-10-31 17:26:51 +01:00
|
|
|
model->SetDirty(~0u);
|
2005-10-25 03:43:07 +02:00
|
|
|
g_Renderer.LoadTexture(model->GetTexture(), GL_CLAMP_TO_EDGE);
|
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
m->models.push_back(smdl);
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// Transform and sort all models
|
2005-11-06 00:15:23 +01:00
|
|
|
struct SortModelsByDist {
|
|
|
|
bool operator()(SModel* lhs, SModel* rhs) {
|
2007-02-10 19:26:57 +01:00
|
|
|
// Sort by distance, and break ties by comparing pointers
|
|
|
|
return lhs->m_Distance > rhs->m_Distance ? true
|
|
|
|
: lhs->m_Distance < rhs->m_Distance ? false
|
|
|
|
: (lhs > rhs);
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
|
|
|
};
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
void SortModelRenderer::PrepareModels()
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
|
|
|
CMatrix3D worldToCam;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
if (m->models.size() == 0)
|
2005-10-25 04:22:22 +02:00
|
|
|
return;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2006-01-22 20:12:30 +01:00
|
|
|
g_Renderer.GetViewCamera().m_Orientation.GetInverse(worldToCam);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
for(std::vector<SModel*>::iterator it = m->models.begin(); it != m->models.end(); ++it)
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
SModel* smdl = *it;
|
|
|
|
CModel* model = smdl->GetModel();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
debug_assert(model->GetRenderData() == smdl);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
m->vertexRenderer->UpdateModelData(model, smdl->m_Data, smdl->m_UpdateFlags);
|
|
|
|
smdl->m_UpdateFlags = 0;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
CVector3D modelpos = model->GetTransform().GetTranslation();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
modelpos = worldToCam.Transform(modelpos);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
smdl->m_Distance = modelpos.Z;
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
2004-10-17 23:01:00 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
PROFILE_START( "sorting transparent" );
|
2005-11-06 00:15:23 +01:00
|
|
|
std::sort(m->models.begin(), m->models.end(), SortModelsByDist());
|
2005-10-25 03:43:07 +02:00
|
|
|
PROFILE_END( "sorting transparent" );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
// Cleanup per-frame model list
|
|
|
|
void SortModelRenderer::EndFrame()
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
m->models.clear();
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Return whether models have been submitted this frame
|
2005-11-06 00:15:23 +01:00
|
|
|
bool SortModelRenderer::HaveSubmissions()
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
return m->models.size() != 0;
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// Render submitted models (filtered by flags) using the given modifier
|
2008-07-17 16:23:51 +02:00
|
|
|
void SortModelRenderer::Render(const RenderModifierPtr& modifier, int flags)
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
int pass = 0;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
if (m->models.size() == 0)
|
2005-10-25 03:43:07 +02:00
|
|
|
return;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
do
|
|
|
|
{
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
int streamflags = modifier->BeginPass(pass);
|
2006-03-26 01:54:20 +01:00
|
|
|
const CMatrix3D* texturematrix = 0;
|
2005-10-25 03:43:07 +02:00
|
|
|
CModelDefPtr lastmdef;
|
|
|
|
CTexture* lasttex = 0;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2006-03-26 01:54:20 +01:00
|
|
|
if (streamflags & STREAM_TEXGENTOUV1)
|
|
|
|
texturematrix = modifier->GetTexGenMatrix(pass);
|
|
|
|
|
|
|
|
m->vertexRenderer->BeginPass(streamflags, texturematrix);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
for(std::vector<SModel*>::iterator it = m->models.begin(); it != m->models.end(); ++it)
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
SModel* smdl = *it;
|
|
|
|
CModel* mdl = smdl->GetModel();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
if (flags & !(mdl->GetFlags() & flags))
|
2005-10-25 03:43:07 +02:00
|
|
|
continue;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
debug_assert(smdl->GetKey() == m);
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
CModelDefPtr mdef = mdl->GetModelDef();
|
|
|
|
CTexture* tex = mdl->GetTexture();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// Prepare per-CModelDef data if changed
|
|
|
|
if (mdef != lastmdef)
|
|
|
|
{
|
2005-11-06 00:15:23 +01:00
|
|
|
m->vertexRenderer->PrepareModelDef(streamflags, mdef);
|
2005-10-25 03:43:07 +02:00
|
|
|
lastmdef = mdef;
|
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// Prepare necessary RenderModifier stuff
|
|
|
|
if (tex != lasttex)
|
|
|
|
{
|
|
|
|
modifier->PrepareTexture(pass, tex);
|
|
|
|
lasttex = tex;
|
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
modifier->PrepareModel(pass, mdl);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
// Render the model
|
|
|
|
m->vertexRenderer->RenderModel(streamflags, mdl, smdl->m_Data);
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
m->vertexRenderer->EndPass(streamflags);
|
2005-10-25 03:43:07 +02:00
|
|
|
} while(!modifier->EndPass(pass++));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// TransparentRenderModifier implementation
|
|
|
|
|
|
|
|
TransparentRenderModifier::TransparentRenderModifier()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TransparentRenderModifier::~TransparentRenderModifier()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
int TransparentRenderModifier::BeginPass(int pass)
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
|
|
|
if (pass == 0)
|
|
|
|
{
|
|
|
|
// First pass: Put down Z for opaque parts of the model,
|
|
|
|
// don't touch the color buffer.
|
2006-05-29 02:49:09 +02:00
|
|
|
|
|
|
|
glDepthMask(1);
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
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_CONSTANT);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
|
|
|
|
|
|
|
// just pass through texture's alpha
|
|
|
|
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);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
glEnable(GL_ALPHA_TEST);
|
|
|
|
glAlphaFunc(GL_GREATER,0.975f);
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// render everything with color writes off to setup depth buffer correctly
|
|
|
|
glColorMask(0,0,0,0);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
return STREAM_POS|STREAM_UV0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Second pass: Put down color, disable Z write
|
|
|
|
glColorMask(1,1,1,1);
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
glDepthMask(0);
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// setup texture environment to modulate diffuse color with texture color
|
|
|
|
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);
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
glAlphaFunc(GL_GREATER,0);
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
// Set the proper LOD bias
|
|
|
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
return STREAM_POS|STREAM_COLOR|STREAM_UV0;
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
bool TransparentRenderModifier::EndPass(int pass)
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
|
|
|
if (pass == 0)
|
|
|
|
return false; // multi-pass
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glDisable(GL_ALPHA_TEST);
|
|
|
|
glDepthMask(1);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void TransparentRenderModifier::PrepareTexture(int UNUSED(pass), CTexture* texture)
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2005-10-25 03:43:07 +02:00
|
|
|
g_Renderer.SetTexture(0, texture);
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void TransparentRenderModifier::PrepareModel(int UNUSED(pass), CModel* UNUSED(model))
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 06:05:07 +01:00
|
|
|
// No per-model setup necessary
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
|
2006-03-26 01:54:20 +01:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// LitTransparentRenderModifier implementation
|
|
|
|
|
|
|
|
LitTransparentRenderModifier::LitTransparentRenderModifier()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
LitTransparentRenderModifier::~LitTransparentRenderModifier()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
int LitTransparentRenderModifier::BeginPass(int pass)
|
2006-03-26 01:54:20 +01:00
|
|
|
{
|
|
|
|
debug_assert(GetShadowMap() && GetShadowMap()->GetUseDepthTexture());
|
|
|
|
|
|
|
|
if (pass == 0)
|
|
|
|
{
|
|
|
|
// First pass: Put down Z for opaque parts of the model,
|
|
|
|
// don't touch the color buffer.
|
|
|
|
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_CONSTANT);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
|
|
|
|
|
|
|
// just pass through texture's alpha
|
|
|
|
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);
|
|
|
|
|
|
|
|
glEnable(GL_ALPHA_TEST);
|
|
|
|
glAlphaFunc(GL_GREATER,0.975f);
|
|
|
|
|
|
|
|
// render everything with color writes off to setup depth buffer correctly
|
|
|
|
glColorMask(0,0,0,0);
|
|
|
|
|
|
|
|
return STREAM_POS|STREAM_UV0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Second pass: Put down color, disable Z write
|
|
|
|
glColorMask(1,1,1,1);
|
|
|
|
|
|
|
|
glDepthMask(0);
|
|
|
|
|
|
|
|
// Ambient + Diffuse * Shadow
|
|
|
|
pglActiveTextureARB(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_PRIMARY_COLOR);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE1);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
|
|
|
|
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);
|
|
|
|
|
|
|
|
pglActiveTextureARB(GL_TEXTURE1);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, GetShadowMap()->GetTexture());
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
|
|
|
|
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &GetLightEnv()->m_UnitsAmbientColor.X);
|
|
|
|
|
|
|
|
// Incoming color is ambient + diffuse light
|
|
|
|
pglActiveTextureARB(GL_TEXTURE2);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, GetShadowMap()->GetTexture());
|
|
|
|
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_TEXTURE0);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
|
|
|
|
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE0);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
|
|
|
|
|
|
|
pglActiveTextureARB(GL_TEXTURE0);
|
|
|
|
|
|
|
|
glAlphaFunc(GL_GREATER,0);
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
|
|
|
// Set the proper LOD bias
|
|
|
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
|
|
|
|
|
|
|
|
return STREAM_POS|STREAM_COLOR|STREAM_UV0|STREAM_TEXGENTOUV1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
bool LitTransparentRenderModifier::EndPass(int pass)
|
2006-03-26 01:54:20 +01:00
|
|
|
{
|
|
|
|
if (pass == 0)
|
|
|
|
return false; // multi-pass
|
|
|
|
|
|
|
|
pglActiveTextureARB(GL_TEXTURE1);
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
pglActiveTextureARB(GL_TEXTURE2);
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
pglActiveTextureARB(GL_TEXTURE0);
|
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glDisable(GL_ALPHA_TEST);
|
|
|
|
glDepthMask(1);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
const CMatrix3D* LitTransparentRenderModifier::GetTexGenMatrix(int UNUSED(pass))
|
2006-03-26 01:54:20 +01:00
|
|
|
{
|
|
|
|
return &GetShadowMap()->GetTextureMatrix();
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void LitTransparentRenderModifier::PrepareTexture(int UNUSED(pass), CTexture* texture)
|
2006-03-26 01:54:20 +01:00
|
|
|
{
|
|
|
|
g_Renderer.SetTexture(0, texture);
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void LitTransparentRenderModifier::PrepareModel(int UNUSED(pass), CModel* UNUSED(model))
|
2006-03-26 01:54:20 +01:00
|
|
|
{
|
|
|
|
// No per-model setup necessary
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// TransparentShadowRenderModifier implementation
|
|
|
|
|
|
|
|
TransparentShadowRenderModifier::TransparentShadowRenderModifier()
|
|
|
|
{
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
2004-10-21 17:04:19 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
TransparentShadowRenderModifier::~TransparentShadowRenderModifier()
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
int TransparentShadowRenderModifier::BeginPass(int pass)
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
|
|
|
debug_assert(pass == 0);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2004-05-30 02:46:58 +02:00
|
|
|
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);
|
2004-06-07 21:53:58 +02:00
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
2004-05-30 02:46:58 +02:00
|
|
|
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);
|
|
|
|
|
2004-10-21 17:04:19 +02:00
|
|
|
// Set the proper LOD bias
|
|
|
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
|
2004-10-17 23:01:00 +02:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
return STREAM_POS|STREAM_UV0;
|
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
bool TransparentShadowRenderModifier::EndPass(int UNUSED(pass))
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2004-05-30 02:46:58 +02:00
|
|
|
glDepthMask(1);
|
|
|
|
glDisable(GL_BLEND);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
return true;
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void TransparentShadowRenderModifier::PrepareTexture(int UNUSED(pass), CTexture* texture)
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2005-10-25 03:43:07 +02:00
|
|
|
g_Renderer.SetTexture(0, texture);
|
2004-06-11 04:14:18 +02:00
|
|
|
}
|
2005-10-25 03:43:07 +02:00
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void TransparentShadowRenderModifier::PrepareModel(int UNUSED(pass), CModel* UNUSED(model))
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2005-11-06 06:05:07 +01:00
|
|
|
// No per-model setup necessary
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
2006-02-11 19:04:32 +01:00
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// TransparentDepthShadowModifier implementation
|
|
|
|
|
|
|
|
TransparentDepthShadowModifier::TransparentDepthShadowModifier()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TransparentDepthShadowModifier::~TransparentDepthShadowModifier()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
int TransparentDepthShadowModifier::BeginPass(int pass)
|
2006-02-11 19:04:32 +01:00
|
|
|
{
|
|
|
|
debug_assert(pass == 0);
|
|
|
|
|
|
|
|
glEnable(GL_ALPHA_TEST);
|
2006-02-19 22:16:54 +01:00
|
|
|
glAlphaFunc(GL_GREATER, 0.4f);
|
2006-02-11 19:04:32 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
return STREAM_POS|STREAM_UV0;
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
bool TransparentDepthShadowModifier::EndPass(int UNUSED(pass))
|
2006-02-11 19:04:32 +01:00
|
|
|
{
|
|
|
|
glDisable(GL_ALPHA_TEST);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void TransparentDepthShadowModifier::PrepareTexture(int UNUSED(pass), CTexture* texture)
|
2006-02-11 19:04:32 +01:00
|
|
|
{
|
|
|
|
g_Renderer.SetTexture(0, texture);
|
|
|
|
}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void TransparentDepthShadowModifier::PrepareModel(int UNUSED(pass), CModel* UNUSED(model))
|
2006-02-11 19:04:32 +01:00
|
|
|
{
|
|
|
|
// No per-model setup necessary
|
|
|
|
}
|