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); }
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 ); }