1
0
forked from 0ad/0ad

Add ARB_vertex_shader specific functions to glext_funcs.h

Add an "instancing" model renderer to improve rendering of
non-transparent,
unanimated models. This renderer is used when the vertexshader path is
rendering path is used.

This was SVN commit r3052.
This commit is contained in:
prefect 2005-10-30 00:22:22 +00:00
parent 998622ff54
commit 875cb3bca1
18 changed files with 619 additions and 8 deletions

View File

@ -0,0 +1,10 @@
vec4 InstancingPosition(vec4 position);
void main()
{
vec4 worldPos = InstancingPosition(gl_Vertex);
gl_FrontColor = gl_BackColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * worldPos;
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<Program>
<Shaders>
<Shader type="VERTEX_SHADER">shaders/instancing.vs</Shader>
<Shader type="VERTEX_SHADER">shaders/instancing_base.vs</Shader>
<Shader type="VERTEX_SHADER">shaders/shlight.vs</Shader>
</Shaders>
</Program>

View File

@ -0,0 +1,29 @@
// 3x4 part of the model-to-world matrix
attribute vec4 Instancing1;
attribute vec4 Instancing2;
attribute vec4 Instancing3;
// Calculate a normal that has been transformed for instancing
vec3 InstancingNormal(vec3 normal)
{
vec3 tmp;
tmp.x = dot(vec3(Instancing1), normal);
tmp.y = dot(vec3(Instancing2), normal);
tmp.z = dot(vec3(Instancing3), normal);
return tmp;
}
// Calculate position, transformed for instancing
vec4 InstancingPosition(vec4 position)
{
vec3 tmp;
tmp.x = dot(Instancing1, position);
tmp.y = dot(Instancing2, position);
tmp.z = dot(Instancing3, position);
return vec4(tmp, 1.0);
}

View File

@ -0,0 +1,14 @@
vec3 lighting(vec3 normal);
vec3 InstancingNormal(vec3 normal);
vec4 InstancingPosition(vec4 position);
void main()
{
vec3 normal = InstancingNormal(gl_Normal);
vec4 worldPos = InstancingPosition(gl_Vertex);
gl_FrontColor = gl_BackColor = vec4(lighting(normal),1.0) * gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * worldPos;
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<Program>
<Shaders>
<Shader type="VERTEX_SHADER">shaders/instancing_light.vs</Shader>
<Shader type="VERTEX_SHADER">shaders/instancing_base.vs</Shader>
<Shader type="VERTEX_SHADER">shaders/shlight.vs</Shader>
</Shaders>
</Program>

View File

@ -268,7 +268,6 @@ void CGameView::CameraLock(float x, float y, float z, bool smooth)
void CGameView::SubmitModelRecursive(CModel* model)
{
model->ValidatePosition();
g_Renderer.Submit(model);
const std::vector<CModel::Prop>& props=model->GetProps();

View File

@ -102,6 +102,53 @@ FUNC2(void, glGetUniformfvARB, glGetUniformfv, "2.0", (GLhandleARB programObj, G
FUNC2(void, glGetUniformivARB, glGetUniformiv, "2.0", (GLhandleARB programObj, GLint location, GLint *params))
FUNC2(void, glGetShaderSourceARB, glGetShaderSource, "2.0", (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source))
// GL_ARB_vertex_shader
FUNC2(void, glVertexAttrib1fARB, glVertexAttrib1f, "2.0", (GLuint index, GLfloat v0))
FUNC2(void, glVertexAttrib1sARB, glVertexAttrib1s, "2.0", (GLuint index, GLshort v0))
FUNC2(void, glVertexAttrib1dARB, glVertexAttrib1d, "2.0", (GLuint index, GLdouble v0))
FUNC2(void, glVertexAttrib2fARB, glVertexAttrib2f, "2.0", (GLuint index, GLfloat v0, GLfloat v1))
FUNC2(void, glVertexAttrib2sARB, glVertexAttrib2s, "2.0", (GLuint index, GLshort v0, GLshort v1))
FUNC2(void, glVertexAttrib2dARB, glVertexAttrib2d, "2.0", (GLuint index, GLdouble v0, GLdouble v1))
FUNC2(void, glVertexAttrib3fARB, glVertexAttrib3f, "2.0", (GLuint index, GLfloat v0, GLfloat v1, GLfloat v2))
FUNC2(void, glVertexAttrib3sARB, glVertexAttrib3s, "2.0", (GLuint index, GLshort v0, GLshort v1, GLshort v2))
FUNC2(void, glVertexAttrib3dARB, glVertexAttrib3d, "2.0", (GLuint index, GLdouble v0, GLdouble v1, GLdouble v2))
FUNC2(void, glVertexAttrib4fARB, glVertexAttrib4f, "2.0", (GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3))
FUNC2(void, glVertexAttrib4sARB, glVertexAttrib4s, "2.0", (GLuint index, GLshort v0, GLshort v1, GLshort v2, GLshort v3))
FUNC2(void, glVertexAttrib4dARB, glVertexAttrib4d, "2.0", (GLuint index, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3))
FUNC2(void, glVertexAttrib4NubARB, glVertexAttrib4Nub, "2.0", (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w))
FUNC2(void, glVertexAttrib1fvARB, glVertexAttrib1fv, "2.0", (GLuint index, const GLfloat *v))
FUNC2(void, glVertexAttrib1svARB, glVertexAttrib1sv, "2.0", (GLuint index, const GLshort *v))
FUNC2(void, glVertexAttrib1dvARB, glVertexAttrib1dv, "2.0", (GLuint index, const GLdouble *v))
FUNC2(void, glVertexAttrib2fvARB, glVertexAttrib2fv, "2.0", (GLuint index, const GLfloat *v))
FUNC2(void, glVertexAttrib2svARB, glVertexAttrib2sv, "2.0", (GLuint index, const GLshort *v))
FUNC2(void, glVertexAttrib2dvARB, glVertexAttrib2dv, "2.0", (GLuint index, const GLdouble *v))
FUNC2(void, glVertexAttrib3fvARB, glVertexAttrib3fv, "2.0", (GLuint index, const GLfloat *v))
FUNC2(void, glVertexAttrib3svARB, glVertexAttrib3sv, "2.0", (GLuint index, const GLshort *v))
FUNC2(void, glVertexAttrib3dvARB, glVertexAttrib3dv, "2.0", (GLuint index, const GLdouble *v))
FUNC2(void, glVertexAttrib4fvARB, glVertexAttrib4fv, "2.0", (GLuint index, const GLfloat *v))
FUNC2(void, glVertexAttrib4svARB, glVertexAttrib4sv, "2.0", (GLuint index, const GLshort *v))
FUNC2(void, glVertexAttrib4dvARB, glVertexAttrib4dv, "2.0", (GLuint index, const GLdouble *v))
FUNC2(void, glVertexAttrib4ivARB, glVertexAttrib4iv, "2.0", (GLuint index, const GLint *v))
FUNC2(void, glVertexAttrib4bvARB, glVertexAttrib4bv, "2.0", (GLuint index, const GLbyte *v))
FUNC2(void, glVertexAttrib4ubvARB, glVertexAttrib4ubv, "2.0", (GLuint index, const GLubyte *v))
FUNC2(void, glVertexAttrib4usvARB, glVertexAttrib4usv, "2.0", (GLuint index, const GLushort *v))
FUNC2(void, glVertexAttrib4uivARB, glVertexAttrib4uiv, "2.0", (GLuint index, const GLuint *v))
FUNC2(void, glVertexAttrib4NbvARB, glVertexAttrib4Nbv, "2.0", (GLuint index, const GLbyte *v))
FUNC2(void, glVertexAttrib4NsvARB, glVertexAttrib4Nsv, "2.0", (GLuint index, const GLshort *v))
FUNC2(void, glVertexAttrib4NivARB, glVertexAttrib4Niv, "2.0", (GLuint index, const GLint *v))
FUNC2(void, glVertexAttrib4NubvARB, glVertexAttrib4Nubv, "2.0", (GLuint index, const GLubyte *v))
FUNC2(void, glVertexAttrib4NusvARB, glVertexAttrib4Nusv, "2.0", (GLuint index, const GLushort *v))
FUNC2(void, glVertexAttrib4NuivARB, glVertexAttrib4Nuiv, "2.0", (GLuint index, const GLuint *v))
FUNC2(void, glVertexAttribPointerARB, glVertexAttribPointer, "2.0", (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer))
FUNC2(void, glEnableVertexAttribArrayARB, glEnableVertexAttribArray, "2.0", (GLuint index))
FUNC2(void, glDisableVertexAttribArrayARB, glDisableVertexAttribArray, "2.0", (GLuint index))
FUNC2(void, glBindAttribLocationARB, glBindAttribLocation, "2.0", (GLhandleARB programObj, GLuint index, const char *name))
FUNC2(void, glGetActiveAttribARB, glGetActiveAttrib, "2.0", (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, int *size, GLenum *type, char *name))
FUNC2(GLint, glGetAttribLocationARB, glGetAttribLocation, "2.0", (GLhandleARB programObj, const char *name))
FUNC2(void, glGetVertexAttribdvARB, glGetVertexAttribdv, "2.0", (GLuint index, GLenum pname, GLdouble *params))
FUNC2(void, glGetVertexAttribfvARB, glGetVertexAttribfv, "2.0", (GLuint index, GLenum pname, GLfloat *params))
FUNC2(void, glGetVertexAttribivARB, glGetVertexAttribiv, "2.0", (GLuint index, GLenum pname, GLint *params))
FUNC2(void, glGetVertexAttribPointervARB, glGetVertexAttribPointerv, "2.0", (GLuint index, GLenum pname, void **pointer))
#if OS_WIN
// WGL_EXT_swap_control

View File

@ -445,3 +445,12 @@ GLint ogl_program_get_uniform_location(Handle h, const char* name)
return glGetUniformLocationARB(p->id, name);
}
// Query vertex attribute information
GLint ogl_program_get_attrib_location(Handle h, const char* name)
{
H_DEREF(h, Ogl_Program, p);
return glGetAttribLocationARB(p->id, name);
}

View File

@ -47,4 +47,7 @@ int ogl_program_use(Handle h);
// Query uniform information
GLint ogl_program_get_uniform_location(Handle h, const char* name);
// Query vertex attribute information
GLint ogl_program_get_attrib_location(Handle h, const char* name);
#endif // OGL_SHADER_H__

View File

@ -17,8 +17,8 @@
struct HWLightingModelRendererInternals;
/**
* Class HWLightingModelRenderer: Render animated models using only
* OpenGL fixed function.
* Class HWLightingModelRenderer: Render animated models using vertex
* shaders for lighting.
*
* Use the RenderModifier to enable normal model rendering as well
* as player colour rendering using this model renderer.

View File

@ -0,0 +1,264 @@
/**
* =========================================================================
* File : InstancingModelRenderer.cpp
* Project : Pyrogenesis
* Description : Implementation of InstancingModelRenderer
*
* @author Nicolai Hähnle <nicolai@wildfiregames.com>
* =========================================================================
*/
#include "precompiled.h"
#include "ogl.h"
#include "lib/res/graphics/ogl_shader.h"
#include "Vector3D.h"
#include "Vector4D.h"
#include "ps/CLogger.h"
#include "graphics/Color.h"
#include "graphics/Model.h"
#include "graphics/ModelDef.h"
#include "renderer/InstancingModelRenderer.h"
#include "renderer/Renderer.h"
#include "renderer/RenderModifiers.h"
#include "renderer/RenderPathVertexShader.h"
#include "renderer/SHCoeffs.h"
#include "renderer/VertexArray.h"
#define LOG_CATEGORY "graphics"
///////////////////////////////////////////////////////////////////////////////////////////////
// InstancingModelRenderer implementation
struct IModelDef : public CModelDefRPrivate
{
/// Static per-CModel vertex array
VertexArray m_Array;
/// Position, normals and UV are all static
VertexArray::Attribute m_Position;
VertexArray::Attribute m_Normal;
VertexArray::Attribute m_UV;
/// Indices are the same for all models, so share them
u16* m_Indices;
IModelDef(CModelDefPtr mdef);
~IModelDef() { delete m_Indices; }
};
IModelDef::IModelDef(CModelDefPtr mdef)
: m_Array(false)
{
size_t numVertices = mdef->GetNumVertices();
m_Position.type = GL_FLOAT;
m_Position.elems = 3;
m_Array.AddAttribute(&m_Position);
m_Normal.type = GL_FLOAT;
m_Normal.elems = 3;
m_Array.AddAttribute(&m_Normal);
m_UV.type = GL_FLOAT;
m_UV.elems = 2;
m_Array.AddAttribute(&m_UV);
m_Array.SetNumVertices(numVertices);
m_Array.Layout();
VertexArrayIterator<CVector3D> Position = m_Position.GetIterator<CVector3D>();
VertexArrayIterator<CVector3D> Normal = m_Normal.GetIterator<CVector3D>();
VertexArrayIterator<float[2]> UVit = m_UV.GetIterator<float[2]>();
ModelRenderer::CopyPositionAndNormals(mdef, Position, Normal);
ModelRenderer::BuildUV(mdef, UVit);
m_Array.Upload();
m_Array.FreeBackingStore();
m_Indices = new u16[mdef->GetNumFaces()*3];
ModelRenderer::BuildIndices(mdef, m_Indices);
}
struct InstancingModelRendererInternals
{
/// Currently used RenderModifier
RenderModifierPtr modifier;
/// Current rendering pass
uint pass;
/// Streamflags required in this pass
uint streamflags;
/// Previously prepared modeldef
IModelDef* imodeldef;
};
// Construction and Destruction
InstancingModelRenderer::InstancingModelRenderer()
{
m = new InstancingModelRendererInternals;
}
InstancingModelRenderer::~InstancingModelRenderer()
{
delete m;
}
// Check hardware support
bool InstancingModelRenderer::IsAvailable()
{
return g_Renderer.m_VertexShader != 0;
}
// Render submitted models.
void InstancingModelRenderer::Render(RenderModifierPtr modifier, u32 flags)
{
if (!HaveSubmissions())
return;
// Save for later
m->modifier = modifier;
glEnableClientState(GL_VERTEX_ARRAY);
m->pass = 0;
do
{
m->streamflags = modifier->BeginPass(m->pass);
if (m->streamflags & STREAM_UV0) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (m->streamflags & STREAM_COLOR)
{
const RGBColor* coeffs = g_Renderer.m_SHCoeffsUnits.GetCoefficients();
int idx;
ogl_program_use(g_Renderer.m_VertexShader->m_InstancingLight);
idx = g_Renderer.m_VertexShader->m_InstancingLight_SHCoefficients;
glUniform3fvARB(idx, 9, (float*)coeffs);
glEnableClientState(GL_NORMAL_ARRAY);
}
else
{
ogl_program_use(g_Renderer.m_VertexShader->m_Instancing);
}
RenderAllModels(flags);
if (m->streamflags & STREAM_UV0) glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (m->streamflags & STREAM_COLOR) glDisableClientState(GL_NORMAL_ARRAY);
glUseProgramObjectARB(0);
} while(!modifier->EndPass(m->pass++));
glDisableClientState(GL_VERTEX_ARRAY);
}
// Build modeldef data if necessary - we have no per-CModel data
void* InstancingModelRenderer::CreateModelData(CModel* model)
{
CModelDefPtr mdef = model->GetModelDef();
IModelDef* imodeldef = (IModelDef*)mdef->GetRenderData(m);
debug_assert(!model->GetBoneMatrices());
if (!imodeldef)
{
imodeldef = new IModelDef(mdef);
mdef->SetRenderData(m, imodeldef);
}
}
void InstancingModelRenderer::UpdateModelData(CModel* model, void* data, u32 updateflags)
{
// We have no per-CModel data
}
void InstancingModelRenderer::DestroyModelData(CModel* model, void* data)
{
// We have no per-CModel data, and per-CModelDef data is deleted by the CModelDef
}
// Prepare UV coordinates for this modeldef
void InstancingModelRenderer::PrepareModelDef(CModelDefPtr def)
{
m->imodeldef = (IModelDef*)def->GetRenderData(m);
debug_assert(m->imodeldef);
u8* base = m->imodeldef->m_Array.Bind();
GLsizei stride = (GLsizei)m->imodeldef->m_Array.GetStride();
glVertexPointer(3, GL_FLOAT, stride, base + m->imodeldef->m_Position.offset);
if (m->streamflags & STREAM_COLOR)
{
glNormalPointer(GL_FLOAT, stride, base + m->imodeldef->m_Normal.offset);
}
if (m->streamflags & STREAM_UV0)
{
glTexCoordPointer(2, GL_FLOAT, stride, base + m->imodeldef->m_UV.offset);
}
}
// Call the modifier to prepare the given texture
void InstancingModelRenderer::PrepareTexture(CTexture* texture)
{
m->modifier->PrepareTexture(m->pass, texture);
}
// Render one model
void InstancingModelRenderer::RenderModel(CModel* model, void* data)
{
m->modifier->PrepareModel(m->pass, model);
CModelDefPtr mdldef = model->GetModelDef();
const CMatrix3D& mat = model->GetTransform();
RenderPathVertexShader* rpvs = g_Renderer.m_VertexShader;
if (m->streamflags & STREAM_COLOR)
{
CColor sc = model->GetShadingColor();
glColor3f(sc.r, sc.g, sc.b);
glVertexAttrib4fARB(rpvs->m_InstancingLight_Instancing1, mat._11, mat._12, mat._13, mat._14);
glVertexAttrib4fARB(rpvs->m_InstancingLight_Instancing2, mat._21, mat._22, mat._23, mat._24);
glVertexAttrib4fARB(rpvs->m_InstancingLight_Instancing3, mat._31, mat._32, mat._33, mat._34);
}
else
{
glVertexAttrib4fARB(rpvs->m_Instancing_Instancing1, mat._11, mat._12, mat._13, mat._14);
glVertexAttrib4fARB(rpvs->m_Instancing_Instancing2, mat._21, mat._22, mat._23, mat._24);
glVertexAttrib4fARB(rpvs->m_Instancing_Instancing3, mat._31, mat._32, mat._33, mat._34);
}
// render the lot
size_t numFaces = mdldef->GetNumFaces();
glDrawRangeElementsEXT(GL_TRIANGLES, 0, mdldef->GetNumVertices(),
numFaces*3, GL_UNSIGNED_SHORT, m->imodeldef->m_Indices);
// bump stats
g_Renderer.m_Stats.m_DrawCalls++;
g_Renderer.m_Stats.m_ModelTris += numFaces;
}

View File

@ -0,0 +1,75 @@
/**
* =========================================================================
* File : InstancingModelRenderer.h
* Project : Pyrogenesis
* Description : Special BatchModelRenderer that only works for non-animated
* : models, but performs all transformation in a vertex shader.
*
* @author Nicolai Hähnle <nicolai@wildfiregames.com>
* =========================================================================
*/
#ifndef INSTANCINGMODELRENDERER_H
#define INSTANCINGMODELRENDERER_H
#include "renderer/ModelRenderer.h"
struct InstancingModelRendererInternals;
/**
* Class InstancingModelRenderer: Render non-animated (but potentially
* moving models) using vertex shaders.
*
* Use the RenderModifier to enable normal model rendering as well
* as player colour rendering using this model renderer.
*
* @note You should verify hardware capabilities using IsAvailable
* before creating this model renderer.
*/
class InstancingModelRenderer : public BatchModelRenderer
{
public:
InstancingModelRenderer();
~InstancingModelRenderer();
/**
* Render: Render submitted models using the given RenderModifier
* for fragment stages.
*
* preconditions : PrepareModels must be called before Render.
*
* @param modifier The RenderModifier that specifies the fragment stage.
* @param flags If flags is 0, all submitted models are rendered.
* If flags is non-zero, only models that contain flags in their
* CModel::GetFlags() are rendered.
*/
void Render(RenderModifierPtr modifier, u32 flags);
/**
* IsAvailable: Determines whether this model renderer can be used
* given the OpenGL implementation specific limits.
*
* @note Do not attempt to construct a InstancingModelRenderer object
* when IsAvailable returns false.
*
* @return true if the OpenGL implementation can support this
* model renderer.
*/
static bool IsAvailable();
protected:
// Implementations
void* CreateModelData(CModel* model);
void UpdateModelData(CModel* model, void* data, u32 updateflags);
void DestroyModelData(CModel* model, void* data);
void PrepareModelDef(CModelDefPtr def);
void PrepareTexture(CTexture* texture);
void RenderModel(CModel* model, void* data);
private:
InstancingModelRendererInternals* m;
};
#endif // INSTANCINGMODELRENDERER_H

View File

@ -74,6 +74,22 @@ static void SkinNormal(const SModelVertex& vertex, const CMatrix3D* invtranspmat
///////////////////////////////////////////////////////////////////////////////////////////////
// ModelRenderer implementation
// Helper function to copy object-space position and normal vectors into arrays.
void ModelRenderer::CopyPositionAndNormals(
CModelDefPtr mdef,
VertexArrayIterator<CVector3D> Position,
VertexArrayIterator<CVector3D> Normal)
{
size_t numVertices = mdef->GetNumVertices();
SModelVertex* vertices = mdef->GetVertices();
for(size_t j = 0; j < numVertices; ++j)
{
Position[j] = vertices[j].m_Coords;
Normal[j] = vertices[j].m_Norm;
}
}
// Helper function to transform position and normal vectors into world-space.
void ModelRenderer::BuildPositionAndNormals(
CModel* model,

View File

@ -143,6 +143,23 @@ public:
*/
virtual void Render(RenderModifierPtr modifier, u32 flags) = 0;
/**
* CopyPositionAndNormals: Copy unanimated object-space vertices and
* normals into the given vertex array.
*
* @param mdef The underlying CModelDef that contains mesh data.
* @param Position Points to the array that will receive
* position vectors. The array behind the iterator
* must be large enough to hold model->GetModelDef()->GetNumVertices()
* vertices.
* @param Normal Points to the array that will receive normal vectors.
* The array behind the iterator must be as large as the Position array.
*/
static void CopyPositionAndNormals(
CModelDefPtr mdef,
VertexArrayIterator<CVector3D> Position,
VertexArrayIterator<CVector3D> Normal);
/**
* BuildPositionAndNormals: Build animated vertices and normals,
* transformed into world space.

View File

@ -13,12 +13,27 @@ RenderPathVertexShader::RenderPathVertexShader()
{
m_ModelLight = 0;
m_ModelLight_SHCoefficients = -1;
m_InstancingLight = 0;
m_InstancingLight_SHCoefficients = -1;
m_InstancingLight_Instancing1 = -1;
m_InstancingLight_Instancing2 = -1;
m_InstancingLight_Instancing3 = -1;
m_Instancing = 0;
m_Instancing_Instancing1 = -1;
m_Instancing_Instancing2 = -1;
m_Instancing_Instancing3 = -1;
}
RenderPathVertexShader::~RenderPathVertexShader()
{
if (m_ModelLight)
ogl_program_free(m_ModelLight);
if (m_InstancingLight)
ogl_program_free(m_InstancingLight);
if (m_Instancing)
ogl_program_free(m_Instancing);
}
// Initialize this render path.
@ -36,6 +51,20 @@ bool RenderPathVertexShader::Init()
return false;
}
m_InstancingLight = ogl_program_load("shaders/instancing_light.xml");
if (m_InstancingLight < 0)
{
LOG(WARNING, LOG_CATEGORY, "Failed to load shaders/instancing_light.xml: %i\n", (int)m_InstancingLight);
return false;
}
m_Instancing = ogl_program_load("shaders/instancing.xml");
if (m_Instancing < 0)
{
LOG(WARNING, LOG_CATEGORY, "Failed to load shaders/instancing.xml: %i\n", (int)m_Instancing);
return false;
}
return true;
}
@ -45,4 +74,20 @@ bool RenderPathVertexShader::Init()
void RenderPathVertexShader::BeginFrame()
{
m_ModelLight_SHCoefficients = ogl_program_get_uniform_location(m_ModelLight, "SHCoefficients");
m_InstancingLight_SHCoefficients = ogl_program_get_uniform_location(
m_InstancingLight, "SHCoefficients");
m_InstancingLight_Instancing1 = ogl_program_get_attrib_location(
m_InstancingLight, "Instancing1");
m_InstancingLight_Instancing2 = ogl_program_get_attrib_location(
m_InstancingLight, "Instancing2");
m_InstancingLight_Instancing3 = ogl_program_get_attrib_location(
m_InstancingLight, "Instancing3");
m_Instancing_Instancing1 = ogl_program_get_attrib_location(
m_Instancing, "Instancing1");
m_Instancing_Instancing2 = ogl_program_get_attrib_location(
m_Instancing, "Instancing2");
m_Instancing_Instancing3 = ogl_program_get_attrib_location(
m_Instancing, "Instancing3");
}

View File

@ -16,6 +16,17 @@ public:
public:
Handle m_ModelLight;
GLint m_ModelLight_SHCoefficients;
Handle m_InstancingLight;
GLint m_InstancingLight_SHCoefficients;
GLint m_InstancingLight_Instancing1; // matrix rows
GLint m_InstancingLight_Instancing2;
GLint m_InstancingLight_Instancing3;
Handle m_Instancing;
GLint m_Instancing_Instancing1; // matrix rows
GLint m_Instancing_Instancing2;
GLint m_Instancing_Instancing3;
};
#endif // __RENDERPATHVERTEXSHADER_H__

View File

@ -46,6 +46,7 @@
#include "renderer/FixedFunctionModelRenderer.h"
#include "renderer/HWLightingModelRenderer.h"
#include "renderer/InstancingModelRenderer.h"
#include "renderer/ModelRenderer.h"
#include "renderer/PlayerRenderer.h"
#include "renderer/RenderModifiers.h"
@ -108,6 +109,16 @@ CRenderer::CRenderer()
m_Models.PlayerHWLit = NULL;
m_Models.TransparentHWLit = NULL;
}
if (InstancingModelRenderer::IsAvailable())
{
m_Models.NormalInstancing = new InstancingModelRenderer;
m_Models.PlayerInstancing = new InstancingModelRenderer;
}
else
{
m_Models.NormalInstancing = NULL;
m_Models.PlayerInstancing = NULL;
}
m_Models.Transparency = new TransparencyRenderer;
m_Models.ModWireframe = RenderModifierPtr(new WireframeRenderModifier);
@ -148,6 +159,8 @@ CRenderer::~CRenderer()
delete m_Models.NormalHWLit;
delete m_Models.PlayerHWLit;
delete m_Models.TransparentHWLit;
delete m_Models.NormalInstancing;
delete m_Models.PlayerInstancing;
delete m_Models.Transparency;
// general
@ -788,6 +801,10 @@ void CRenderer::RenderShadowMap()
m_Models.NormalHWLit->Render(m_Models.ModSolidColor, MODELFLAG_CASTSHADOWS);
if (m_Models.PlayerHWLit)
m_Models.PlayerHWLit->Render(m_Models.ModSolidColor, MODELFLAG_CASTSHADOWS);
if (m_Models.NormalInstancing)
m_Models.NormalInstancing->Render(m_Models.ModSolidColor, MODELFLAG_CASTSHADOWS);
if (m_Models.PlayerInstancing)
m_Models.PlayerInstancing->Render(m_Models.ModSolidColor, MODELFLAG_CASTSHADOWS);
m_Models.TransparentFF->Render(m_Models.ModTransparentShadow, MODELFLAG_CASTSHADOWS);
if (m_Models.TransparentHWLit)
m_Models.TransparentHWLit->Render(m_Models.ModTransparentShadow, MODELFLAG_CASTSHADOWS);
@ -1017,7 +1034,7 @@ void CRenderer::RenderWater()
}
}
glColor4f(m_WaterColor.r*losMod, m_WaterColor.g*losMod, m_WaterColor.b*losMod, alpha);
glColor4f(m_WaterColor.r*losMod, m_WaterColor.g*losMod, m_WaterColor.b*losMod, alpha);
glMultiTexCoord2fARB(GL_TEXTURE0, vertX/16.0f, vertZ/16.0f);
glVertex3f(vertX, m_WaterHeight, vertZ);
}
@ -1050,6 +1067,10 @@ void CRenderer::RenderModels()
m_Models.NormalHWLit->Render(m_Models.ModPlain, 0);
if (m_Models.PlayerHWLit)
m_Models.PlayerHWLit->Render(m_Models.ModPlayer, 0);
if (m_Models.NormalInstancing)
m_Models.NormalInstancing->Render(m_Models.ModPlain, 0);
if (m_Models.PlayerInstancing)
m_Models.PlayerInstancing->Render(m_Models.ModPlayer, 0);
if (m_ModelRenderMode==WIREFRAME) {
// switch wireframe off again
@ -1061,6 +1082,10 @@ void CRenderer::RenderModels()
m_Models.NormalHWLit->Render(m_Models.ModWireframe, 0);
if (m_Models.PlayerHWLit)
m_Models.PlayerHWLit->Render(m_Models.ModWireframe, 0);
if (m_Models.NormalInstancing)
m_Models.NormalInstancing->Render(m_Models.ModWireframe, 0);
if (m_Models.PlayerInstancing)
m_Models.PlayerInstancing->Render(m_Models.ModWireframe, 0);
}
}
@ -1111,6 +1136,10 @@ void CRenderer::FlushFrame()
m_Models.PlayerHWLit->PrepareModels();
if (m_Models.TransparentHWLit)
m_Models.TransparentHWLit->PrepareModels();
if (m_Models.NormalInstancing)
m_Models.NormalInstancing->PrepareModels();
if (m_Models.PlayerInstancing)
m_Models.PlayerInstancing->PrepareModels();
m_Models.Transparency->PrepareModels();
PROFILE_END("prepare models");
@ -1169,6 +1198,10 @@ void CRenderer::FlushFrame()
m_Models.PlayerHWLit->EndFrame();
if (m_Models.TransparentHWLit)
m_Models.TransparentHWLit->EndFrame();
if (m_Models.NormalInstancing)
m_Models.NormalInstancing->EndFrame();
if (m_Models.PlayerInstancing)
m_Models.PlayerInstancing->EndFrame();
m_Models.Transparency->EndFrame();
}
@ -1225,17 +1258,30 @@ void CRenderer::Submit(CModel* model)
{
if (model->GetFlags() & MODELFLAG_CASTSHADOWS) {
PROFILE( "updating shadow bounds" );
m_ShadowBound+=model->GetBounds();
m_ShadowBound += model->GetBounds();
}
// Tricky: The call to GetBounds() above can invalidate the position
model->ValidatePosition();
bool canUseInstancing = false;
if (model->GetModelDef()->GetNumBones() == 0)
canUseInstancing = true;
if (model->GetMaterial().IsPlayer())
{
if (m_Options.m_RenderPath == RP_VERTEXSHADER)
m_Models.PlayerHWLit->Submit(model);
{
if (canUseInstancing && m_Models.PlayerInstancing)
m_Models.PlayerInstancing->Submit(model);
else
m_Models.PlayerHWLit->Submit(model);
}
else
m_Models.PlayerFF->Submit(model);
}
else if(model->GetMaterial().UsesAlpha())
else if (model->GetMaterial().UsesAlpha())
{
if (m_SortAllTransparent)
m_Models.Transparency->Submit(model);
@ -1247,7 +1293,12 @@ void CRenderer::Submit(CModel* model)
else
{
if (m_Options.m_RenderPath == RP_VERTEXSHADER)
m_Models.NormalHWLit->Submit(model);
{
if (canUseInstancing && m_Models.NormalInstancing)
m_Models.NormalInstancing->Submit(model);
else
m_Models.NormalHWLit->Submit(model);
}
else
m_Models.NormalFF->Submit(model);
}

View File

@ -295,6 +295,7 @@ protected:
friend class TransparencyRenderer;
friend class RenderPathVertexShader;
friend class HWLightingModelRenderer;
friend class InstancingModelRenderer;
// scripting
jsval JSI_GetFastPlayerColor(JSContext*);
@ -416,6 +417,8 @@ protected:
ModelRenderer* NormalHWLit;
ModelRenderer* PlayerHWLit;
ModelRenderer* TransparentHWLit;
ModelRenderer* NormalInstancing;
ModelRenderer* PlayerInstancing;
ModelRenderer* Transparency;
RenderModifierPtr ModWireframe;