//-------------------------------------------------------------- // constructor Planet::Planet( const mgOptionsFile& options) { mgVertex::loadShader("cave"); m_outsideIndexes = NULL; m_outsideVertexes = NULL; m_insideIndexes = NULL; m_insideVertexes = NULL; m_lavaIndexes = NULL; m_lavaVertexes = NULL; mgString fileName; options.getFileName("asteroid-outside", options.m_sourceFileName, "terrain.jpg", fileName); m_outsideTexture = mgDisplay->loadTexture(fileName); options.getFileName("asteroid-inside", options.m_sourceFileName, "terrain.jpg", fileName); m_insideTexture = mgDisplay->loadTexture(fileName); options.getFileName("asteroid-lava", options.m_sourceFileName, "terrain.jpg", fileName); m_lavaTexture = mgDisplay->loadTexture(fileName); m_outsideRadius = 200.0; m_outsideHeight = 50.0; m_insideRadius = 270.0; m_insideHeight = 170.0; m_lavaRadius = 120.0; m_samples = 64; }
//-------------------------------------------------------------- // constructor Ring::Ring( const mgOptionsFile& options, double radius, double wallHeight, double wallWidth) { mgVertexTA::loadShader("litTextureArray"); m_radius = radius; m_wallHeight = wallHeight; m_wallWidth = wallWidth; m_ringWidth = (m_radius*2*PI*32)/2048; m_ringThick = m_wallWidth; mgString ringFront; options.getFileName("ring-front", options.m_sourceFileName, "", ringFront); mgString ringBack; options.getFileName("ring-back", options.m_sourceFileName, "", ringBack); mgStringArray filenames; filenames.add(ringFront); filenames.add(ringBack); m_farTexture = mgDisplay->loadTextureArray(filenames); m_farVertexes = NULL; m_farIndexes = NULL; }
//-------------------------------------------------------------- // constructor SolarSystem::SolarSystem( const mgOptionsFile& options) { m_planetDayLen = options.getDouble("planetDayLen", 600.0); // seconds if (m_planetDayLen == 0.0) m_planetDayLen = 1e10; // infinity m_moonDayLen = options.getDouble("moonDayLen", 300.0); // seconds if (m_moonDayLen == 0.0) m_moonDayLen = 1e10; // infinity m_ringDayLen = options.getDouble("ringDayLen", 200.0); // seconds if (m_ringDayLen == 0.0) m_ringDayLen = 1e10; // infinity m_moonMonthLen = options.getDouble("moonMonthLen", 1000.0); // seconds if (m_moonMonthLen == 0.0) m_moonMonthLen = 1e10; // infinity m_beltMonthLen = options.getDouble("beltMonthLen", 1000.0); // seconds if (m_beltMonthLen == 0.0) m_beltMonthLen = 1e10; // infinity m_planet = new Planet(options, PLANET_RADIUS); // m_belt = new Belt(options, BELT_RADIUS); m_moon = new Moon(options, MOON_RADIUS); m_ring = new Ring(options, RING_RADIUS, RING_WALL_HEIGHT, RING_WALL_WIDTH); m_planetDay = 90.0; m_moonDay = 0.0; m_ringDay = 0.0; m_moonMonth = 30.0; m_beltMonth = 0.0; m_coordSystem = COORDS_PLANET; m_coordPosn = mgPoint3(0.0, 2.0, 0.0); m_eyeRotX = 0.0; m_eyeRotY = 0.0; m_eyeRotZ = 0.0; mgDebug("Planet radius = %g km (%g miles)", PLANET_RADIUS/1000.0, PLANET_RADIUS/1600.0); double val = 4*PI*PLANET_RADIUS*PLANET_RADIUS; mgDebug("Surface area of planet = %g million sq km (%g million sq mi)", val/1e12, (val/1e12)/1.609); mgDebug("Moon radius = %g km (%g miles)", MOON_RADIUS/1000.0, MOON_RADIUS/1600.0); val = 4*PI*MOON_RADIUS*MOON_RADIUS; mgDebug("Surface area of moon = %g million sq km (%g million sq mi)", val/1e12, (val/1e12)/1.609); mgDebug("Moon distance = %g km (%g miles)", MOON_DISTANCE/1000.0, MOON_DISTANCE/1600.0); mgDebug("Ring radius = %g km (%g miles)", RING_RADIUS/1000.0, RING_RADIUS/1600.0); val = 2*PI*RING_RADIUS*RING_WIDTH; mgDebug("Surface area of ring = %g million sq km (%g million sq mi)", val/1e12, (val/1e12)/1.609); mgDebug("Ring width = %g m (%g ft)", RING_WIDTH, RING_WIDTH*3.16); mgDebug("Ring wall height = %g m (%g ft)", RING_WALL_HEIGHT, RING_WALL_HEIGHT*3.16); mgDebug("Ring wall width = %g m (%g ft)", RING_WALL_WIDTH, RING_WALL_WIDTH*3.16); }
//-------------------------------------------------------------- // constructor Wreck::Wreck( const mgOptionsFile& options) { m_indexes = NULL; m_vertexes = NULL; // load ball textures. must all be same size. mgStringArray fileList; mgString fileName; options.getFileName("wreck-shell", options.m_sourceFileName, "wreck-shell.jpg", fileName); fileList.add(fileName); m_texture = mgDisplay->loadTextureArray(fileList); for (int i = 0; i < 6; i++) { // omit the wrecked towers if (i == 2 || i == 5) m_towers.add(NULL); else { Tower* tower = new Tower(options, true); m_towers.add(tower); } } }
//----------------------------------------------------------------------------- // compile the shader void Planet::compileShader( const mgOptionsFile& options) { // compile the shader mgDebug("compile planet shader:"); mgString fileName; options.getFileName("planetVertexShader", options.m_sourceFileName, "", fileName); const char* vertexSource = loadFile(fileName); options.getFileName("planetFragmentShader", options.m_sourceFileName, "", fileName); const char* fragmentSource = loadFile(fileName); int attribCount = 2; const char* attribNames[] = {"vertPoint", "modelPoint"}; const DWORD attribIndexes[] = {0, 1}; m_planetShader = mgPlatform->compileGLShaderPair(vertexSource, fragmentSource, attribCount, attribNames, attribIndexes); delete vertexSource; delete fragmentSource; }
//-------------------------------------------------------------- // constructor Moon::Moon( const mgOptionsFile& options, double radius) { mgVertex::loadShader("litTextureCube"); m_radius = radius/SYSTEM_FAR_SCALE; mgString xminFace, xmaxFace, yminFace, ymaxFace, zminFace, zmaxFace; options.getFileName("moon-xmin", options.m_sourceFileName, "", xminFace); options.getFileName("moon-xmax", options.m_sourceFileName, "", xmaxFace); options.getFileName("moon-ymin", options.m_sourceFileName, "", yminFace); options.getFileName("moon-ymax", options.m_sourceFileName, "", ymaxFace); options.getFileName("moon-zmin", options.m_sourceFileName, "", zminFace); options.getFileName("moon-zmax", options.m_sourceFileName, "", zmaxFace); m_farTexture = mgDisplay->loadTextureCube(xminFace, xmaxFace, yminFace, ymaxFace, zminFace, zmaxFace); m_farVertexes = NULL; m_farIndexes = NULL; }
//-------------------------------------------------------------- // constructor Intro::Intro( const mgOptionsFile& options, const mgPoint3& origin) { m_origin = origin; // load wall texture mgString fileName; options.getFileName("tube", options.m_sourceFileName, "tube.jpg", fileName); m_tubeTexture = mgDisplay->loadTexture(fileName); options.getFileName("intro-wall", options.m_sourceFileName, "tube.jpg", fileName); m_wallTexture = mgDisplay->loadTexture(fileName); m_saucer = new Saucer(options); m_tube = new Tube(TUBE_RADIUS, TUBE_STEPS); m_wall = new Tube(WALL_RADIUS, WALL_STEPS); initTrack(); m_ballPosn = 0.0; updateBallPt(); }
//-------------------------------------------------------------- // constructor ChunkWorld::ChunkWorld( const mgOptionsFile& options) { BrickBlob::staticInit(); loadShaders(); // read the brick set to use mgString fileName; options.getFileName("brickSet", options.m_sourceFileName, "bricks.xml", fileName); BrickSetFile brickSetFile(fileName); readBrickSet(brickSetFile); loadWaterTexture(brickSetFile); m_textureArray = mgDisplay->loadTextureArray(m_textureFiles); m_displayMemLimit = options.getInteger("displayMemory", 200); m_displayMemLimit *= 1024*1024; // megabytes m_systemMemLimit = options.getInteger("systemMemory", 400); m_systemMemLimit *= 1024*1024; // megabytes m_threadCount = options.getInteger("threadCount", 1); #ifdef EMSCRIPTEN m_threadCount = 0; #endif m_viewDistance = options.getInteger("viewDistance", 300); // since the view list goes up as the cube of distance, limit it m_viewDistance = min(450, m_viewDistance); m_sortCount = options.getInteger("sortCount", 5); options.getPoint("torchColor", mgPoint3(0.5, 0.5, 0.1), m_torchColor); mgDebug("thread count: %d", m_threadCount); m_viewList = NULL; createViewList(m_viewDistance); createHorizon(); createWater(); m_displayMemUsed = 0; m_systemMemUsed = 0; m_shutdown = false; m_chunksChanged = false; createWorkers(); }
//-------------------------------------------------------------- // constructor Planet::Planet( const mgOptionsFile& options) { // load the planet cubemap texture mgString xminName, xmaxName, yminName, ymaxName, zminName, zmaxName; options.getFileName("planet-xmin", options.m_sourceFileName, "", xminName); options.getFileName("planet-xmax", options.m_sourceFileName, "", xmaxName); options.getFileName("planet-ymin", options.m_sourceFileName, "", yminName); options.getFileName("planet-ymax", options.m_sourceFileName, "", ymaxName); options.getFileName("planet-zmin", options.m_sourceFileName, "", zminName); options.getFileName("planet-zmax", options.m_sourceFileName, "", zmaxName); m_surfaceTexture = loadCubeMap(xminName, xmaxName, yminName, ymaxName, zminName, zmaxName); // load the clouds cubemap texture options.getFileName("clouds-xmin", options.m_sourceFileName, "", xminName); options.getFileName("clouds-xmax", options.m_sourceFileName, "", xmaxName); options.getFileName("clouds-ymin", options.m_sourceFileName, "", yminName); options.getFileName("clouds-ymax", options.m_sourceFileName, "", ymaxName); options.getFileName("clouds-zmin", options.m_sourceFileName, "", zminName); options.getFileName("clouds-zmax", options.m_sourceFileName, "", zmaxName); m_cloudsTexture = loadCubeMap(xminName, xmaxName, yminName, ymaxName, zminName, zmaxName); compileShader(options); // create the vertex buffer glGenVertexArrays(1, &m_vertexArray); glBindVertexArray(m_vertexArray); glGenBuffers(1, &m_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexPlanet), (const GLvoid*) offsetof(VertexPlanet, m_px)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexPlanet), (const GLvoid*) offsetof(VertexPlanet, m_mx)); m_eyePt = mgPoint3(3500, 0, 0); m_eyeRotX = 0.0; m_eyeRotY = 90.0; m_eyeMatrix.rotateYDeg(m_eyeRotY); m_eyeMatrix.rotateXDeg(m_eyeRotX); m_specularColor = mgPoint3(0.4, 0.4, 0.4); m_lightColor = mgPoint3(0.6, 0.6, 0.6); m_lightAmbient = mgPoint3(0.2, 0.2, 0.2); m_matColor = mgPoint4(1, 1, 1, 1); }
//-------------------------------------------------------------- // constructor Planet::Planet( const mgOptionsFile& options) { // load the planet cubemap texture mgString xminName, xmaxName, yminName, ymaxName, zminName, zmaxName; options.getFileName("planet-xmin", options.m_sourceFileName, "", xminName); options.getFileName("planet-xmax", options.m_sourceFileName, "", xmaxName); options.getFileName("planet-ymin", options.m_sourceFileName, "", yminName); options.getFileName("planet-ymax", options.m_sourceFileName, "", ymaxName); options.getFileName("planet-zmin", options.m_sourceFileName, "", zminName); options.getFileName("planet-zmax", options.m_sourceFileName, "", zmaxName); m_surfaceTexture = loadCubeMap(xminName, xmaxName, yminName, ymaxName, zminName, zmaxName); // load the clouds cubemap texture options.getFileName("clouds-xmin", options.m_sourceFileName, "", xminName); options.getFileName("clouds-xmax", options.m_sourceFileName, "", xmaxName); options.getFileName("clouds-ymin", options.m_sourceFileName, "", yminName); options.getFileName("clouds-ymax", options.m_sourceFileName, "", ymaxName); options.getFileName("clouds-zmin", options.m_sourceFileName, "", zminName); options.getFileName("clouds-zmax", options.m_sourceFileName, "", zmaxName); m_cloudsTexture = loadCubeMap(xminName, xmaxName, yminName, ymaxName, zminName, zmaxName); compileShader(options); // create the vertex buffer glGenBuffers(1, &m_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer); m_eyePt = mgPoint3(3500, 0, 0); m_eyeRotX = 0.0; m_eyeRotY = 90.0; m_eyeMatrix.rotateYDeg(m_eyeRotY); m_eyeMatrix.rotateXDeg(m_eyeRotX); m_specularColor = mgPoint3(0.4, 0.4, 0.4); m_lightColor = mgPoint3(0.6, 0.6, 0.6); m_lightAmbient = mgPoint3(0.2, 0.2, 0.2); m_matColor = mgPoint4(1, 1, 1, 1); }
//-------------------------------------------------------------- // constructor Tower::Tower( const mgOptionsFile& options, BOOL lights) { m_lights = lights; m_shellIndexes = NULL; m_shellVertexes = NULL; m_officeIndexes = NULL; m_officeVertexes = NULL; m_glassIndexes = NULL; // load ball textures. must all be same size. mgString fileName; options.getFileName("tower-shell", options.m_sourceFileName, "tower-body.jpg", fileName); m_shellTexture = mgDisplay->loadTexture(fileName); options.getFileName("tower-glass", options.m_sourceFileName, "tower-glass.jpg", fileName); m_glassTexture = mgDisplay->loadTexture(fileName); mgStringArray fileList; options.getFileName("tower-wall", options.m_sourceFileName, "tower-wall.jpg", fileName); fileList.add(fileName); options.getFileName("tower-light", options.m_sourceFileName, "tower-light.jpg", fileName); fileList.add(fileName); options.getFileName("tower-floor", options.m_sourceFileName, "tower-floor.jpg", fileName); fileList.add(fileName); options.getFileName("tower-wall-dark", options.m_sourceFileName, "tower-wall.jpg", fileName); fileList.add(fileName); options.getFileName("tower-light-dark", options.m_sourceFileName, "tower-light.jpg", fileName); fileList.add(fileName); options.getFileName("tower-floor-dark", options.m_sourceFileName, "tower-floor.jpg", fileName); fileList.add(fileName); options.getFileName("tower-frame", options.m_sourceFileName, "tower-frame.jpg", fileName); fileList.add(fileName); m_officeTextures = mgDisplay->loadTextureArray(fileList); m_floorSpline.addVertex(mgPoint3(-30.0, 0.0, 0.0), mgPoint3(-30.0, 0.0+10, 0.0)); m_floorSpline.addVertex(mgPoint3( 0.0, 10.0, 0.0), mgPoint3( 0.0-30, 10.0, 0.0)); m_floorSpline.addVertex(mgPoint3( 30.0, 0.0, 0.0), mgPoint3( 30.0, 0.0+10, 0.0)); m_floorSpline.addVertex(mgPoint3( 0.0, -10.0, 0.0), mgPoint3( 0.0+30, -10.0, 0.0)); m_floorSpline.addVertex(mgPoint3(-30.0, 0.0, 0.0), mgPoint3(-30.0, 0.0-10, 0.0)); m_floorLen = m_floorSpline.getLength(); m_aptSpline.addVertex(mgPoint3( 0.0, 1.5, 0.0), mgPoint3( 0.0+0, 1.5, 0.0)); m_aptSpline.addVertex(mgPoint3( 3.0, 1.5, 0.0), mgPoint3( 3.0-2.5, 1.5, 0.0)); m_aptSpline.addVertex(mgPoint3( 5.0, 7.5, 0.0), mgPoint3( 5.0, 7.5-2.5, 0.0)); m_aptSpline.addVertex(mgPoint3( 5.0, 7.5, 0.0), mgPoint3( 5.0, 7.5-7.5, 0.0)); m_aptSpline.addVertex(mgPoint3( 35.0, 15.0, 0.0), mgPoint3( 35.0-30, 15.0, 0.0)); m_aptSpline.addVertex(mgPoint3( 65.0, 7.5, 0.0), mgPoint3( 65.0, 7.5+7.5, 0.0)); m_aptSpline.addVertex(mgPoint3( 65.0, 0.0, 0.0), mgPoint3( 65.0, 0.0, 0.0)); m_aptLen = m_aptSpline.getLength(); /* The spline class returns points based on a 'distance' which is a sum of all the segments that define the spline curve, not the actual length of the curve. To get regularly spaced points for windows, we search for the input distances that produce the correct x values (used for height here). The portions of the shape above and below the floors are then generated from the first and last distance point making the floors. */ m_floorDists = new double[APT_STEPS+1]; // find the floor heights for (int i = 0; i <= FLOORS*3; i++) { m_floorDists[15+i] = findSplineX(m_aptSpline, BOTTOM_FLOOR+i, 12, m_aptLen/2); } // fill in the rest of the tower double bottom = m_floorDists[15]; double top = m_floorDists[15+FLOORS*3]; for (int i = 0; i < 15; i++) { m_floorDists[i] = (bottom*i)/15; m_floorDists[16+FLOORS*3+i] = top + (m_aptLen - top)*(i+1)/15.0; } }
//-------------------------------------------------------------- // constructor SpeedUI::SpeedUI( const mgOptionsFile& options) { m_speed = 0.0; m_range = 0.0; m_units = UNITS_KM; m_landingState = LANDING_NONE; // create a rendering surface m_surface = mgDisplay->createOverlaySurface(); // create a style object, which creates controls m_style = new mgUglyStyle(m_surface); // create the top control that holds the ui m_top = new mgTopControl(m_surface, m_style); mgTableLayout* layout = new mgTableLayout(m_top); m_top->setLayout(layout); // set fonts and colors mgString fontName, colorName; options.getString("speedFont", "Courier-10", fontName); const mgFont* speedFont = m_surface->createFont(fontName); options.getString("speedColor", "white", colorName); mgColor speedColor(colorName); m_style->setAttr("speedHead", "font", speedFont); m_style->setAttr("speedHead", "textColor", speedColor); m_style->setAttr("speedLbL", "font", speedFont); m_style->setAttr("speedLbl", "textColor", speedColor); options.getString("rangeFont", "Courier-10", fontName); const mgFont* rangeFont = m_surface->createFont(fontName); options.getString("rangeColor", "white", colorName); mgColor rangeColor(colorName); m_style->setAttr("rangeHead", "font", rangeFont); m_style->setAttr("rangeHead", "textColor", rangeColor); m_style->setAttr("rangeLbL", "font", rangeFont); m_style->setAttr("rangeLbl", "textColor", rangeColor); // create the labels mgLabelControl* txt1 = m_style->createLabel(m_top, "speedHead", "Speed:"); m_speedLbl = m_style->createLabel(m_top, "speedLbl", ""); m_speedLbl->setMaxLabel("9,999,999 mph"); mgLabelControl* txt2 = m_style->createLabel(m_top, "rangeHead", "Range:"); m_rangeLbl = m_style->createLabel(m_top, "rangeLbl", ""); m_rangeLbl->setMaxLabel("9,999,999 mi"); // layout controls layout->addCell(txt1, mgTableAlignLeft, mgTableAlignTop, 1, 1); layout->addCell(m_speedLbl, mgTableAlignLeft, mgTableAlignTop, 1, 1); layout->newRow(); layout->addCell(txt2, mgTableAlignLeft, mgTableAlignTop, 1, 1); layout->addCell(m_rangeLbl, mgTableAlignLeft, mgTableAlignTop, 1, 1); layout->endRow(); // set the help pane to preferred size mgDimension size; m_top->preferredSize(size); m_top->surfaceResized(size.m_width, size.m_height); m_surface->setSurfaceSize(size.m_width, size.m_height); }