예제 #1
0
void MainWindow::OnCreate()
{
	glewInit();

	if (GL_ARB_vertex_array_object) {
		GLuint vao;
		glGenVertexArrays(1, &vao);
		glBindVertexArray(vao);
	}

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
	glEnable(GL_MULTISAMPLE);
	glEnable(GL_COLOR_MATERIAL);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glClearColor(0.82f, 0.85f, 0.96f, 1.0f);

	const char *sides[6] = 
	{
		"textures/skybox/ft.tga",
		"textures/skybox/bk.tga",
		"textures/skybox/up.tga",
		"textures/skybox/dn.tga",
		"textures/skybox/lf.tga",
		"textures/skybox/rt.tga",
	};

	skybox = new Skybox(m_rc, sides);
	mainShader = new ProgramObject(m_rc, "shaders/main.vert.glsl", "shaders/main.frag.glsl");
	terrainShader = new ProgramObject(m_rc, "shaders/terrain.vert.glsl", "shaders/terrain.frag.glsl");
	grass_mesh = new Mesh(m_rc);
	gun = new Model(m_rc);
	muzzle_flash = new Model(m_rc);
	crosshair = new Model(m_rc);
	terrain = new Terrain(m_rc);

	grassShader = new ProgramObject(m_rc);
	grassShader->BindAttribLocation(5, "TopPos");
	grassShader->BindAttribLocation(6, "BottomPos");
	grassShader->AttachShader(Shader(GL_VERTEX_SHADER, "shaders/grass.vert.glsl"));
	grassShader->AttachShader(Shader(GL_FRAGMENT_SHADER, "shaders/grass.frag.glsl"));
	grassShader->Link();

	tex_grassobj = new Texture2D("textures/grassobj.tga");
	tex_ground = new Texture2D("textures/ground.tga", GL_TEXTURE0);
	tex_grass = new Texture2D("textures/grass.tga", GL_TEXTURE1);
	tex_rocks = new Texture2D("textures/rocks.tga", GL_TEXTURE2);

	tex_grassobj->SetFilters(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
	tex_grassobj->SetWrapMode(GL_CLAMP, GL_CLAMP);
	tex_ground->SetFilters(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
	tex_grass->SetFilters(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
	tex_rocks->SetFilters(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
	tex_grassobj->BuildMipmaps();
	tex_ground->BuildMipmaps();
	tex_grass->BuildMipmaps();
	tex_rocks->BuildMipmaps();
	
	terrain->LoadHeightmap("textures/hm.tga", heightScale);

	GenerateGrass(grass_mesh);
	grass_mesh->BindTexture(*tex_grassobj);

	Texture2D gun_diffuse("textures/gun/diffuse.tga", GL_TEXTURE0),
			  gun_normal("textures/gun/normal.tga", GL_TEXTURE1),
			  gun_specular("textures/gun/specular.tga", GL_TEXTURE2);
	gun_diffuse.SetFilters(GL_LINEAR, GL_LINEAR);
	gun_normal.SetFilters(GL_LINEAR, GL_LINEAR);
	gun_specular.SetFilters(GL_LINEAR, GL_LINEAR);

	gun->LoadObj("models/gun.obj");
	gun->meshes[0]->BindTexture(gun_diffuse);
	gun->meshes[0]->BindNormalMap(gun_normal);
	gun->meshes[0]->BindSpecularMap(gun_specular);
	gun->BindShader(*mainShader);
	gun->location = Vector3f(0.7f, -2.0f, -2.0f);
	gun->scale = Vector3f(-1, 1, -1);

	Texture2D tex_muzzle("textures/muzzle.tga");
	tex_muzzle.SetFilters(GL_LINEAR, GL_LINEAR);
	muzzle_flash->LoadObj("models/quad.obj");
	muzzle_flash->meshes[0]->BindTexture(tex_muzzle);
	muzzle_flash->BindShader(*mainShader);
	muzzle_flash->location = Vector3f(0.72f, -0.26f, -3.5f);

	Texture2D tex_ie("textures/ie.tga");
	tex_ie.SetFilters(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
	tex_ie.BuildMipmaps();

	Model target(m_rc);
	target.LoadObj("models/target.obj");
	target.meshes[0]->BindTexture(tex_ie);
	target.meshes[1]->BindTexture(tex_ie);
	target.BindShader(*mainShader);

	targets = new Target[numTargets];
	Vector2i s = terrain->GetSize();
	for (int i = 0; i < numTargets; i++)
	{
		targets[i].model = new Model(target);
		float x = (float)(rand() % (s.x - 1) - s.x/2 + 1);
		float z = (float)(rand() % (s.y - 1) - s.y/2 + 1);
		float a = (float)(rand() % 360);
		targets[i].model->location = Vector3f(x, terrain->GetHeightAt(x, z), z);
		targets[i].model->rotation = Quaternion(Vector3f(0,1,0), a);
	}

	Texture2D tex_corsshair("textures/crosshair.tga");
	tex_corsshair.SetFilters(GL_LINEAR, GL_LINEAR);
	crosshair->AddMesh(*muzzle_flash->meshes[0]);
	crosshair->meshes[0]->BindTexture(tex_corsshair);
	crosshair->BindShader(*mainShader);
	crosshair->scale = Vector3f(4.0f);

	mainShader->Uniform("ColorMap", 0);
	mainShader->Uniform("NormalMap", 1);
	mainShader->Uniform("SpecularMap", 2);
	mainShader->Uniform("FrontMaterial.shininess", 100);

	terrainShader->Uniform("FrontMaterial.diffuse", 0.5f, 0.5f, 0.5f);
	terrainShader->Uniform("HeightScale", heightScale);
	terrainShader->Uniform("tex_ground", 0);
	terrainShader->Uniform("tex_grass", 1);
	terrainShader->Uniform("tex_rocks", 2);

	grassShader->Uniform("tex_grass", 0);
	camera.SetPosition(0, growth + terrain->GetHeightAt(0, 0), 0);
}
예제 #2
0
bool WorldRenderer::Update()
{
	// Update Terrain Routine
	UpdateTerrain();

	// Cam Pos
	Vector3 camPos = zGraphics->GetCamera()->GetPosition();

	// Don't update grass if we don't have a world
	if ( zWorld )
	{
		// Check if we should render grass
		zGraphics->SetGrassFilePath("Media/Grass.png");
		if ( zGraphics->GetRenderGrassFlag() )
		{
			if ( (zLastGrassUpdatePos - camPos.GetXZ()).GetLength() >= zGrassUpdateDistance )
			{
				std::map<Vector2UINT, int> grassSectors;

				// Remove Current Grass Sectors
				for( auto i = zGrass.cbegin(); i != zGrass.cend(); ++i )
				{
					grassSectors[i->first]--;
				}

				// Insert New Sectors
				std::set<Vector2UINT> newSectorsSet;
				zWorld->GetSectorsInCicle(camPos.GetXZ(), zGrassFarDistance, newSectorsSet);
				for( auto i = newSectorsSet.cbegin(); i != newSectorsSet.cend(); ++i )
				{
					grassSectors[*i]++;
				}

				// Update Sector Grasses
				for( auto i = grassSectors.cbegin(); i != grassSectors.cend(); ++i )
				{
					if ( i->second < 0 )
					{
						auto grassIt = zGrass.find(i->first);
						if ( grassIt != zGrass.cend() )
						{
							if ( grassIt->second )
							{
								zGraphics->DeleteBillboardCollection(grassIt->second);
							}

							zGrass.erase(grassIt);
						}
					}
					else if ( i->second > 0 )
					{
						GenerateGrass(i->first);
					}
				}

				zLastGrassUpdatePos = camPos.GetXZ();
			}
		}
	}

	// Check Distance
	if ( (zLastEntUpdatePos - camPos).GetLength() > 10.0f )
	{
		// Update Existing LOD
		for( auto i = zEntities.cbegin(); i != zEntities.cend(); ++i )
		{
			zEntsToUpdate.insert(i->first);
		}

		// Scan New Entities
		if ( zWorld ) 
		{
			zWorld->GetEntitiesInCircle(camPos.GetXZ(), zGraphics->GetEngineParameters().FarClip, zEntsToUpdate);
		}

		// Update Position
		zLastEntUpdatePos = camPos;
	}
	
	// Update a between 10% and a minimum of 25
	unsigned int x = zEntsToUpdate.size() / 10;
	if ( x < 25 ) x = 25;
	if ( x > 100 ) x = 100;
	auto i = zEntsToUpdate.begin();
	while( i != zEntsToUpdate.end() )
	{
		SetEntityGraphics(*i);
		i = zEntsToUpdate.erase(i);
		if ( !x || !--x ) break;
	}

	// Check if there is more to be updated
	return ( zEntsToUpdate.size() > 0 || zUpdatesRequired.size() > 0 );
}