Пример #1
0
/**
 * @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;
}
Пример #2
0
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();
}