📄 unitdrawer.cpp
字号:
unit->Draw();
} else {
// ghosted enemy units
if (unit->losStatus[gu->myAllyTeam] & LOS_CONTRADAR)
glColor4f(0.9f, 0.9f, 0.9f, 0.5f);
else
glColor4f(0.6f, 0.6f, 0.6f, 0.4f);
glPushMatrix();
glTranslatef3(unit->pos);
glRotatef(unit->buildFacing * 90.0f, 0, 1, 0);
// check for decoy models
const int unitTeam = unit->team;
const UnitDef* decoyDef = unit->unitDef->decoyDef;
S3DOModel* model;
if (decoyDef == NULL) {
model = unit->model;
} else {
model = decoyDef->LoadModel(unitTeam);
is_s3o = (model->rootobjects3o != NULL);
}
if (is_s3o) {
SetBasicS3OTeamColour(unitTeam);
texturehandler->SetS3oTexture(model->textureType);
}
model->DrawStatic();
glPopMatrix();
}
}
// buildings that died but were still ghosted
glColor4f(0.6f, 0.6f, 0.6f, 0.4f);
for (std::list<GhostBuilding*>::iterator gbi = gB.begin(); gbi != gB.end();) {
if (loshandler->InLos((*gbi)->pos, gu->myAllyTeam)) {
if ((*gbi)->decal)
(*gbi)->decal->gbOwner = 0;
delete *gbi;
gbi = gB.erase(gbi);
} else {
if (camera->InView((*gbi)->pos, (*gbi)->model->radius * 2)) {
glPushMatrix();
glTranslatef3((*gbi)->pos);
glRotatef((*gbi)->facing * 90.0f, 0, 1, 0);
if (is_s3o) {
SetBasicS3OTeamColour((*gbi)->team);
texturehandler->SetS3oTexture((*gbi)->model->textureType);
}
(*gbi)->model->DrawStatic();
glPopMatrix();
}
++gbi;
}
}
}
void CUnitDrawer::SetupForUnitDrawing(void)
{
if (shadowHandler->inShadowPass)
return;
if (advShading && !water->drawReflection) {
// standard doesn't seem to support vertex program + clipplanes at once
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, unitVP);
glEnable(GL_VERTEX_PROGRAM_ARB);
if (shadowHandler->drawShadows) {
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, unitShadowFP);
} else {
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, unitFP);
}
glEnable(GL_FRAGMENT_PROGRAM_ARB);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 10, gs->sunVector.x, gs->sunVector.y, gs->sunVector.z, 0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 12, unitAmbientColor.x, unitAmbientColor.y, unitAmbientColor.z, 1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 11, unitSunColor.x, unitSunColor.y, unitSunColor.z, 0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 13, camera->pos.x, camera->pos.y, camera->pos.z, 0);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 10, 0, 0, 0, unitShadowDensity);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 11, unitAmbientColor.x, unitAmbientColor.y, unitAmbientColor.z, 1);
if (shadowHandler->drawShadows) {
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, shadowHandler->shadowTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glEnable(GL_TEXTURE_2D);
}
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
texturehandler->SetTATexture();
glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, boxtex);
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, specularTex);
glActiveTextureARB(GL_TEXTURE0_ARB);
float t[16];
glGetFloatv(GL_MODELVIEW_MATRIX,t);
glMatrixMode(GL_MATRIX0_ARB);
glLoadMatrixf(shadowHandler->shadowMatrix.m);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMultMatrixf(t);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
} else {
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT1, GL_POSITION,gs->sunVector4); // Position The Light
glEnable(GL_LIGHT1); // Enable Light One
// glDisable(GL_CULL_FACE);
// glCullFace(GL_BACK);
glEnable(GL_TEXTURE_2D);
float cols[] = {1, 1, 1, 1};
float cols2[] = {1, 1, 1, 1};
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,cols);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,cols2);
glColor3f(1, 1, 1);
texturehandler->SetTATexture();
}
// glAlphaFunc(GL_GREATER,0.05f);
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
}
void CUnitDrawer::CleanUpUnitDrawing(void)
{
if (shadowHandler->inShadowPass)
return;
if(advShading && !water->drawReflection){
glDisable( GL_VERTEX_PROGRAM_ARB );
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE3_ARB);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
} else {
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT1);
}
}
void CUnitDrawer::SetS3OTeamColour(int team)
{
if (advShading) {
unsigned char* col = gs->Team(team)->color;
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 14, col[0] / 255.f, col[1] / 255.f, col[2] / 255.f, 1);
if (luaDrawing) { // FIXME?
SetBasicS3OTeamColour(team);
}
} else {
SetBasicS3OTeamColour(team);
}
}
void CUnitDrawer::SetBasicS3OTeamColour(int team)
{
unsigned char* col = gs->Team(team)->color;
float texConstant[] = {col[0] / 255.f, col[1] / 255.f, col[2] / 255.f, 1};
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texConstant);
}
/**
* Set up the texture environment in texture unit 0
* to give an S3O texture its team-colour.
*
* Also:
* - call SetBasicS3OTeamColour to set the team colour to transform to.
* - Replace the output alpha channel. If not, only the team-coloured bits will show, if that. Or something.
*/
void CUnitDrawer::SetupBasicS3OTexture0(void)
{
// RGB = Texture * (1-Alpha) + Teamcolor * Alpha
glActiveTextureARB(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glEnable(GL_TEXTURE_2D);
}
/**
* This sets the first texture unit to GL_MODULATE the colours from the
* first texture unit with the current glColor.
*
* Normal S3O drawing sets the color to full white; translucencies
* use this setup to 'tint' the drawn model.
*
* - Leaves glActivateTextureARB at the first unit.
* - This doesn't tinker with the output alpha, either.
*/
void CUnitDrawer::SetupBasicS3OTexture1(void)
{
// RGB = Primary Color * Previous
glActiveTextureARB(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, whiteTex);
}
void CUnitDrawer::SetupForS3ODrawing(void)
{
//glDisable(GL_ALPHA_TEST);
//glDisable(GL_BLEND);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
// When rendering shadows, we just want to take extraColor.alpha (tex2) into account,
// so textures with masked texels create correct shadows.
if (shadowHandler->inShadowPass)
{
// Instead of enabling GL_TEXTURE1_ARB i have modified CTextureHandler.SetS3oTexture()
// to set texture 0 if shadowHandler->inShadowPass is true.
glEnable(GL_TEXTURE_2D);
glAlphaFunc(GL_GREATER, 0.5f);
glEnable(GL_ALPHA_TEST);
return;
}
if (advShading && !water->drawReflection) { //standard doesnt seem to support vertex program+clipplanes at once
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, unitS3oVP );
glEnable( GL_VERTEX_PROGRAM_ARB );
if (shadowHandler->drawShadows) {
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, unitShadowS3oFP );
} else {
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, unitS3oFP );
}
glEnable( GL_FRAGMENT_PROGRAM_ARB );
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10, gs->sunVector.x,gs->sunVector.y,gs->sunVector.z,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, unitAmbientColor.x,unitAmbientColor.y,unitAmbientColor.z,1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, unitSunColor.x,unitSunColor.y,unitSunColor.z,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, camera->pos.x, camera->pos.y, camera->pos.z, 0);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,10, 0,0,0,unitShadowDensity);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,11, unitAmbientColor.x,unitAmbientColor.y,unitAmbientColor.z,1);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
if (shadowHandler->drawShadows) {
glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D,shadowHandler->shadowTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glEnable(GL_TEXTURE_2D);
}
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, boxtex);
glActiveTextureARB(GL_TEXTURE4_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, specularTex);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER,0.5f);
glEnable(GL_ALPHA_TEST);
float t[16];
glGetFloatv(GL_MODELVIEW_MATRIX,t);
glMatrixMode(GL_MATRIX0_ARB);
glLoadMatrixf(shadowHandler->shadowMatrix.m);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMultMatrixf(t);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
} else {
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT1, GL_POSITION,gs->sunVector4); // Position The Light
glEnable(GL_LIGHT1); // Enable Light One
SetupBasicS3OTexture0();
// Set material color and fallback texture (3DO texture)
float cols[]={1,1,1,1};
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,cols);
glColor3f(1,1,1);
texturehandler->SetTATexture();
SetupBasicS3OTexture1();
glActiveTextureARB(GL_TEXTURE0_ARB);
}
}
void CUnitDrawer::CleanUpS3ODrawing(void)
{
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
if (shadowHandler->inShadowPass) {
glDisable(GL_TEXTURE_2D);
return;
}
if(advShading && !water->drawReflection){
glDisable( GL_VERTEX_PROGRAM_ARB );
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glActiveTextureARB(GL_TEXTURE3_ARB);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE4_ARB);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
} else {
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT1);
CleanupBasicS3OTexture1();
CleanupBasicS3OTexture0();
}
}
void CUnitDrawer::CleanupBasicS3OTexture1(void)
{
// reset texture1 state
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB, GL_TEXTURE);
}
void CUnitDrawer::CleanupBasicS3OTexture0(void)
{
// reset texture0 state
glActiveTextureARB(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
}
/**
* Between a pair of SetupFor/CleanUpUnitDrawing (or SetupForS3ODrawing),
* temporarily turns off textures and shaders.
*
* Used by CUnit::Draw() for drawing a unit under construction.
*
* Unfortunately, it doesn't work! With advanced shading on, the green
* is darker than usual; with shadows as well, it's almost black. -- krudat
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -