📄 unitdrawer.cpp
字号:
void CUnitDrawer::UnitDrawingTexturesOff(S3DOModel *model)
{
if (model->textureType == 0){
/* 3DO */
/* If SetupForUnitDrawing is changed, this may need tweaking too. */
if(advShading && !water->drawReflection){
glDisable(GL_VERTEX_PROGRAM_ARB);
glDisable(GL_FRAGMENT_PROGRAM_ARB);
/* TEXTURE0: Shadows. */
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB); // Unit texture.
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE2_ARB); // boxtex
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE3_ARB); // specularTex
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_FOG);
} else {
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
}
} else {
/* S3O */
/* If SetupForS3ODrawing is changed, this may need tweaking too. */
if(advShading && !water->drawReflection){
/* Odd. Units with only the first texture build cyan rather than
green. Presume it's an improvement on black. :S -- krudat */
glDisable(GL_VERTEX_PROGRAM_ARB);
glDisable(GL_FRAGMENT_PROGRAM_ARB);
/* TEXTURE0: Colour texture. */
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB); // 'Shiny' texture.
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE2_ARB); // Shadows.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE3_ARB); // boxtex
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE4_ARB); // specularTex
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
} else {
glDisable(GL_LIGHTING);
/* TEXTURE0: Colour texture. */
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB); // GL lighting, I think.
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
}
}
}
/**
* The companion to UnitDrawingTexturesOff(), re-enables the texture units
* needed for drawing a model.
*
* Does *not* restore the texture bindings.
*/
void CUnitDrawer::UnitDrawingTexturesOn(S3DOModel *model)
{
/* If UnitDrawingTextureOff is changed, this may need tweaking too. */
if (model->textureType == 0){
/* 3DO */
if(advShading && !water->drawReflection){
glEnable(GL_VERTEX_PROGRAM_ARB);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_FOG);
} else {
glEnable(GL_LIGHTING);
glColor3f(1,1,1);
glEnable(GL_TEXTURE_2D);
}
} else {
/* S3O */
if(advShading && !water->drawReflection){
glEnable(GL_VERTEX_PROGRAM_ARB);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE2_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE4_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
} else {
glEnable(GL_LIGHTING);
glColor3f(1,1,1);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
}
}
}
void CUnitDrawer::CreateSpecularFace(unsigned int gltype, int size, float3 baseDir, float3 xdif, float3 ydif, float3 sundir, float exponent,float3 suncolor)
{
unsigned char* buf = SAFE_NEW unsigned char[size * size * 4];
for (int y = 0; y < size; ++y) {
for (int x = 0; x < size; ++x) {
float3 vec = baseDir + (xdif * (x + 0.5f)) / size + (ydif * (y + 0.5f)) / size;
vec.Normalize();
float dot = vec.dot(sundir);
if (dot < 0)
dot = 0;
float exp = min(1.f, powf(dot, exponent) + powf(dot, 3) * 0.25f);
buf[(y * size + x) * 4 + 0] = (unsigned char) (suncolor.x * exp * 255);
buf[(y * size + x) * 4 + 1] = (unsigned char) (suncolor.y * exp * 255);
buf[(y * size + x) * 4 + 2] = (unsigned char) (suncolor.z * exp * 255);
buf[(y * size + x) * 4 + 3] = 255;
}
}
glTexImage2D(gltype, 0, GL_RGBA8, size, size, 0, GL_RGBA,GL_UNSIGNED_BYTE, buf);
delete[] buf;
}
void CUnitDrawer::UpdateReflectTex(void)
{
switch(updateFace++){
case 0:
CreateReflectionFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, float3(1, 0, 0));
break;
case 1:
CreateReflectionFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, float3(-1, 0, 0));
break;
case 2:
CreateReflectionFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, float3(0, 1, 0));
break;
case 3:
CreateReflectionFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, float3(0, -1, 0));
break;
case 4:
CreateReflectionFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, float3(0, 0, 1));
break;
case 5:
CreateReflectionFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, float3(0, 0, -1));
updateFace=0;
break;
default:
updateFace=0;
break;
}
}
void CUnitDrawer::CreateReflectionFace(unsigned int gltype, float3 camdir)
{
glViewport(0, 0, reflTexSize, reflTexSize);
CCamera *realCam = camera;
camera = new CCamera(*realCam);
camera->SetFov(90);
camera->forward = camdir;
camera->up = -UpVector;
if (camera->forward.y == 1)
camera->up = float3(0, 0, 1);
if (camera->forward.y == -1)
camera->up = float3(0, 0, -1);
// if (camera->pos.y < ground->GetHeight(camera->pos.x, camera->pos.z) + 50)
camera->pos.y = ground->GetHeight(camera->pos.x, camera->pos.z) + 50;
camera->Update(false);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, 1, NEAR_PLANE, gu->viewRange);
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
sky->Draw();
readmap->GetGroundDrawer()->Draw(false, true);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, boxtex);
glCopyTexSubImage2D(gltype, 0, 0, 0, 0, 0,reflTexSize, reflTexSize);
glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
delete camera;
camera = realCam;
}
void CUnitDrawer::QueS3ODraw(CWorldObject* object,int textureType)
{
while (quedS3Os.size() <= textureType)
quedS3Os.push_back(std::vector<CWorldObject*>());
quedS3Os[textureType].push_back(object);
usedS3OTextures.insert(textureType);
}
void CUnitDrawer::DrawQuedS3O(void)
{
SetupForS3ODrawing();
for (std::set<int>::iterator uti = usedS3OTextures.begin(); uti != usedS3OTextures.end(); ++uti) {
const int tex = *uti;
texturehandler->SetS3oTexture(tex);
for(std::vector<CWorldObject*>::iterator ui = quedS3Os[tex].begin(); ui != quedS3Os[tex].end(); ++ui){
(*ui)->DrawS3O();
}
quedS3Os[tex].clear();
}
usedS3OTextures.clear();
CleanUpS3ODrawing();
}
/**
* Draw one unit.
*
* Used for drawing the view of the controlled unit.
*
* Note: does all the GL state setting for that one unit, so you might want
* something else for drawing many units.
*/
void CUnitDrawer::DrawIndividual(CUnit * unit)
{
const bool origDebug = gu->drawdebug;
gu->drawdebug = false;
LuaUnitLODMaterial* lodMat = NULL;
if (unit->lodCount > 0) {
const LuaMatType matType =
(water->drawReflection) ? LUAMAT_OPAQUE_REFLECT : LUAMAT_OPAQUE;
LuaUnitMaterial& unitMat = unit->luaMats[matType];
lodMat = unitMat.GetMaterial(unit->currentLOD);
}
if (lodMat && lodMat->IsActive()) {
CUnit::SetLODFactor(LODScale);
luaMatHandler.setup3doShader = SetupOpaque3DO;
luaMatHandler.reset3doShader = ResetOpaque3DO;
luaMatHandler.setupS3oShader = SetupOpaqueS3O;
luaMatHandler.resetS3oShader = ResetOpaqueS3O;
const LuaMaterial& mat = (LuaMaterial&) *lodMat->matref.GetBin();
mat.Execute(LuaMaterial::defMat);
lodMat->uniforms.Execute(unit);
SetS3OTeamColour(unit->team);
unit->DrawRawWithLists(lodMat->preDisplayList, lodMat->postDisplayList);
LuaMaterial::defMat.Execute(mat);
}
else if (unit->model->textureType == 0){
/* 3DO */
SetupForUnitDrawing();
unit->DrawRaw();
CleanUpUnitDrawing();
}
else {
/* S3O */
SetupForS3ODrawing();
texturehandler->SetS3oTexture(unit->model->textureType);
SetS3OTeamColour(unit->team);
unit->DrawRaw();
CleanUpS3ODrawing();
}
gu->drawdebug = origDebug;
}
/**
* Draw one unit,
* - with depth-buffering(!) and lighting off,
* - 'tinted' by the current glColor, *including* alpha.
*
* Used for drawing building orders.
*
* Note: does all the GL state setting for that one unit, so you might want
* something else for drawing many translucent units.
*/
void CUnitDrawer::DrawBuildingSample(const UnitDef* unitdef, int side, float3 pos, int facing)
{
S3DOModel* model = unitdef->LoadModel(side);
if (model->textureType == 0) {
/* 3DO */
SetupForGhostDrawing(); // (model, side);
glPushMatrix();
glTranslatef3(pos);
glRotatef(facing * 90.0f, 0, 1, 0);
model->DrawStatic();
CleanUpGhostDrawing();
glPopMatrix();
return;
}
/* S3O */
/* From SetupForGhostDrawing. */
glPushAttrib (GL_TEXTURE_BIT | GL_ENABLE_BIT);
/* *No* GL lighting. */
/* Get the team-coloured texture constructed by unit 0. */
SetBasicS3OTeamColour(side);
SetupBasicS3OTexture0();
texturehandler->SetS3oTexture(model->textureType);
/* Tint it with the current glColor in unit 1. */
SetupBasicS3OTexture1();
/* Use the alpha given by glColor for the outgoing alpha.
(Might need to change this if we ever have transparent bits on units?)
*/
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,GL_PRIMARY_COLOR_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
/* From SetupForGhostDrawing. */
glDepthMask(0);
glDisable(GL_CULL_FACE); /* Leave out face culling, as 3DO and 3DO translucents does. */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
/* Push out the polygons. */
glPushMatrix();
glTranslatef3(pos);
glRotatef(facing * 90.0f, 0, 1, 0);
model->DrawStatic();
glPopMatrix();
// reset texture1 state
CleanupBasicS3OTexture1();
/* Also reset the alpha generation. */
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
// reset texture0 state
CleanupBasicS3OTexture0();
/* From CleanUpGhostDrawing. */
glPopAttrib();
glDisable(GL_TEXTURE_2D);
glDepthMask(1);
}
void CUnitDrawer::DrawUnitDef(const UnitDef* unitDef, int team)
{
S3DOModel* model = unitDef->LoadModel(team);
glPushAttrib (GL_TEXTURE_BIT | GL_ENABLE_BIT);
glEnable(GL_TEXTURE_2D);
if (model->textureType == 0) {
// 3DO model
texturehandler->SetTATexture();
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_SOURCE1_RGB_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
model->DrawStatic();
}
else {
// get the team-coloured texture constructed by unit 0
SetBasicS3OTeamColour(team);
SetupBasicS3OTexture0();
texturehandler->SetS3oTexture(model->textureType);
// tint it with the current glColor in unit 1
SetupBasicS3OTexture1();
// use the alpha given by glColor for the outgoing alpha.
// (might need to change this if we ever have transparent bits on units?)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
model->DrawStatic();
// reset texture1 state
CleanupBasicS3OTexture1();
// also reset the alpha generation
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
// reset texture0 state
CleanupBasicS3OTexture0();
}
glPopAttrib();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -