📄 tsmesh.cc
字号:
{
glBlendFunc( GL_SRC_ALPHA, GL_ONE );
}
else
{
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
ColorF curColor;
glGetFloatv( GL_FOG_COLOR, (GLfloat*)&curColor );
curColor.alpha = overrideFadeVal;
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, curColor);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA,GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA,GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA,GL_SRC_ALPHA);
}
}
void TSMesh::setFade(F32 fadeValue)
{
TSShapeInstance::smRenderData.vertexAlpha.vis = fadeValue;
if (TSShapeInstance::smRenderData.vertexAlpha.set())
{
Point4F v(1,1,1,TSShapeInstance::smRenderData.vertexAlpha.current);
glColor4fv(v);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,v);
}
TSShapeInstance::smRenderData.fadeSet = true;
}
void TSMesh::clearFade()
{
setFade(1.0f);
TSShapeInstance::smRenderData.fadeSet = false;
}
//-----------------------------------------------------
// TSMesh render environment map (2-pass) methods
//-----------------------------------------------------
void TSMesh::renderEnvironmentMap(S32 frame, S32 matFrame, TSMaterialList * materials)
{
matFrame;
// most gl states assumed to be all set up...
// if we're here, then we're drawing environment map in two passes...
S32 firstVert = vertsPerFrame * frame;
// set up vertex arrays -- already enabled in TSShapeInstance::render
glVertexPointer(3,GL_FLOAT,0,&verts[firstVert]);
glNormalPointer(GL_FLOAT,0,&norms[firstVert]);
// lock...
bool lockArrays = dglDoesSupportCompiledVertexArray();
if (lockArrays)
glLockArraysEXT(0,vertsPerFrame);
S32 matIndex = -1;
for (S32 i=0; i<primitives.size(); i++)
{
TSDrawPrimitive & draw = primitives[i];
AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,"TSMesh::render: rendering of non-indexed meshes no longer supported");
if ( (matIndex ^ draw.matIndex) & (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial))
{
// material change
matIndex = draw.matIndex & (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial);
if (matIndex & TSDrawPrimitive::NoMaterial)
// no material...
continue;
else
{
if (materials->getFlags(matIndex) & TSMaterialList::NeverEnvMap)
continue;
TSShapeInstance::smRenderData.vertexAlpha.emap =
TSShapeInstance::smRenderData.environmentMapAlpha * materials->getReflectionAmount(matIndex);
glBindTexture(GL_TEXTURE_2D, materials->getReflectionMap(matIndex)->getGLName());
if (TSShapeInstance::smRenderData.vertexAlpha.set())
{
Point4F v(1,1,1,TSShapeInstance::smRenderData.vertexAlpha.current);
glColor4fv(v);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,v);
}
}
}
glDrawElements(getDrawType(draw.matIndex>>30),draw.numElements,GL_UNSIGNED_SHORT,&indices[draw.start]);
}
// unlock...
if (lockArrays)
glUnlockArraysEXT();
}
void TSMesh::initEnvironmentMapMaterials()
{
// set up gl environment
// TE0
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glDepthMask(GL_TRUE);
glFrontFace(GL_CW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
// TE1
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glBindTexture(GL_TEXTURE_2D, TSShapeInstance::smRenderData.environmentMapGLName);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); // should leave alpha alone since emap has no alpha
// TE0 again
glActiveTextureARB(GL_TEXTURE0_ARB);
TSShapeInstance::smRenderData.vertexAlpha.init();
TSShapeInstance::smRenderData.vertexAlpha.emap = TSShapeInstance::smRenderData.environmentMapAlpha;
TSShapeInstance::smRenderData.vertexAlpha.always = TSShapeInstance::smRenderData.alwaysAlphaValue;
TSShapeInstance::smRenderData.vertexAlpha.set();
glColor4fv(Point4F(1.0f,1.0f,1.0f,TSShapeInstance::smRenderData.vertexAlpha.current));
}
void TSMesh::resetEnvironmentMapMaterials()
{
// restore texture environmnet 0
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// restore texture environment 1
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
}
//-----------------------------------------------------
// TSMesh render detail map (2 pass) methods
//-----------------------------------------------------
void TSMesh::renderDetailMap(S32 frame, S32 matFrame, TSMaterialList * materials)
{
// most gl states assumed to be all set up...
// if we're here, then we're drawing detail map in two passes...
S32 firstVert = vertsPerFrame * frame;
S32 firstTVert = vertsPerFrame * matFrame;
// set up vertex arrays -- already enabled in TSShapeInstance::render
glVertexPointer(3,GL_FLOAT,0,&verts[firstVert]);
glNormalPointer(GL_FLOAT,0,&norms[firstVert]);
glTexCoordPointer(2,GL_FLOAT,0,&tverts[firstTVert]);
// lock...
bool lockArrays = dglDoesSupportCompiledVertexArray();
if (lockArrays)
glLockArraysEXT(0,vertsPerFrame);
S32 matIndex = -1;
for (S32 i=0; i<primitives.size(); i++)
{
TSDrawPrimitive & draw = primitives[i];
AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,"TSMesh::render: rendering of non-indexed meshes no longer supported");
if ( (matIndex ^ draw.matIndex) & (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial))
{
// material change
matIndex = draw.matIndex & (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial);
if (matIndex & TSDrawPrimitive::NoMaterial)
// no material...
continue;
else
{
TSShapeInstance::smRenderData.detailMapTE = 0; // borrow this variable...use as a bool to flag that we have a dmap
TextureHandle * detailMap = materials->getDetailMap(matIndex);
if (detailMap)
glBindTexture(GL_TEXTURE_2D,detailMap->getGLName());
else
continue;
TSShapeInstance::smRenderData.detailMapTE = 1;
F32 tscale = materials->getDetailMapScale(matIndex);
if (mFabs(tscale-TSShapeInstance::smRenderData.detailTextureScale) > 0.001f)
{
// yes, update scale
TSShapeInstance::smRenderData.detailTextureScale = tscale;
glMatrixMode(GL_TEXTURE);
MatrixF scaleMat;
scaleMat.identity();
for (S32 i=0; i<15; i++)
((F32*)scaleMat)[i] *= tscale;
dglLoadMatrix(&scaleMat);
glMatrixMode(GL_MODELVIEW);
}
}
}
if (TSShapeInstance::smRenderData.detailMapTE)
glDrawElements(getDrawType(draw.matIndex>>30),draw.numElements,GL_UNSIGNED_SHORT,&indices[draw.start]);
}
// unlock...
if (lockArrays)
glUnlockArraysEXT();
}
void TSMesh::initDetailMapMaterials()
{
TSShapeInstance::smRenderData.detailTextureScale = 1.0f;
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
glDepthMask(GL_TRUE);
glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// set texture environment color and fragment color
// so that c=1-k/2 and f=k/2, where k is 1-detailMapAlpha
// result is that distance from 0.5 is reduced as
// detailMapAlpha goes to 0...
F32 k = 0.5f * (1.0f - TSShapeInstance::smRenderData.detailMapAlpha);
Point4F TEColor(1.0f-k,1.0f-k,1.0f-k,1.0f);
glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,TEColor);
Point4F fColor(k,k,k,1.0f);
glColor4fv(fColor);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_BLEND);
glDisable(GL_LIGHTING);
}
void TSMesh::resetDetailMapMaterials()
{
glEnable(GL_LIGHTING);
if (mFabs(TSShapeInstance::smRenderData.detailTextureScale-1.0f)>0.001f)
{
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
}
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glColor4fv(Point4F(1,1,1,1));
glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,Point4F(0,0,0,0));
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
}
//-----------------------------------------------------
// TSMesh renderShadow
//-----------------------------------------------------
Vector<Point2I> gShadowVerts(__FILE__, __LINE__);
void shadowTransform(const MatrixF & mat, Point3F * v, Point3F * vend, S32 max)
{
const F32 * m = (const F32*)mat;
F32 ax = m[0];
F32 ay = m[1];
F32 az = m[2];
F32 at = m[3];
F32 bx = m[8];
F32 by = m[9];
F32 bz = m[10];
F32 bt = m[11];
Point2I * dest = gShadowVerts.address();
S32 val;
while (v < vend)
{
val = (S32)(ax*v->x + ay*v->y + az*v->z + at);
dest->x = val<0 ? 0 : (val>max ? max : val);
val = (S32)(bx*v->x + by*v->y + bz*v->z + bt);
dest->y = val<0 ? 0 : (val>max ? max : val);
dest++; v++;
}
}
void TSMesh::renderShadow(S32 frame, const MatrixF & mat, S32 dim, U32 * bits, TSMaterialList * materials)
{
if (!vertsPerFrame || !primitives.size())
return;
if (!(primitives[0].matIndex & TSDrawPrimitive::NoMaterial) && (TSMaterialList::Translucent & materials->getFlags(primitives[0].matIndex & TSDrawPrimitive::MaterialMask)))
// if no material...it would be nice to just exit...but may have some real polys back there...
return;
AssertFatal(primitives[0].matIndex & TSDrawPrimitive::Indexed,"TSMesh::renderShadow: indexed polys only");
gShadowVerts.setSize(vertsPerFrame);
Point3F * vstart = &verts[frame*vertsPerFrame];
Point3F * vend = vstart + vertsPerFrame;
// result placed into gShadowVerts
shadowTransform(mat,vstart,vend,dim-1);
// pick correct bit render routine...we assume all strips or all triangles
if ( (primitives[0].matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Strip)
BitRender::render_strips((U8*)primitives.address(),primitives.size(),sizeof(TSDrawPrimitive),indices.address(),gShadowVerts.address(),dim,bits);
else if ( (primitives[0].matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
BitRender::render_tris((U8*)primitives.address(),primitives.size(),sizeof(TSDrawPrimitive),indices.address(),gShadowVerts.address(),dim,bits);
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -