void CFeatureDrawer::Draw() { if(globalRendering->drawFog) { glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); } GML_RECMUTEX_LOCK(feat); // Draw CBaseGroundDrawer* gd = readmap->GetGroundDrawer(); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE2_ARB); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, gd->infoTex); glActiveTextureARB(GL_TEXTURE0_ARB); } unitDrawer->SetupForUnitDrawing(); GetVisibleFeatures(0, true); for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) { opaqueModelRenderers[modelType]->PushRenderState(); DrawOpaqueFeatures(modelType); opaqueModelRenderers[modelType]->PopRenderState(); } unitDrawer->CleanUpUnitDrawing(); farTextureHandler->Draw(); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE2_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glActiveTextureARB(GL_TEXTURE0_ARB); } glDisable(GL_TEXTURE_2D); glDisable(GL_FOG); DrawFeatureStats(); }
void CFeatureDrawer::Draw() { ISky::SetupFog(); GML_RECMUTEX_LOCK(feat); // Draw CBaseGroundDrawer* gd = readMap->GetGroundDrawer(); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE2_ARB); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); glMultiTexCoord4f(GL_TEXTURE2_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture()); glActiveTextureARB(GL_TEXTURE0_ARB); } unitDrawer->SetupForUnitDrawing(false); GetVisibleFeatures(0, true); for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) { opaqueModelRenderers[modelType]->PushRenderState(); DrawOpaqueFeatures(modelType); opaqueModelRenderers[modelType]->PopRenderState(); } unitDrawer->CleanUpUnitDrawing(false); farTextureHandler->Draw(); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE2_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glActiveTextureARB(GL_TEXTURE0_ARB); } glDisable(GL_TEXTURE_2D); glDisable(GL_FOG); #ifdef USE_GML DrawFeatureStats(); #endif }
void CGrassDrawer::EnableShader(const GrassShaderProgram type) { CBaseGroundDrawer* gd = readMap->GetGroundDrawer(); const float3 windSpeed = wind.GetCurrentDirection() * wind.GetCurrentStrength() * mapInfo->grass.bladeWaveScale; grassShader = grassShaders[type]; grassShader->SetFlag("HAVE_INFOTEX", gd->DrawExtraTex()); grassShader->SetFlag("HAVE_SHADOWS", shadowHandler->shadowsLoaded); grassShader->Enable(); grassShader->SetUniform("frame", gs->frameNum + globalRendering->timeOffset); grassShader->SetUniform3v("windSpeed", &windSpeed.x); grassShader->SetUniform3v("camPos", &camera->GetPos().x); grassShader->SetUniform3v("camDir", &camera->forward.x); grassShader->SetUniform3v("camUp", &camera->up.x); grassShader->SetUniform3v("camRight", &camera->right.x); grassShader->SetUniform("groundShadowDensity", mapInfo->light.groundShadowDensity); grassShader->SetUniformMatrix4x4("shadowMatrix", false, &shadowHandler->shadowMatrix.m[0]); grassShader->SetUniform4v("shadowParams", &shadowHandler->GetShadowParams().x); grassShader->SetUniform3v("ambientLightColor", &mapInfo->light.unitAmbientColor.x); grassShader->SetUniform3v("diffuseLightColor", &mapInfo->light.unitSunColor.x); grassShader->SetUniform3v("specularLightColor", &mapInfo->light.unitSpecularColor.x); grassShader->SetUniform3v("sunDir", &mapInfo->light.sunDir.x); }
void CGrassDrawer::ResetGlStateNear() { CBaseGroundDrawer* gd = readMap->GetGroundDrawer(); if (shadowHandler->shadowsLoaded && globalRendering->haveGLSL) { grassShader->Disable(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); /*glActiveTextureARB(GL_TEXTURE1_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); glActiveTextureARB(GL_TEXTURE0_ARB);*/ } else { glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glActiveTextureARB(GL_TEXTURE2_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE3_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } glActiveTextureARB(GL_TEXTURE0_ARB); } glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); }
void CGrassDrawer::SetupGlStateFar() { assert(globalRendering->haveGLSL); CBaseGroundDrawer* gd = readMap->GetGroundDrawer(); //glEnable(GL_ALPHA_TEST); //glAlphaFunc(GL_GREATER, 0.01f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMultMatrixf(camera->GetViewMatrix()); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); EnableShader(GRASS_PROGRAM_DIST); glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, farTex); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture()); glActiveTextureARB(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture()); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE3_ARB); glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture()); } if (shadowHandler->shadowsLoaded) { glActiveTextureARB(GL_TEXTURE4_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_ALPHA); } glActiveTextureARB(GL_TEXTURE0_ARB); }
void CAdvTreeDrawer::Draw(float treeDistance,bool drawReflection) { int activeFarTex=camera->forward.z<0 ? treeGen->farTex[0] : treeGen->farTex[1]; bool drawDetailed=true; if(treeDistance<4) drawDetailed=false; if(drawReflection) drawDetailed=false; CBaseGroundDrawer *gd = readmap->GetGroundDrawer (); glEnable(GL_ALPHA_TEST); if(gu->drawFog) { glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); glEnable(GL_FOG); } if(shadowHandler->drawShadows && !gd->DrawExtraTex()){ glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarVP ); glEnable(GL_VERTEX_PROGRAM_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_ALPHA); if(shadowHandler->useFPShadows){ glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, treeGen->treeFPShadow ); glEnable( GL_FRAGMENT_PROGRAM_ARB ); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,10, mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,1); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,11, 0,0,0,1-mapInfo->light.groundShadowDensity*0.5f); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, activeFarTex); } else { glEnable(GL_TEXTURE_2D); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 1-mapInfo->light.groundShadowDensity*0.5f); float texConstant[]={mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,0.0f}; glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,texConstant); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB,GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_ARB,GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_ADD); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB); glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, activeFarTex); } glActiveTextureARB(GL_TEXTURE0_ARB); glMatrixMode(GL_MATRIX0_ARB); glLoadMatrixf(shadowHandler->shadowMatrix.m); glMatrixMode(GL_MODELVIEW); } else { glBindTexture(GL_TEXTURE_2D, activeFarTex); } glEnable(GL_TEXTURE_2D); int cx=(int)(camera->pos.x/(SQUARE_SIZE*TREE_SQUARE_SIZE)); int cy=(int)(camera->pos.z/(SQUARE_SIZE*TREE_SQUARE_SIZE)); CAdvTreeSquareDrawer drawer; drawer.td = this; drawer.cx = cx; drawer.cy = cy; drawer.treeDistance = treeDistance * SQUARE_SIZE * TREE_SQUARE_SIZE; drawer.drawDetailed = drawDetailed; GML_STDMUTEX_LOCK(tree); // Draw // draw far away trees using the map dependent grid visibility oldTreeDistance=treeDistance; readmap->GridVisibility (camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer); if(drawDetailed){ int xstart=std::max(0,cx-2); int xend=std::min(gs->mapx/TREE_SQUARE_SIZE-1,cx+2); int ystart=std::max(0,cy-2); int yend=std::min(gs->mapy/TREE_SQUARE_SIZE-1,cy+2); if(shadowHandler->drawShadows && !gd->DrawExtraTex()){ glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeVP ); glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); glActiveTextureARB(GL_TEXTURE0_ARB); } else { glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeNSVP ); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,15, 1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),1.0f/(gs->pwr2mapx*SQUARE_SIZE),1); } glEnable( GL_VERTEX_PROGRAM_ARB ); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, camera->right.x,camera->right.y,camera->right.z,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9, camera->up.x,camera->up.y,camera->up.z,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, mapInfo->light.groundSunColor.x,mapInfo->light.groundSunColor.y,mapInfo->light.groundSunColor.z,0.85f); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,14, mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,0.85f); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 0,0,0,0.20f*(1.0f/MAX_TREE_HEIGHT)); //w=alpha/height modifier glAlphaFunc(GL_GREATER,0.5f); glDisable(GL_BLEND); glColor4f(1,1,1,1); va=GetVertexArray(); va->Initialize(); struct FadeTree{ float3 pos; float relDist; float deltaY; int type; }; static FadeTree fadeTrees[3000]; FadeTree *pFT=fadeTrees; for(TreeSquareStruct* pTSS=trees+ystart*treesX; pTSS<=trees+yend*treesX; pTSS+=treesX) { for(TreeSquareStruct* tss=pTSS+xstart; tss<=pTSS+xend; ++tss) { tss->lastSeen=gs->frameNum; va->EnlargeArrays(12*tss->trees.size(),0,VA_SIZE_T); //!alloc room for all tree vertexes for(std::map<int,TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){ TreeStruct* ts=&ti->second; float3 pos(ts->pos); int type=ts->type; float dy; unsigned int displist; if(type<8){ dy=0.5f; displist=treeGen->pineDL+type; } else { type-=8; dy=0; displist=treeGen->leafDL+type; } if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){ float camDist=(pos-camera->pos).SqLength(); if(camDist<SQUARE_SIZE*SQUARE_SIZE*110*110){ //draw detailed tree glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0); glCallList(displist); } else if(camDist<SQUARE_SIZE*SQUARE_SIZE*125*125){ //draw fading tree float relDist=(pos.distance(camera->pos)-SQUARE_SIZE*110)/(SQUARE_SIZE*15); glAlphaFunc(GL_GREATER,0.8f+relDist*0.2f); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0); glCallList(displist); glAlphaFunc(GL_GREATER,0.5f); pFT->pos=pos; pFT->deltaY=dy; pFT->type=type; pFT->relDist=relDist; ++pFT; } else { //draw undetailed tree DrawTreeVertex(pos, type*0.125f, dy, false); } } } } } //draw trees that has been marked as falling glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,0,0,0,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, camera->right.x,camera->right.y,camera->right.z,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9, camera->up.x,camera->up.y,camera->up.z,0); for(std::list<FallingTree>::iterator fti=fallingTrees.begin(); fti!=fallingTrees.end(); ++fti){ float3 pos=fti->pos-UpVector*(fti->fallPos*20); if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){ float ang=fti->fallPos*PI; float3 up(fti->dir.x*sin(ang),cos(ang),fti->dir.z*sin(ang)); float3 z(up.cross(float3(-1,0,0))); z.ANormalize(); float3 x(up.cross(z)); CMatrix44f transMatrix(pos,x,up,z); glPushMatrix(); glMultMatrixf(&transMatrix[0]); int type=fti->type; int displist; if(type<8){ displist=treeGen->pineDL+type; } else { type-=8; displist=treeGen->leafDL+type; } glCallList(displist); glPopMatrix(); } } glDisable( GL_VERTEX_PROGRAM_ARB ); if(shadowHandler->drawShadows && !gd->DrawExtraTex()){ glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarVP ); glEnable(GL_VERTEX_PROGRAM_ARB); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, activeFarTex); glActiveTextureARB(GL_TEXTURE0_ARB); } else { glBindTexture(GL_TEXTURE_2D, activeFarTex); } va->DrawArrayT(GL_QUADS); for(FadeTree *pFTree=fadeTrees; pFTree<pFT; ++pFTree) { //faded close trees va=GetVertexArray(); va->Initialize(); va->CheckInitSize(12*VA_SIZE_T); DrawTreeVertex(pFTree->pos, pFTree->type*0.125f, pFTree->deltaY, false); glAlphaFunc(GL_GREATER,1-pFTree->relDist*0.5f); va->DrawArrayT(GL_QUADS); } } if(shadowHandler->drawShadows && !gd->DrawExtraTex()){ glDisable( GL_VERTEX_PROGRAM_ARB ); if(shadowHandler->useFPShadows){ glDisable(GL_FRAGMENT_PROGRAM_ARB); } glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); } glDisable(GL_FOG); glDisable(GL_ALPHA_TEST); //clean out squares from memory that are no longer visible int startClean=lastListClean*20%(nTrees); lastListClean=gs->frameNum; int endClean=gs->frameNum*20%(nTrees); if(startClean>endClean){ for(TreeSquareStruct *pTSS=trees+startClean; pTSS<trees+nTrees; ++pTSS) { if(pTSS->lastSeen<gs->frameNum-50 && pTSS->displist){ glDeleteLists(pTSS->displist,1); pTSS->displist=0; } if(pTSS->lastSeenFar<gs->frameNum-50 && pTSS->farDisplist){ glDeleteLists(pTSS->farDisplist,1); pTSS->farDisplist=0; } } for(TreeSquareStruct *pTSS=trees; pTSS<trees+endClean; ++pTSS) { if(pTSS->lastSeen<gs->frameNum-50 && pTSS->displist){ glDeleteLists(pTSS->displist,1); pTSS->displist=0; } if(pTSS->lastSeenFar<gs->frameNum-50 && pTSS->farDisplist){ glDeleteLists(pTSS->farDisplist,1); pTSS->farDisplist=0; } } } else { for(TreeSquareStruct *pTSS=trees+startClean; pTSS<trees+endClean; ++pTSS) { if(pTSS->lastSeen<gs->frameNum-50 && pTSS->displist){ glDeleteLists(pTSS->displist,1); pTSS->displist=0; } if(pTSS->lastSeenFar<gs->frameNum-50 && pTSS->farDisplist){ glDeleteLists(pTSS->farDisplist,1); pTSS->farDisplist=0; } } } }
void CAdvTreeDrawer::Draw(float treeDistance, bool drawReflection) { const int activeFarTex = (camera->forward.z < 0.0f)? treeGen->farTex[0]: treeGen->farTex[1]; const bool drawDetailed = ((treeDistance >= 4.0f) || drawReflection); CBaseGroundDrawer* gd = readmap->GetGroundDrawer(); Shader::IProgramObject* treeShader = NULL; #define L mapInfo->light glEnable(GL_ALPHA_TEST); glEnable(GL_TEXTURE_2D); if (globalRendering->drawFog) { glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); glEnable(GL_FOG); } if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, activeFarTex); glActiveTexture(GL_TEXTURE0); 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_ALPHA); treeShader = treeShaders[TREE_PROGRAM_DIST_SHADOW]; treeShader->Enable(); if (globalRendering->haveGLSL) { treeShader->SetUniformMatrix4fv(7, false, &shadowHandler->shadowMatrix.m[0]); treeShader->SetUniform4fv(8, &(shadowHandler->GetShadowParams().x)); } else { treeShader->SetUniformTarget(GL_FRAGMENT_PROGRAM_ARB); treeShader->SetUniform4f(10, L.groundAmbientColor.x, L.groundAmbientColor.y, L.groundAmbientColor.z, 1.0f); treeShader->SetUniform4f(11, 0.0f, 0.0f, 0.0f, 1.0f - (sky->GetLight()->GetGroundShadowDensity() * 0.5f)); treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB); glMatrixMode(GL_MATRIX0_ARB); glLoadMatrixf(shadowHandler->shadowMatrix.m); glMatrixMode(GL_MODELVIEW); } } else { glBindTexture(GL_TEXTURE_2D, activeFarTex); } const int cx = int(camera->pos.x / (SQUARE_SIZE * TREE_SQUARE_SIZE)); const int cy = int(camera->pos.z / (SQUARE_SIZE * TREE_SQUARE_SIZE)); CAdvTreeSquareDrawer drawer(this, cx, cy, treeDistance * SQUARE_SIZE * TREE_SQUARE_SIZE, drawDetailed); GML_STDMUTEX_LOCK(tree); // Draw oldTreeDistance = treeDistance; // draw far-trees using map-dependent grid-visibility readmap->GridVisibility(camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer); if (drawDetailed) { // draw near-trees const int xstart = std::max( 0, cx - 2); const int xend = std::min(gs->mapx / TREE_SQUARE_SIZE - 1, cx + 2); const int ystart = std::max( 0, cy - 2); const int yend = std::min(gs->mapy / TREE_SQUARE_SIZE - 1, cy + 2); if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) { treeShader->Disable(); treeShader = treeShaders[TREE_PROGRAM_NEAR_SHADOW]; treeShader->Enable(); if (globalRendering->haveGLSL) { treeShader->SetUniformMatrix4fv(7, false, &shadowHandler->shadowMatrix.m[0]); treeShader->SetUniform4fv(8, &(shadowHandler->GetShadowParams().x)); } glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); glActiveTexture(GL_TEXTURE0); } else { glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); treeShader = treeShaders[TREE_PROGRAM_NEAR_BASIC]; treeShader->Enable(); if (!globalRendering->haveGLSL) { #define MX (gs->pwr2mapx * SQUARE_SIZE) #define MY (gs->pwr2mapy * SQUARE_SIZE) treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB); treeShader->SetUniform4f(15, 1.0f / MX, 1.0f / MY, 1.0f / MX, 1.0f); #undef MX #undef MY } } if (globalRendering->haveGLSL) { treeShader->SetUniform3fv(0, &camera->right[0]); treeShader->SetUniform3fv(1, &camera->up[0]); treeShader->SetUniform2f(5, 0.20f * (1.0f / MAX_TREE_HEIGHT), 0.85f); } else { treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB); treeShader->SetUniform3f(13, camera->right.x, camera->right.y, camera->right.z); treeShader->SetUniform3f( 9, camera->up.x, camera->up.y, camera->up.z ); treeShader->SetUniform4f(11, L.groundSunColor.x, L.groundSunColor.y, L.groundSunColor.z, 0.85f); treeShader->SetUniform4f(14, L.groundAmbientColor.x, L.groundAmbientColor.y, L.groundAmbientColor.z, 0.85f); treeShader->SetUniform4f(12, 0.0f, 0.0f, 0.0f, 0.20f * (1.0f / MAX_TREE_HEIGHT)); // w = alpha/height modifier } glAlphaFunc(GL_GREATER, 0.5f); glDisable(GL_BLEND); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); varr = GetVertexArray(); varr->Initialize(); static FadeTree fadeTrees[3000]; FadeTree* pFT = fadeTrees; for (TreeSquareStruct* pTSS = trees + ystart * treesX; pTSS <= trees + yend * treesX; pTSS += treesX) { for (TreeSquareStruct* tss = pTSS + xstart; tss <= pTSS + xend; ++tss) { tss->lastSeen = gs->frameNum; varr->EnlargeArrays(12 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes for (std::map<int, TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) { const TreeStruct* ts = &ti->second; const float3 pos(ts->pos); if (!camera->InView(pos + float3(0.0f, MAX_TREE_HEIGHT / 2.0f, 0.0f), MAX_TREE_HEIGHT / 2.0f)) { continue; } const float camDist = (pos - camera->pos).SqLength(); int type = ts->type; float dy = 0.0f; unsigned int displist; if (type < 8) { dy = 0.5f; displist = treeGen->pineDL + type; } else { type -= 8; dy = 0.0f; displist = treeGen->leafDL + type; } if (camDist < (SQUARE_SIZE * SQUARE_SIZE * 110 * 110)) { // draw detailed near-distance tree (same as mid-distance trees without alpha) treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), pos.x, pos.y, pos.z); glCallList(displist); } else if (camDist < (SQUARE_SIZE * SQUARE_SIZE * 125 * 125)) { // draw mid-distance tree const float relDist = (pos.distance(camera->pos) - SQUARE_SIZE * 110) / (SQUARE_SIZE * 15); treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), pos.x, pos.y, pos.z); glAlphaFunc(GL_GREATER, 0.8f + relDist * 0.2f); glCallList(displist); glAlphaFunc(GL_GREATER, 0.5f); // save for second pass pFT->pos = pos; pFT->deltaY = dy; pFT->type = type; pFT->relDist = relDist; ++pFT; } else { // draw far-distance tree DrawTreeVertex(varr, pos, type * 0.125f, dy, false); } } } } // reset the world-offset treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), 0.0f, 0.0f, 0.0f); // draw trees that have been marked as falling for (std::list<FallingTree>::iterator fti = fallingTrees.begin(); fti != fallingTrees.end(); ++fti) { const float3 pos = fti->pos - UpVector * (fti->fallPos * 20); if (camera->InView(pos + float3(0.0f, MAX_TREE_HEIGHT / 2, 0.0f), MAX_TREE_HEIGHT / 2.0f)) { const float ang = fti->fallPos * PI; const float3 yvec(fti->dir.x * sin(ang), cos(ang), fti->dir.z * sin(ang)); const float3 zvec((yvec.cross(float3(-1.0f, 0.0f, 0.0f))).ANormalize()); const float3 xvec(yvec.cross(zvec)); CMatrix44f transMatrix(pos, xvec, yvec, zvec); glPushMatrix(); glMultMatrixf(&transMatrix[0]); int type = fti->type; int displist = 0; if (type < 8) { displist = treeGen->pineDL + type; } else { type -= 8; displist = treeGen->leafDL + type; } glCallList(displist); glPopMatrix(); } } if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) { treeShader->Disable(); treeShader = treeShaders[TREE_PROGRAM_DIST_SHADOW]; treeShader->Enable(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, activeFarTex); glActiveTexture(GL_TEXTURE0); } else { treeShader->Disable(); glBindTexture(GL_TEXTURE_2D, activeFarTex); } // draw far-distance trees varr->DrawArrayT(GL_QUADS); // draw faded mid-distance trees for (FadeTree* pFTree = fadeTrees; pFTree < pFT; ++pFTree) { varr = GetVertexArray(); varr->Initialize(); varr->CheckInitSize(12 * VA_SIZE_T); DrawTreeVertex(varr, pFTree->pos, pFTree->type * 0.125f, pFTree->deltaY, false); glAlphaFunc(GL_GREATER, 1.0f - (pFTree->relDist * 0.5f)); varr->DrawArrayT(GL_QUADS); } } if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) { treeShader->Disable(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); } else { glBindTexture(GL_TEXTURE_2D, 0); } glDisable(GL_TEXTURE_2D); glDisable(GL_FOG); glDisable(GL_ALPHA_TEST); // clean out squares from memory that are no longer visible const int startClean = lastListClean * 20 % (nTrees); const int endClean = gs->frameNum * 20 % (nTrees); lastListClean = gs->frameNum; if (startClean > endClean) { for (TreeSquareStruct* pTSS = trees + startClean; pTSS < trees + nTrees; ++pTSS) { if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->displist) { glDeleteLists(pTSS->displist, 1); pTSS->displist = 0; } if ((pTSS->lastSeenFar < gs->frameNum - 50) && pTSS->farDisplist) { glDeleteLists(pTSS->farDisplist, 1); pTSS->farDisplist = 0; } } for (TreeSquareStruct* pTSS = trees; pTSS < trees + endClean; ++pTSS) { if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->displist) { glDeleteLists(pTSS->displist, 1); pTSS->displist = 0; } if ((pTSS->lastSeenFar < gs->frameNum - 50) && pTSS->farDisplist) { glDeleteLists(pTSS->farDisplist, 1); pTSS->farDisplist = 0; } } } else { for (TreeSquareStruct* pTSS = trees + startClean; pTSS < trees + endClean; ++pTSS) { if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->displist) { glDeleteLists(pTSS->displist, 1); pTSS->displist = 0; } if ((pTSS->lastSeenFar < gs->frameNum - 50) && pTSS->farDisplist) { glDeleteLists(pTSS->farDisplist, 1); pTSS->farDisplist = 0; } } } #undef L }
void CGrassDrawer::SetupGlStateNear() { CBaseGroundDrawer* gd = readMap->GetGroundDrawer(); // bind textures { glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, grassBladeTex); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture()); glActiveTextureARB(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture()); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE3_ARB); glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture()); } glActiveTextureARB(GL_TEXTURE5_ARB); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cubeMapHandler->GetSpecularTextureID()); } // bind shader if (globalRendering->haveGLSL) { EnableShader(GRASS_PROGRAM_NEAR); if (shadowHandler->shadowsLoaded) { glActiveTextureARB(GL_TEXTURE4_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_ALPHA); } glMatrixMode(GL_PROJECTION); glPushMatrix(); glMultMatrixf(camera->GetViewMatrix()); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); } else { // FPP enable textures glActiveTextureARB(GL_TEXTURE0_ARB); glEnable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glMultiTexCoord4f(GL_TEXTURE1_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen SetTexGen(1.0f / (gs->mapx * SQUARE_SIZE), 1.0f / (gs->mapy * SQUARE_SIZE), 0.0f, 0.0f); glActiveTextureARB(GL_TEXTURE2_ARB); glEnable(GL_TEXTURE_2D); glMultiTexCoord4f(GL_TEXTURE2_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE3_ARB); glEnable(GL_TEXTURE_2D); glMultiTexCoord4f(GL_TEXTURE3_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); } } glActiveTextureARB(GL_TEXTURE0_ARB); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glDepthMask(GL_TRUE); ISky::SetupFog(); }
void CFeatureDrawer::Draw() { drawFar.clear(); if(gu->drawFog) { glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); } GML_RECMUTEX_LOCK(feat); // Draw fadeFeatures.clear(); fadeFeaturesS3O.clear(); CBaseGroundDrawer *gd = readmap->GetGroundDrawer(); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE2_ARB); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB); SetTexGen(1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,0); glBindTexture(GL_TEXTURE_2D, gd->infoTex); glActiveTextureARB(GL_TEXTURE0_ARB); } unitDrawer->SetupForUnitDrawing(); unitDrawer->SetupFor3DO(); DrawRaw(0, &drawFar); unitDrawer->CleanUp3DO(); unitDrawer->DrawQuedS3O(); unitDrawer->CleanUpUnitDrawing(); if (drawFar.size()>0) { glAlphaFunc(GL_GREATER, 0.5f); glEnable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, fartextureHandler->GetTextureID()); glColor3f(1.0f, 1.0f, 1.0f); glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(drawFar.size() * 4, 0, VA_SIZE_T); for (vector<CFeature*>::iterator it = drawFar.begin(); it != drawFar.end(); ++it) { fartextureHandler->DrawFarTexture(camera, (*it)->model, (*it)->pos, (*it)->radius, (*it)->heading, va); } va->DrawArrayT(GL_QUADS); glDisable(GL_ALPHA_TEST); } if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE2_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glActiveTextureARB(GL_TEXTURE0_ARB); } glDisable(GL_TEXTURE_2D); glDisable(GL_FOG); if(drawStat.size() > 0) { if(!water->drawReflection) { for (vector<CFeature *>::iterator fi = drawStat.begin(); fi != drawStat.end(); ++fi) DrawFeatureStats(*fi); } drawStat.clear(); } }
void CGrassDrawer::SetupGlStateFar() { assert(globalRendering->haveGLSL); CBaseGroundDrawer* gd = readMap->GetGroundDrawer(); const float3 windSpeed = wind.GetCurrentDirection() * wind.GetCurrentStrength() * mapInfo->grass.bladeWaveScale; glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.01f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); if (shadowHandler->shadowsLoaded) { grassShader = grassShaders[GRASS_PROGRAM_DIST_SHADOW]; grassShader->SetFlag("HAVE_INFOTEX", gd->DrawExtraTex()); grassShader->Enable(); grassShader->SetUniformMatrix4fv(6, false, &shadowHandler->shadowMatrix.m[0]); grassShader->SetUniform4fv(7, shadowHandler->GetShadowParams()); grassShader->SetUniform1f(8, gs->frameNum); grassShader->SetUniform3fv(9, &windSpeed.x); grassShader->SetUniform3fv(10, &camera->GetPos().x); glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture()); glActiveTextureARB(GL_TEXTURE1_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_ALPHA); static const float texConstant[] = { mapInfo->light.groundAmbientColor.x * 1.24f, mapInfo->light.groundAmbientColor.y * 1.24f, mapInfo->light.groundAmbientColor.z * 1.24f, 1.0f }; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texConstant); glActiveTextureARB(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture()); glActiveTextureARB(GL_TEXTURE3_ARB); glBindTexture(GL_TEXTURE_2D, farTex); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE4_ARB); glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture()); } glActiveTextureARB(GL_TEXTURE0_ARB); } else { grassShader = grassShaders[GRASS_PROGRAM_DIST_BASIC]; grassShader->Enable(); grassShader->SetUniform1f(8, gs->frameNum); grassShader->SetUniform3fv(9, &windSpeed.x); grassShader->SetUniform3fv(10, &camera->GetPos().x); glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture()); //glActiveTextureARB(GL_TEXTURE1_ARB); glActiveTextureARB(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture()); glActiveTextureARB(GL_TEXTURE3_ARB); glBindTexture(GL_TEXTURE_2D, farTex); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE4_ARB); glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture()); } glActiveTextureARB(GL_TEXTURE0_ARB); } }
void CGrassDrawer::SetupGlStateNear() { CBaseGroundDrawer* gd = readMap->GetGroundDrawer(); const float3 windSpeed = wind.GetCurrentDirection() * wind.GetCurrentStrength() * mapInfo->grass.bladeWaveScale; if (shadowHandler->shadowsLoaded && globalRendering->haveGLSL) { grassShader = grassShaders[GRASS_PROGRAM_NEAR_SHADOW]; grassShader->SetFlag("HAVE_INFOTEX", gd->DrawExtraTex()); grassShader->Enable(); grassShader->SetUniform2f(2, 0.0f, 0.0f); grassShader->SetUniformMatrix4fv(6, false, shadowHandler->shadowMatrix); grassShader->SetUniform4fv(7, shadowHandler->GetShadowParams()); grassShader->SetUniform1f(8, gs->frameNum); grassShader->SetUniform3fv(9, &windSpeed.x); grassShader->SetUniform3fv(10, &camera->GetPos().x); glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture()); glActiveTextureARB(GL_TEXTURE1_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_ALPHA); static const float texConstant[] = { mapInfo->light.groundAmbientColor.x * 1.24f, mapInfo->light.groundAmbientColor.y * 1.24f, mapInfo->light.groundAmbientColor.z * 1.24f, 1.0f }; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texConstant); glActiveTextureARB(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture()); glActiveTextureARB(GL_TEXTURE3_ARB); glBindTexture(GL_TEXTURE_2D, grassBladeTex); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE4_ARB); glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture()); } glActiveTextureARB(GL_TEXTURE0_ARB); if (!globalRendering->haveGLSL) { glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE2_ARB); glEnable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE3_ARB); glEnable(GL_TEXTURE_2D); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE4_ARB); glEnable(GL_TEXTURE_2D); } glActiveTextureARB(GL_TEXTURE0_ARB); glEnable(GL_TEXTURE_2D); } glMatrixMode(GL_PROJECTION); glPushMatrix(); glMultMatrixf(camera->GetViewMatrix()); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); } else { glActiveTextureARB(GL_TEXTURE0_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, grassBladeTex); glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture()); glMultiTexCoord4f(GL_TEXTURE1_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen SetTexGen(1.0f / (gs->mapx * SQUARE_SIZE), 1.0f / (gs->mapy * SQUARE_SIZE), 0.0f, 0.0f); glActiveTextureARB(GL_TEXTURE2_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture()); glMultiTexCoord4f(GL_TEXTURE2_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE3_ARB); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); glMultiTexCoord4f(GL_TEXTURE3_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture()); glActiveTextureARB(GL_TEXTURE0_ARB); } glActiveTextureARB(GL_TEXTURE0_ARB); } glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glDepthMask(GL_TRUE); ISky::SetupFog(); }
void CGroundDecalHandler::Draw(void) { if (!drawDecals) { return; } glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-10, -200); glDepthMask(0); glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, readmap->GetShadingTexture()); SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0, 0); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); CBaseGroundDrawer *gd = readmap->GetGroundDrawer(); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE3_ARB); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_ARB,GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB); SetTexGen(1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,0); glBindTexture(GL_TEXTURE_2D, gd->infoTex); } glActiveTextureARB(GL_TEXTURE0_ARB); if (shadowHandler && shadowHandler->drawShadows) { glActiveTextureARB(GL_TEXTURE2_ARB); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 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); glActiveTextureARB(GL_TEXTURE0_ARB); if (readmap->GetShadingTexture() == 0) { glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, decalFPsm3); } else { // also used for SM3 maps with baked lighting glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, decalFPsmf); } glEnable(GL_FRAGMENT_PROGRAM_ARB); glBindProgramARB(GL_VERTEX_PROGRAM_ARB, decalVP); glEnable(GL_VERTEX_PROGRAM_ARB); const float3 ac = mapInfo->light.groundAmbientColor * (210.0f / 255.0f); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 10, 1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0, 1); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 10, ac.x, ac.y, ac.z, 1); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 11, 0, 0, 0, mapInfo->light.groundShadowDensity); glMatrixMode(GL_MATRIX0_ARB); glLoadMatrixf(shadowHandler->shadowMatrix.m); glMatrixMode(GL_MODELVIEW); } // create and draw the quads for each building decal for (std::vector<BuildingDecalType*>::iterator bdti = buildingDecalTypes.begin(); bdti != buildingDecalTypes.end(); ++bdti) { BuildingDecalType* bdt = *bdti; if (!bdt->buildingDecals.empty()) { glBindTexture(GL_TEXTURE_2D, bdt->texture); decalsToDraw.clear(); { GML_STDMUTEX_LOCK(decal); // Draw set<BuildingGroundDecal*>::iterator bgdi = bdt->buildingDecals.begin(); while (bgdi != bdt->buildingDecals.end()) { BuildingGroundDecal* decal = *bgdi; if (decal->owner && decal->owner->buildProgress >= 0) { decal->alpha = decal->owner->buildProgress; } else if (!decal->gbOwner) { decal->alpha -= decal->alphaFalloff * globalRendering->lastFrameTime * gs->speedFactor; } if (decal->alpha < 0.0f) { // make sure RemoveBuilding() won't try to modify this decal if (decal->owner) { decal->owner->buildingDecal = 0; } delete decal; set<BuildingGroundDecal*>::iterator next(bgdi); ++next; bdt->buildingDecals.erase(bgdi); bgdi = next; continue; } if (!decal->owner || (decal->owner->losStatus[gu->myAllyTeam] & (LOS_INLOS | LOS_PREVLOS)) || gu->spectatingFullView) { decalsToDraw.push_back(decal); } bgdi++; } } for(std::vector<BuildingGroundDecal*>::iterator di = decalsToDraw.begin(); di != decalsToDraw.end(); ++di) { BuildingGroundDecal *decal = *di; if (camera->InView(decal->pos, decal->radius)) { DrawBuildingDecal(decal); } } //glBindTexture(GL_TEXTURE_2D, 0); } } if (shadowHandler && shadowHandler->drawShadows) { glDisable(GL_FRAGMENT_PROGRAM_ARB); glDisable(GL_VERTEX_PROGRAM_ARB); glActiveTextureARB(GL_TEXTURE2_ARB); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE1_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); glActiveTextureARB(GL_TEXTURE0_ARB); } glPolygonOffset(-10, -20); unsigned char color[4] = {255, 255, 255, 255}; unsigned char color2[4] = {255, 255, 255, 255}; { GML_STDMUTEX_LOCK(track); // Draw // Delayed addition of new tracks for (std::vector<TrackToAdd>::iterator ti = tracksToBeAdded.begin(); ti != tracksToBeAdded.end(); ++ti) { TrackToAdd *tta = &(*ti); if(tta->ts->owner == NULL) { delete tta->tp; if(tta->unit == NULL) tracksToBeDeleted.push_back(tta->ts); continue; // unit removed } CUnit *unit = tta->unit; if(unit == NULL) { unit = tta->ts->owner; trackTypes[unit->unitDef->trackType]->tracks.insert(tta->ts); } TrackPart *tp = tta->tp; //if the unit is moving in a straight line only place marks at half the rate by replacing old ones bool replace = false; if(unit->myTrack->parts.size()>1) { list<TrackPart *>::iterator pi = --unit->myTrack->parts.end(); list<TrackPart *>::iterator pi2 = pi--; if(((tp->pos1+(*pi)->pos1)*0.5f).SqDistance((*pi2)->pos1)<1) replace = true; } if(replace) { delete unit->myTrack->parts.back(); unit->myTrack->parts.back() = tp; } else { unit->myTrack->parts.push_back(tp); } } tracksToBeAdded.clear(); } for (std::vector<UnitTrackStruct *>::iterator ti = tracksToBeDeleted.begin(); ti != tracksToBeDeleted.end(); ++ti) { delete *ti; } tracksToBeDeleted.clear(); tracksToBeCleaned.clear(); // create and draw the unit footprint quads for (std::vector<TrackType*>::iterator tti = trackTypes.begin(); tti != trackTypes.end(); ++tti) { TrackType* tt = *tti; if (!tt->tracks.empty()) { set<UnitTrackStruct*>::iterator utsi = tt->tracks.begin(); CVertexArray* va = GetVertexArray(); va->Initialize(); glBindTexture(GL_TEXTURE_2D, tt->texture); while (utsi != tt->tracks.end()) { UnitTrackStruct* track = *utsi; if (track->parts.empty()) { tracksToBeCleaned.push_back(TrackToClean(track, &(tt->tracks))); continue; } if (track->parts.front()->creationTime < gs->frameNum - track->lifeTime) { tracksToBeCleaned.push_back(TrackToClean(track, &(tt->tracks))); } if (camera->InView((track->parts.front()->pos1 + track->parts.back()->pos1) * 0.5f, track->parts.front()->pos1.distance(track->parts.back()->pos1) + 500)) { list<TrackPart *>::iterator ppi = track->parts.begin(); color2[3] = std::max(0, track->trackAlpha - (int) ((gs->frameNum - (*ppi)->creationTime) * track->alphaFalloff)); va->EnlargeArrays(track->parts.size()*4,0,VA_SIZE_TC); for (list<TrackPart *>::iterator pi = ++track->parts.begin(); pi != track->parts.end(); ++pi) { color[3] = std::max(0, track->trackAlpha - (int) ((gs->frameNum - (*ppi)->creationTime) * track->alphaFalloff)); if ((*pi)->connected) { va->AddVertexQTC((*ppi)->pos1, (*ppi)->texPos, 0, color2); va->AddVertexQTC((*ppi)->pos2, (*ppi)->texPos, 1, color2); va->AddVertexQTC((*pi)->pos2, (*pi)->texPos, 1, color); va->AddVertexQTC((*pi)->pos1, (*pi)->texPos, 0, color); } color2[3] = color[3]; ppi = pi; } } utsi++; } va->DrawArrayTC(GL_QUADS); } } { GML_STDMUTEX_LOCK(track); // Draw // Cleanup old tracks for (std::vector<TrackToClean>::iterator ti = tracksToBeCleaned.begin(); ti != tracksToBeCleaned.end(); ++ti) { TrackToClean *ttc = &(*ti); UnitTrackStruct *track = ttc->track; while (!track->parts.empty() && track->parts.front()->creationTime < gs->frameNum - track->lifeTime) { delete track->parts.front(); track->parts.pop_front(); } if (track->parts.empty()) { if (track->owner) { track->owner->myTrack = 0; track->owner = 0; } ttc->tracks->erase(track); tracksToBeDeleted.push_back(track); } } } glBindTexture(GL_TEXTURE_2D, scarTex); glPolygonOffset(-10, -400); scarsToBeChecked.clear(); { GML_STDMUTEX_LOCK(scar); // Draw for (std::vector<Scar*>::iterator si = scarsToBeAdded.begin(); si != scarsToBeAdded.end(); ++si) scarsToBeChecked.push_back(*si); scarsToBeAdded.clear(); } for (std::vector<Scar*>::iterator si = scarsToBeChecked.begin(); si != scarsToBeChecked.end(); ++si) { Scar* s = *si; TestOverlaps(s); int x1 = s->x1 / 16; int x2 = min(scarFieldX - 1, s->x2 / 16); int y1 = s->y1 / 16; int y2 = min(scarFieldY - 1, s->y2 / 16); for (int y = y1; y <= y2; ++y) { for (int x = x1; x <= x2; ++x) { std::set<Scar*>* quad = &scarField[y * scarFieldX + x]; quad->insert(s); } } scars.push_back(s); } // create and draw the 16x16 quads for each ground scar for (std::list<Scar*>::iterator si = scars.begin(); si != scars.end(); ) { Scar* scar = *si; if (scar->lifeTime < gs->frameNum) { RemoveScar(*si, false); si = scars.erase(si); continue; } if (camera->InView(scar->pos, scar->radius + 16)) { DrawGroundScar(scar, groundScarAlphaFade); } ++si; } glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_BLEND); glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glActiveTextureARB(GL_TEXTURE3_ARB); //! infotex glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glActiveTextureARB(GL_TEXTURE0_ARB); }