2004-06-03 20:38:14 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
2005-06-28 06:06:25 +02:00
|
|
|
|
2004-05-30 02:46:58 +02:00
|
|
|
#include <algorithm>
|
2005-08-12 19:06:53 +02:00
|
|
|
#include "lib/res/graphics/ogl_tex.h"
|
2004-05-30 02:46:58 +02:00
|
|
|
#include "Renderer.h"
|
|
|
|
#include "TransparencyRenderer.h"
|
2005-01-24 07:14:13 +01:00
|
|
|
#include "PlayerRenderer.h"
|
2004-05-30 02:46:58 +02:00
|
|
|
#include "ModelRData.h"
|
|
|
|
#include "Model.h"
|
2004-12-12 20:43:55 +01:00
|
|
|
#include "ModelDef.h"
|
2004-09-24 05:52:32 +02:00
|
|
|
#include "MaterialManager.h"
|
2005-05-20 19:09:47 +02:00
|
|
|
#include "Profile.h"
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
// shared list of all submitted models this frame
|
|
|
|
std::vector<CModel*> CModelRData::m_Models;
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
// CModelRData constructor
|
2004-05-30 02:46:58 +02:00
|
|
|
CModelRData::CModelRData(CModel* model)
|
|
|
|
: m_Model(model), m_Vertices(0), m_Normals(0), m_Indices(0), m_VB(0), m_Flags(0)
|
|
|
|
{
|
2005-06-28 06:06:25 +02:00
|
|
|
debug_assert(model);
|
2004-05-30 02:46:58 +02:00
|
|
|
// build all data now
|
|
|
|
Build();
|
|
|
|
}
|
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
// CModelRData destructor
|
2004-05-30 02:46:58 +02:00
|
|
|
CModelRData::~CModelRData()
|
2004-06-11 00:24:03 +02:00
|
|
|
{
|
2004-06-07 21:53:58 +02:00
|
|
|
// clean up system copies of data
|
2004-05-30 02:46:58 +02:00
|
|
|
delete[] m_Indices;
|
|
|
|
delete[] m_Vertices;
|
|
|
|
delete[] m_Normals;
|
2004-06-11 00:24:03 +02:00
|
|
|
if (m_VB) {
|
|
|
|
// release vertex buffer chunks
|
2004-06-07 21:53:58 +02:00
|
|
|
g_VBMan.Release(m_VB);
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CModelRData::Build()
|
|
|
|
{
|
|
|
|
// build data
|
|
|
|
BuildVertices();
|
|
|
|
BuildIndices();
|
2005-02-10 00:19:48 +01:00
|
|
|
// force a texture load on model's texture
|
2004-05-30 02:46:58 +02:00
|
|
|
g_Renderer.LoadTexture(m_Model->GetTexture(),GL_CLAMP_TO_EDGE);
|
|
|
|
// setup model render flags
|
2004-09-24 05:52:32 +02:00
|
|
|
/*if (g_Renderer.IsTextureTransparent(m_Model->GetTexture())) {
|
2004-05-30 02:46:58 +02:00
|
|
|
m_Flags|=MODELRDATA_FLAG_TRANSPARENT;
|
2004-09-24 05:52:32 +02:00
|
|
|
}*/
|
2005-01-27 03:52:26 +01:00
|
|
|
if(m_Model->GetMaterial().IsPlayer())
|
|
|
|
{
|
2005-01-24 07:14:13 +01:00
|
|
|
m_Flags |= MODELRDATA_FLAG_PLAYERCOLOR;
|
2005-01-27 03:52:26 +01:00
|
|
|
}
|
2005-01-24 07:14:13 +01:00
|
|
|
else if(m_Model->GetMaterial().UsesAlpha())
|
2005-01-27 03:52:26 +01:00
|
|
|
{
|
2004-09-24 05:52:32 +02:00
|
|
|
m_Flags |= MODELRDATA_FLAG_TRANSPARENT;
|
2005-01-27 03:52:26 +01:00
|
|
|
}
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CModelRData::BuildIndices()
|
2004-06-07 21:53:58 +02:00
|
|
|
{
|
2004-12-12 19:40:00 +01:00
|
|
|
CModelDefPtr mdef=m_Model->GetModelDef();
|
2005-06-28 06:06:25 +02:00
|
|
|
debug_assert(mdef);
|
2004-06-11 00:24:03 +02:00
|
|
|
|
|
|
|
// must have a valid vertex buffer by this point so we know where indices are supposed to start
|
2005-06-28 06:06:25 +02:00
|
|
|
debug_assert(m_VB);
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2004-05-30 02:46:58 +02:00
|
|
|
// allocate indices if we haven't got any already
|
|
|
|
if (!m_Indices) {
|
|
|
|
m_Indices=new u16[mdef->GetNumFaces()*3];
|
|
|
|
}
|
|
|
|
|
|
|
|
// build indices
|
2004-06-11 04:14:18 +02:00
|
|
|
u32 base=(u32)m_VB->m_Index;
|
2004-05-30 02:46:58 +02:00
|
|
|
u32 indices=0;
|
|
|
|
SModelFace* faces=mdef->GetFaces();
|
2005-08-09 17:55:44 +02:00
|
|
|
for (size_t j=0; j<mdef->GetNumFaces(); j++) {
|
2004-05-30 02:46:58 +02:00
|
|
|
SModelFace& face=faces[j];
|
2004-06-07 21:53:58 +02:00
|
|
|
m_Indices[indices++]=face.m_Verts[0]+base;
|
|
|
|
m_Indices[indices++]=face.m_Verts[1]+base;
|
|
|
|
m_Indices[indices++]=face.m_Verts[2]+base;
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static SColor4ub ConvertColor(const RGBColor& src)
|
|
|
|
{
|
|
|
|
SColor4ub result;
|
|
|
|
result.R=clamp(int(src.X*255),0,255);
|
|
|
|
result.G=clamp(int(src.Y*255),0,255);
|
|
|
|
result.B=clamp(int(src.Z*255),0,255);
|
|
|
|
result.A=0xff;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// SkinPoint: skin the vertex position using it's blend data and given bone matrices
|
2004-06-07 21:53:58 +02:00
|
|
|
static void SkinPoint(const SModelVertex& vertex,const CMatrix3D* matrices,CVector3D& result)
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2004-06-11 00:24:03 +02:00
|
|
|
CVector3D tmp;
|
|
|
|
const SVertexBlend& blend=vertex.m_Blend;
|
|
|
|
|
|
|
|
// must have at least one valid bone if we're using SkinPoint
|
2005-06-28 06:06:25 +02:00
|
|
|
debug_assert(blend.m_Bone[0]!=0xff);
|
2004-06-11 00:24:03 +02:00
|
|
|
|
|
|
|
const CMatrix3D& m=matrices[blend.m_Bone[0]];
|
|
|
|
m.Transform(vertex.m_Coords,result);
|
|
|
|
result*=blend.m_Weight[0];
|
|
|
|
|
2005-07-02 23:42:55 +02:00
|
|
|
for (u32 i=1; i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff; i++) {
|
2004-06-11 00:24:03 +02:00
|
|
|
const CMatrix3D& m=matrices[blend.m_Bone[i]];
|
|
|
|
m.Transform(vertex.m_Coords,tmp);
|
|
|
|
result+=tmp*blend.m_Weight[i];
|
|
|
|
}
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// SkinPoint: skin the vertex normal using it's blend data and given bone matrices
|
2004-06-07 21:53:58 +02:00
|
|
|
static void SkinNormal(const SModelVertex& vertex,const CMatrix3D* invmatrices,CVector3D& result)
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2004-06-07 21:53:58 +02:00
|
|
|
CVector3D tmp;
|
2004-06-11 00:24:03 +02:00
|
|
|
const SVertexBlend& blend=vertex.m_Blend;
|
|
|
|
|
|
|
|
// must have at least one valid bone if we're using SkinNormal
|
2005-06-28 06:06:25 +02:00
|
|
|
debug_assert(blend.m_Bone[0]!=0xff);
|
2004-06-11 00:24:03 +02:00
|
|
|
|
|
|
|
const CMatrix3D& m=invmatrices[blend.m_Bone[0]];
|
|
|
|
m.RotateTransposed(vertex.m_Norm,result);
|
|
|
|
result*=blend.m_Weight[0];
|
2004-06-07 21:53:58 +02:00
|
|
|
|
2005-07-02 23:42:55 +02:00
|
|
|
for (u32 i=1; i<SVertexBlend::SIZE && vertex.m_Blend.m_Bone[i]!=0xff; i++) {
|
2004-06-07 21:53:58 +02:00
|
|
|
const CMatrix3D& m=invmatrices[blend.m_Bone[i]];
|
2004-05-30 02:46:58 +02:00
|
|
|
m.RotateTransposed(vertex.m_Norm,tmp);
|
2004-06-07 21:53:58 +02:00
|
|
|
result+=tmp*blend.m_Weight[i];
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CModelRData::BuildVertices()
|
|
|
|
{
|
2004-12-12 19:40:00 +01:00
|
|
|
CModelDefPtr mdef=m_Model->GetModelDef();
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
// allocate vertices if we haven't got any already
|
|
|
|
if (!m_Vertices) {
|
|
|
|
m_Vertices=new SVertex[mdef->GetNumVertices()];
|
|
|
|
m_Normals=new CVector3D[mdef->GetNumVertices()];
|
|
|
|
}
|
|
|
|
|
|
|
|
// build vertices
|
2005-08-09 17:55:44 +02:00
|
|
|
size_t numVertices=mdef->GetNumVertices();
|
2004-05-30 02:46:58 +02:00
|
|
|
SModelVertex* vertices=mdef->GetVertices();
|
2004-06-11 00:24:03 +02:00
|
|
|
const CMatrix3D* bonematrices=m_Model->GetBoneMatrices();
|
2004-06-07 21:53:58 +02:00
|
|
|
if (bonematrices) {
|
2004-06-11 00:24:03 +02:00
|
|
|
// boned model - calculate skinned vertex positions/normals
|
2005-05-20 19:09:47 +02:00
|
|
|
PROFILE( "skinning bones" );
|
2004-06-07 21:53:58 +02:00
|
|
|
const CMatrix3D* invbonematrices=m_Model->GetInvBoneMatrices();
|
2005-08-09 17:55:44 +02:00
|
|
|
for (size_t j=0; j<numVertices; j++) {
|
2004-06-07 21:53:58 +02:00
|
|
|
SkinPoint(vertices[j],bonematrices,m_Vertices[j].m_Position);
|
|
|
|
SkinNormal(vertices[j],invbonematrices,m_Normals[j]);
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// just copy regular positions, transform normals to world space
|
2004-06-11 00:24:03 +02:00
|
|
|
const CMatrix3D& transform=m_Model->GetTransform();
|
2004-06-07 21:53:58 +02:00
|
|
|
const CMatrix3D& invtransform=m_Model->GetInvTransform();
|
2004-05-30 02:46:58 +02:00
|
|
|
for (uint j=0; j<numVertices; j++) {
|
2004-06-07 21:53:58 +02:00
|
|
|
transform.Transform(vertices[j].m_Coords,m_Vertices[j].m_Position);
|
|
|
|
invtransform.RotateTransposed(vertices[j].m_Norm,m_Normals[j]);
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-20 19:09:47 +02:00
|
|
|
PROFILE_START( "lighting vertices" );
|
2004-05-30 02:46:58 +02:00
|
|
|
// now fill in UV and vertex colour data
|
|
|
|
for (uint j=0; j<numVertices; j++) {
|
|
|
|
m_Vertices[j].m_UVs[0]=vertices[j].m_U;
|
|
|
|
m_Vertices[j].m_UVs[1]=1-vertices[j].m_V;
|
|
|
|
g_Renderer.m_SHCoeffsUnits.Evaluate(m_Normals[j],m_Vertices[j].m_Color);
|
|
|
|
}
|
2005-05-20 19:09:47 +02:00
|
|
|
PROFILE_END( "lighting vertices" );
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2004-06-07 21:53:58 +02:00
|
|
|
// upload everything to vertex buffer - create one if necessary
|
2004-06-11 00:24:03 +02:00
|
|
|
if (!m_VB) {
|
|
|
|
m_VB=g_VBMan.Allocate(sizeof(SVertex),mdef->GetNumVertices(),mdef->GetNumBones() ? true : false);
|
|
|
|
}
|
2004-06-07 21:53:58 +02:00
|
|
|
m_VB->m_Owner->UpdateChunkVertices(m_VB,m_Vertices);
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-01-24 07:14:13 +01:00
|
|
|
void CModelRData::RenderStreams(u32 streamflags, bool isplayer)
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2004-12-12 19:40:00 +01:00
|
|
|
CModelDefPtr mdldef=m_Model->GetModelDef();
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2004-09-24 05:52:32 +02:00
|
|
|
if (streamflags & STREAM_UV0)
|
|
|
|
{
|
2005-01-24 07:14:13 +01:00
|
|
|
if(!isplayer)
|
|
|
|
m_Model->GetMaterial().Bind();
|
|
|
|
else
|
|
|
|
g_Renderer.SetTexture(1,m_Model->GetTexture());
|
|
|
|
|
2004-09-24 05:52:32 +02:00
|
|
|
g_Renderer.SetTexture(0,m_Model->GetTexture());
|
|
|
|
}
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2004-06-07 21:53:58 +02:00
|
|
|
u8* base=m_VB->m_Owner->Bind();
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
// set vertex pointers
|
|
|
|
u32 stride=sizeof(SVertex);
|
|
|
|
glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Position));
|
|
|
|
if (streamflags & STREAM_COLOR) glColorPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Color));
|
|
|
|
if (streamflags & STREAM_UV0) glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SVertex,m_UVs));
|
|
|
|
|
|
|
|
// render the lot
|
2005-08-09 17:55:44 +02:00
|
|
|
size_t numFaces=mdldef->GetNumFaces();
|
2004-05-30 02:46:58 +02:00
|
|
|
// glDrawRangeElements(GL_TRIANGLES,0,mdldef->GetNumVertices(),numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
2005-08-09 17:55:44 +02:00
|
|
|
glDrawElements(GL_TRIANGLES,(GLsizei)numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
2004-09-24 05:52:32 +02:00
|
|
|
|
2005-01-24 07:14:13 +01:00
|
|
|
if(streamflags & STREAM_UV0 & !isplayer)
|
|
|
|
m_Model->GetMaterial().Unbind();
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
// bump stats
|
|
|
|
g_Renderer.m_Stats.m_DrawCalls++;
|
2004-06-07 21:53:58 +02:00
|
|
|
g_Renderer.m_Stats.m_ModelTris+=numFaces;
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CModelRData::Update()
|
|
|
|
{
|
|
|
|
if (m_UpdateFlags!=0) {
|
|
|
|
// renderdata changed : rebuild necessary portions
|
|
|
|
if (m_UpdateFlags & RENDERDATA_UPDATE_VERTICES) {
|
|
|
|
BuildVertices();
|
|
|
|
}
|
|
|
|
if (m_UpdateFlags & RENDERDATA_UPDATE_INDICES) {
|
|
|
|
BuildIndices();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_UpdateFlags=0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef std::pair<int,float> IntFloatPair;
|
|
|
|
static std::vector<IntFloatPair> IndexSorter;
|
|
|
|
|
|
|
|
struct SortFacesByDist {
|
|
|
|
bool operator()(const IntFloatPair& lhs,const IntFloatPair& rhs) {
|
|
|
|
return lhs.second>rhs.second ? true : false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
float CModelRData::BackToFrontIndexSort(CMatrix3D& objToCam)
|
|
|
|
{
|
|
|
|
float mindist=1.0e30f;
|
|
|
|
CVector3D osvtx,csvtx;
|
|
|
|
|
2004-12-12 19:40:00 +01:00
|
|
|
CModelDefPtr mdldef=m_Model->GetModelDef();
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
SModelVertex* vtxs=mdldef->GetVertices();
|
|
|
|
|
2005-08-09 17:55:44 +02:00
|
|
|
size_t numFaces=mdldef->GetNumFaces();
|
2004-05-30 02:46:58 +02:00
|
|
|
SModelFace* faces=mdldef->GetFaces();
|
|
|
|
|
|
|
|
IndexSorter.reserve(numFaces);
|
|
|
|
|
|
|
|
SModelFace* facePtr=faces;
|
|
|
|
u32 i;
|
|
|
|
for (i=0;i<numFaces;i++)
|
|
|
|
{
|
|
|
|
osvtx=vtxs[facePtr->m_Verts[0]].m_Coords;
|
|
|
|
osvtx+=vtxs[facePtr->m_Verts[1]].m_Coords;
|
|
|
|
osvtx+=vtxs[facePtr->m_Verts[2]].m_Coords;
|
|
|
|
osvtx*=1.0f/3.0f;
|
|
|
|
|
|
|
|
csvtx=objToCam.Transform(osvtx);
|
|
|
|
float distsqrd=SQR(csvtx.X)+SQR(csvtx.Y)+SQR(csvtx.Z);
|
|
|
|
if (distsqrd<mindist) mindist=distsqrd;
|
|
|
|
|
|
|
|
IndexSorter.push_back(IntFloatPair(i,distsqrd));
|
|
|
|
facePtr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::sort(IndexSorter.begin(),IndexSorter.end(),SortFacesByDist());
|
|
|
|
|
|
|
|
// now build index list
|
|
|
|
u32 indices=0;
|
|
|
|
for (i=0;i<numFaces;i++) {
|
|
|
|
SModelFace& face=faces[IndexSorter[i].first];
|
2004-06-11 04:14:18 +02:00
|
|
|
m_Indices[indices++]=(u16)(face.m_Verts[0]+m_VB->m_Index);
|
|
|
|
m_Indices[indices++]=(u16)(face.m_Verts[1]+m_VB->m_Index);
|
|
|
|
m_Indices[indices++]=(u16)(face.m_Verts[2]+m_VB->m_Index);
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// clear list for next call
|
|
|
|
IndexSorter.clear();
|
|
|
|
|
|
|
|
return mindist;
|
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// SubmitBatches: submit batches for this model to the vertex buffer
|
|
|
|
void CModelRData::SubmitBatches()
|
|
|
|
{
|
2005-06-28 06:06:25 +02:00
|
|
|
debug_assert(m_VB);
|
2004-06-11 00:24:03 +02:00
|
|
|
m_VB->m_Owner->AppendBatch(m_VB,m_Model->GetTexture()->GetHandle(),m_Model->GetModelDef()->GetNumFaces()*3,m_Indices);
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// RenderModels: render all submitted models; assumes necessary client states already enabled,
|
|
|
|
// and texture environment already setup as required
|
2004-10-06 20:44:47 +02:00
|
|
|
void CModelRData::RenderModels(u32 streamflags,u32 flags)
|
2004-06-11 00:24:03 +02:00
|
|
|
{
|
|
|
|
uint i;
|
|
|
|
#if 1
|
|
|
|
// submit batches for each model to the vertex buffer
|
|
|
|
for (i=0;i<m_Models.size();++i) {
|
2004-10-06 20:44:47 +02:00
|
|
|
if (!flags || (m_Models[i]->GetFlags()&flags)) {
|
|
|
|
CModelRData* modeldata=(CModelRData*) m_Models[i]->GetRenderData();
|
|
|
|
modeldata->SubmitBatches();
|
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// step through all accumulated batches
|
|
|
|
const std::list<CVertexBuffer*>& buffers=g_VBMan.GetBufferList();
|
|
|
|
std::list<CVertexBuffer*>::const_iterator iter;
|
|
|
|
for (iter=buffers.begin();iter!=buffers.end();++iter) {
|
|
|
|
CVertexBuffer* buffer=*iter;
|
|
|
|
|
|
|
|
// any batches in this VB?
|
|
|
|
const std::vector<CVertexBuffer::Batch*>& batches=buffer->GetBatches();
|
|
|
|
if (batches.size()>0) {
|
|
|
|
u8* base=buffer->Bind();
|
|
|
|
|
|
|
|
// setup data pointers
|
|
|
|
u32 stride=sizeof(SVertex);
|
|
|
|
glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Position));
|
|
|
|
if (streamflags & STREAM_COLOR) glColorPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Color));
|
|
|
|
if (streamflags & STREAM_UV0) glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SVertex,m_UVs[0]));
|
|
|
|
|
|
|
|
// render each batch
|
|
|
|
for (i=0;i<batches.size();++i) {
|
|
|
|
const CVertexBuffer::Batch* batch=batches[i];
|
|
|
|
if (batch->m_IndexData.size()>0) {
|
2005-01-22 22:25:27 +01:00
|
|
|
if (streamflags & STREAM_UV0)
|
2005-09-02 04:58:40 +02:00
|
|
|
ogl_tex_bind(batch->m_Texture);
|
2005-01-24 09:28:03 +01:00
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
for (uint j=0;j<batch->m_IndexData.size();j++) {
|
2004-06-11 04:14:18 +02:00
|
|
|
glDrawElements(GL_TRIANGLES,(GLsizei)batch->m_IndexData[j].first,GL_UNSIGNED_SHORT,batch->m_IndexData[j].second);
|
2004-06-11 00:24:03 +02:00
|
|
|
g_Renderer.m_Stats.m_DrawCalls++;
|
2004-06-11 04:14:18 +02:00
|
|
|
g_Renderer.m_Stats.m_ModelTris+=(u32)batch->m_IndexData[j].first/2;
|
2004-06-11 00:24:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// everything rendered; empty out batch lists
|
|
|
|
g_VBMan.ClearBatchIndices();
|
|
|
|
#else
|
|
|
|
for (i=0;i<m_Models.size();++i) {
|
2004-10-06 20:44:47 +02:00
|
|
|
if (!flags || (m_Models[i]->GetFlags()&flags)) {
|
|
|
|
CModelRData* modeldata=(CModelRData*) m_Models[i]->GetRenderData();
|
|
|
|
modeldata->RenderStreams(streamflags);
|
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Submit: submit a model to render this frame
|
|
|
|
void CModelRData::Submit(CModel* model)
|
|
|
|
{
|
|
|
|
CModelRData* data=(CModelRData*) model->GetRenderData();
|
|
|
|
if (data==0) {
|
|
|
|
// no renderdata for model, create it now
|
2005-05-20 19:09:47 +02:00
|
|
|
PROFILE( "create render data" );
|
2004-06-11 00:24:03 +02:00
|
|
|
data=new CModelRData(model);
|
|
|
|
model->SetRenderData(data);
|
|
|
|
} else {
|
2005-05-20 19:09:47 +02:00
|
|
|
PROFILE( "update render data" );
|
2004-06-11 00:24:03 +02:00
|
|
|
data->Update();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data->GetFlags() & MODELRDATA_FLAG_TRANSPARENT) {
|
|
|
|
// add this mode to the transparency renderer for later processing - calculate
|
|
|
|
// transform matrix
|
|
|
|
g_TransparencyRenderer.Add(model);
|
2005-01-24 07:14:13 +01:00
|
|
|
} else if (data->GetFlags() & MODELRDATA_FLAG_PLAYERCOLOR) {
|
|
|
|
// add this model to the player renderer
|
|
|
|
g_PlayerRenderer.Add(model);
|
2004-06-11 00:24:03 +02:00
|
|
|
} else {
|
|
|
|
// add to regular model list
|
|
|
|
m_Models.push_back(model);
|
|
|
|
}
|
|
|
|
}
|