/** * @brief Really create the far texture for the given model. */ void CFarTextureHandler::CreateFarTexture(const CSolidObject* obj) { const S3DModel* model = obj->model; // make space in the std::vectors if (obj->team >= (int)cache.size()) { cache.resize(obj->team + 1); } if (model->id >= (int)cache[obj->team].size()) { cache[obj->team].resize(model->id + 1, 0); } cache[obj->team][model->id] = -1; // enough free space in the atlas? if (!CheckResizeAtlas()) { return; } // NOTE: // the icons are RTT'ed using a snapshot of the // current state (advModelShading, sunDir, etc) // and will not track later state-changes fbo.Bind(); fbo.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT16, texSizeX, texSizeY); fbo.CheckStatus("FARTEXTURE"); glPushAttrib(GL_ALL_ATTRIB_BITS); glDisable(GL_BLEND); glFrontFace(GL_CW); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, 0.0f); glFogf(GL_FOG_END, 1e6); glFogf(GL_FOG_DENSITY, 1.0f); unitDrawer->SetupForUnitDrawing(); unitDrawer->GetOpaqueModelRenderer(model->type)->PushRenderState(); unitDrawer->SetTeamColour(obj->team); if (model->type != MODELTYPE_3DO) { texturehandlerS3O->SetS3oTexture(model->textureType); } //const float xs = std::max(math::fabs(model->relMidPos.x + model->maxs.x), math::fabs(model->relMidPos.x + model->mins.x)); //const float ys = std::max(math::fabs(model->relMidPos.y + model->maxs.y), math::fabs(model->relMidPos.y + model->mins.y)); //const float zs = std::max(math::fabs(model->relMidPos.z + model->maxs.z), math::fabs(model->relMidPos.z + model->mins.z)); //const float modelradius = std::max(xs, std::max(ys, zs));*/ const float modelradius = 1.15f * model->radius; // overwrite the matrices set by SetupForUnitDrawing // RTT with a top-down view; the view-matrix must be // on the PROJECTION stack for the model shaders glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-modelradius, modelradius, -modelradius, modelradius, -modelradius, modelradius); glRotatef(45.0f, 1.0f, 0.0f, 0.0f); glScalef(-1.0f, 1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); for (int orient = 0; orient < numOrientations; ++orient) { // setup viewport const int2 pos = GetTextureCoordsInt(usedFarTextures, orient); glViewport(pos.x * iconSizeX, pos.y * iconSizeY, iconSizeX, iconSizeY); glClear(GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0f, -model->height * 0.5f, 0.0f); // draw model model->DrawStatic(); glPopMatrix(); // rotate by 360 / numOrientations degrees for the next orientation glRotatef(-360.0f / numOrientations, 0.0f, 1.0f, 0.0f); } glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); unitDrawer->GetOpaqueModelRenderer(model->type)->PopRenderState(); unitDrawer->CleanUpUnitDrawing(); // glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY); glPopAttrib(); fbo.Detach(GL_DEPTH_ATTACHMENT_EXT); fbo.Unbind(); cache[obj->team][model->id] = ++usedFarTextures; }
void CFarTextureHandler::Draw() { if (queuedForRender.empty()) { return; } { // check if there is enough free space in the atlas, if not try resizing // it (as many times as the number of models queued for iconification) unsigned int maxNewIcons = 0; for (unsigned int n = 0; n < queuedForRender.size(); n++) { if (!CheckResizeAtlas(n + 1)) { break; } maxNewIcons++; } // now create the new far-icons // NOTE: // the icons are RTT'ed using a snapshot of the // current state (advModelShading, sunDir, etc) // and will not track later state-changes unitDrawer->SetupForUnitDrawing(); GML_VECTOR<const CSolidObject*>::iterator it; for (it = queuedForRender.begin(); it != queuedForRender.end() && maxNewIcons > 0; ++it) { maxNewIcons--; const CSolidObject* obj = *it; const S3DModel* mdl = obj->model; unitDrawer->GetOpaqueModelRenderer(mdl->type)->PushRenderState(); unitDrawer->SetTeamColour(obj->team); if (mdl->type != MODELTYPE_3DO) { texturehandlerS3O->SetS3oTexture(mdl->textureType); } if ((int)cache.size() <= obj->team || (int)cache[obj->team].size() <= mdl->id || !cache[obj->team][mdl->id]) { CreateFarTexture(obj); } unitDrawer->GetOpaqueModelRenderer(mdl->type)->PopRenderState(); } unitDrawer->CleanUpUnitDrawing(); } glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, farTextureID); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x); ISky::SetupFog(); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(queuedForRender.size() * 4, 0, VA_SIZE_T); for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { DrawFarTexture(*it, va); } va->DrawArrayT(GL_QUADS); glDisable(GL_ALPHA_TEST); queuedForRender.clear(); }