⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unitdrawer.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
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 + -