From ee0c9fc3c0f6a5c91981cd7c72712ee51dbe39c6 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 8 Jul 2009 14:13:50 +0100 Subject: [PATCH] Add skybox with textures --- include/ISkyBox.hpp | 34 +++++++++++ src/Game.cpp | 6 ++ src/SkyBox.cpp | 136 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 include/ISkyBox.hpp create mode 100644 src/SkyBox.cpp diff --git a/include/ISkyBox.hpp b/include/ISkyBox.hpp new file mode 100644 index 0000000..a9144b3 --- /dev/null +++ b/include/ISkyBox.hpp @@ -0,0 +1,34 @@ +// +// Copyright (C) 2009 Nick Gasson +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef INC_ISKYBOX_HPP +#define INC_ISKYBOX_HPP + +#include "Platform.hpp" + +// Simple textured skybox +struct ISkyBox { + virtual ~ISkyBox() {} + + virtual void apply(float anAngle=0.0f) const = 0; +}; + +typedef shared_ptr ISkyBoxPtr; + +ISkyBoxPtr makeSkyBox(const string& aBaseName); + +#endif diff --git a/src/Game.cpp b/src/Game.cpp index bf1003c..725a30e 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -26,6 +26,7 @@ #include "GameScreens.hpp" #include "IBillboard.hpp" #include "IterateTrack.hpp" +#include "ISkyBox.hpp" #include @@ -56,6 +57,7 @@ private: IMapPtr myMap; ITrainPtr myTrain; ILightPtr mySun; + ISkyBoxPtr mySkyBox; // Station the train is either approaching or stopped at IStationPtr myActiveStation; @@ -80,6 +82,7 @@ Game::Game(IMapPtr aMap) { myTrain = makeTrain(myMap); mySun = makeSunLight(); + mySkyBox = makeSkyBox("skybox"); myMap->setGrid(false); @@ -123,6 +126,9 @@ Game::~Game() void Game::display(IGraphicsPtr aContext) const { + // Render the skybox before everything else + mySkyBox->apply(myHorizAngle); + Vector trainPos = myTrain->front(); // Two angles give unique position on surface of a sphere diff --git a/src/SkyBox.cpp b/src/SkyBox.cpp new file mode 100644 index 0000000..c3cc38c --- /dev/null +++ b/src/SkyBox.cpp @@ -0,0 +1,136 @@ +// +// Copyright (C) 2009 Nick Gasson +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include "ISkyBox.hpp" +#include "ITexture.hpp" +#include "Maths.hpp" + +#include + +// Concrete implementation of skyboxes +class SkyBox : public ISkyBox { +public: + SkyBox(const string& aBaseName); + + // ISkyBox interface + void apply(float anAngle) const; + +private: + void loadSkyTexture(int anIndex, const string& aSuffix); + + ITexturePtr myTextures[6]; + const string myBaseName; +}; + +// The base name is used to generate the file names of all six +// textures +SkyBox::SkyBox(const string& aBaseName) + : myBaseName(aBaseName) +{ + loadSkyTexture(0, "bottom"); + loadSkyTexture(1, "top"); + loadSkyTexture(2, "front"); + loadSkyTexture(3, "front"); + loadSkyTexture(4, "front"); + loadSkyTexture(5, "front"); +} + +void SkyBox::loadSkyTexture(int anIndex, const string& aSuffix) +{ + myTextures[anIndex] = + loadTexture("data/images/" + myBaseName + "_" + aSuffix + ".png"); +} + +void SkyBox::apply(float anAngle) const +{ + glColor3f(1.0f, 1.0f, 1.0f); + + const float r = 5.0f; + + glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING); + + glDepthMask(0); + + glPushMatrix(); + glLoadIdentity(); + + glRotatef(radToDeg(anAngle), 0.0f, 1.0f, 0.0f); + + // Bottom + myTextures[0]->bind(); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-r, -r, -r); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-r, -r, r); + glTexCoord2f(1.0f, 0.0f); glVertex3f(r, -r, r); + glTexCoord2f(1.0f, 1.0f); glVertex3f(r, -r, -r); + glEnd(); + + // Top + myTextures[1]->bind(); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-r, r, -r); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-r, r, r); + glTexCoord2f(1.0f, 0.0f); glVertex3f(r, r, r); + glTexCoord2f(1.0f, 1.0f); glVertex3f(r, r, -r); + glEnd(); + + // Front + myTextures[2]->bind(); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-r, -r, -r); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-r, r, -r); + glTexCoord2f(1.0f, 0.0f); glVertex3f(r, r, -r); + glTexCoord2f(1.0f, 1.0f); glVertex3f(r, -r, -r); + glEnd(); + + // Back + myTextures[3]->bind(); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-r, -r, r); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-r, r, r); + glTexCoord2f(1.0f, 0.0f); glVertex3f(r, r, r); + glTexCoord2f(1.0f, 1.0f); glVertex3f(r, -r, r); + glEnd(); + + // Left + myTextures[4]->bind(); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-r, -r, -r); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-r, r, -r); + glTexCoord2f(1.0f, 0.0f); glVertex3f(-r, r, r); + glTexCoord2f(1.0f, 1.0f); glVertex3f(-r, -r, r); + glEnd(); + + // Right + myTextures[5]->bind(); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 1.0f); glVertex3f(r, -r, -r); + glTexCoord2f(0.0f, 0.0f); glVertex3f(r, r, -r); + glTexCoord2f(1.0f, 0.0f); glVertex3f(r, r, r); + glTexCoord2f(1.0f, 1.0f); glVertex3f(r, -r, r); + glEnd(); + + glPopMatrix(); + glPopAttrib(); +} + +ISkyBoxPtr makeSkyBox(const string& aBaseName) +{ + return ISkyBoxPtr(new SkyBox(aBaseName)); +} -- 2.39.2