Ver código fonte

Merge pull request #18 from CrystalPointA4/feature/Menu

Feature/menu
Kenneth van Ewijk 9 anos atrás
pai
commit
7c4805d899
22 arquivos alterados com 537 adições e 74 exclusões
  1. 76 0
      Button.cpp
  2. 30 0
      Button.h
  3. 76 39
      CrystalPoint.cpp
  4. 7 0
      CrystalPoint.h
  5. 12 4
      CrystalPoint.vcxproj
  6. 35 8
      CrystalPoint.vcxproj.filters
  7. 22 0
      Cursor.cpp
  8. 6 2
      Cursor.h
  9. 2 13
      Interface.cpp
  10. 18 1
      Main.cpp
  11. 59 0
      Menu.cpp
  12. 20 0
      Menu.h
  13. 12 0
      MenuElement.cpp
  14. 17 0
      MenuElement.h
  15. 0 1
      Model.cpp
  16. 7 6
      Skybox.cpp
  17. 2 0
      Skybox.h
  18. 31 0
      Text.cpp
  19. 23 0
      Text.h
  20. 65 0
      Util.cpp
  21. 16 0
      Util.h
  22. 1 0
      World.cpp

+ 76 - 0
Button.cpp

@@ -0,0 +1,76 @@
+#include "Button.h"
+#include <string>
+#include "Util.h"
+#include "Vector.h"
+#include "Cursor.h"
+
+Button::Button(const std::string & text, Vec2f position, float width, float height) : Text(text,position)
+{
+	this->width = width;
+	this->height = height;
+	this->planePosition = position;
+
+	cursorOnButton = false;
+	alfa = 0.5f;
+	background = Vec3f(10, 10, 10);
+	//foreground = Vec3f(255, 255, 255);
+	this->setColor(Vec3f(255, 255, 255));
+
+	this->position.x += width / 2 - textWidth / 2;
+	this->position.y += height / 2 - textHeight / 2;
+}
+
+Button::~Button()
+{
+	/*if (action != nullptr)
+		delete action;*/
+}
+
+void Button::draw(void)
+{
+	
+	glColor4f(background.x/255.0f, background.y / 255.0f, background.z / 255.0f, alfa);
+
+	glBegin(GL_QUADS);
+	glVertex2f(planePosition.x, planePosition.y);
+	glVertex2f(planePosition.x, planePosition.y + height);
+	glVertex2f(planePosition.x + width, planePosition.y + height);
+	glVertex2f(planePosition.x + width, planePosition.y);
+	glEnd();	
+
+	/*glColor4f(foreground.x / 255.0f, foreground.y / 255.0f, foreground.z / 255.0f, 1.0f);
+	Util::glutBitmapString(text, position.x, position.y+height/2+14/2);*/
+	Text::draw();
+}
+
+void Button::update(int x, int y)
+{	
+	cursorOnButton =
+		(x > planePosition.x && x < planePosition.x + width) &&
+		y > planePosition.y && y < planePosition.y + height;
+
+
+	if (cursorOnButton)
+		alfa = 1.0f;
+	else
+		alfa = 0.5f;
+
+	if (cursorOnButton && Cursor::getInstance()->clicked)
+		if(action != nullptr)
+			action(this);
+}
+
+void Button::addAction(action_function action)
+{
+	this->action = action;
+}
+
+void Button::setForeground(Vec3f color)
+{
+	this->setColor(color);
+}
+
+void Button::setBackground(Vec3f color)
+{
+	background = color;
+}

+ 30 - 0
Button.h

@@ -0,0 +1,30 @@
+#pragma once
+#include "Text.h"
+
+
+
+class Button : public Text
+{
+private:	
+	typedef void(*action_function)(Button* b);
+	float width, height;	
+	Vec3f background;
+	Vec2f planePosition;
+	bool cursorOnButton;
+	float alfa;
+	action_function action = nullptr;
+public:
+	Button(const std::string &text, Vec2f position, float width, float height);
+	~Button();
+
+
+
+	void draw();
+	void update(int x, int y);
+
+	void addAction(action_function action);
+
+	void setForeground(Vec3f color);
+	void setBackground(Vec3f color);
+};
+

+ 76 - 39
CrystalPoint.cpp

@@ -5,23 +5,33 @@
 #include <cstring>
 #include "WorldHandler.h"
 #include "Player.h"
+#include "Cursor.h"
+#include "Menu.h"
+#include "Text.h"
+#include "Vector.h"
+#include "Button.h"
 
 int CrystalPoint::width = 0;
 int CrystalPoint::height = 0;
 
 SoundSystem CrystalPoint::sound_system;
+bool state = false;
+
+
 
 void CrystalPoint::init()
 {
 	player = Player::getInstance();
 	worldhandler = WorldHandler::getInstance();
-	//cursor = Cursor::getInstance();
+	cursor = Cursor::getInstance();
+
+	menu = new Menu();
+	buildMenu();
 
 	lastFrameTime = 0;
+	state = true;
 
 	glClearColor(0.7f, 0.7f, 1.0f, 1.0f);
-
-	mousePosition = Vec2f(width / 2, height / 2);
 }
 
 
@@ -39,9 +49,10 @@ void CrystalPoint::draw()
 	glMatrixMode(GL_MODELVIEW);
 	glLoadIdentity();
 
+	
 	worldhandler->draw();
-
-	//cursor->draw();
+	if(!state)
+		menu->draw();
 
 	glutSwapBuffers();
 }
@@ -53,41 +64,45 @@ void CrystalPoint::update()
 	float deltaTime = frameTime - lastFrameTime;
 	lastFrameTime = frameTime;
 
-	if (keyboardState.special[GLUT_KEY_LEFT] && !prevKeyboardState.special[GLUT_KEY_LEFT])
-		worldhandler->PreviousWorld();
-	if (keyboardState.special[GLUT_KEY_RIGHT] && !prevKeyboardState.special[GLUT_KEY_RIGHT])
-		worldhandler->NextWorld();
-	if (keyboardState.keys[27])
-		exit(0);
-
-	Player* player = Player::getInstance();
-
-	player->rotation.y += mouseOffset.x / 10.0f;
-	player->rotation.x += mouseOffset.y / 10.0f;
-	if (player->rotation.x > 90)
-		player->rotation.x = 90;
-	if (player->rotation.x < -90)
-		player->rotation.x = -90;
-
-	float speed = 10;
+	if (state)
+	{
+		if (keyboardState.special[GLUT_KEY_LEFT] && !prevKeyboardState.special[GLUT_KEY_LEFT])
+			worldhandler->PreviousWorld();
+		if (keyboardState.special[GLUT_KEY_RIGHT] && !prevKeyboardState.special[GLUT_KEY_RIGHT])
+			worldhandler->NextWorld();
+		if (keyboardState.keys[27])
+			state = false;
+
+		Player* player = Player::getInstance();
+
+		player->rotation.y += mouseOffset.x / 10.0f;
+		player->rotation.x += mouseOffset.y / 10.0f;
+		if (player->rotation.x > 90)
+			player->rotation.x = 90;
+		if (player->rotation.x < -90)
+			player->rotation.x = -90;
+
+		float speed = 10;
+
+		Vec3f oldPosition = player->position;
+		if (keyboardState.keys['a']) player->setPosition(0, deltaTime*speed, false);
+		if (keyboardState.keys['d']) player->setPosition(180, deltaTime*speed, false);
+		if (keyboardState.keys['w']) player->setPosition(90, deltaTime*speed, false);
+		if (keyboardState.keys['s']) player->setPosition(270, deltaTime*speed, false);
+		if (keyboardState.keys['q']) player->setPosition(1, deltaTime*speed, true);
+		if (keyboardState.keys['e']) player->setPosition(-1, deltaTime*speed, true);
+
+		if (!worldhandler->isPlayerPositionValid())
+			player->position = oldPosition;
+		player->position.y = worldhandler->getHeight(player->position.x, player->position.z) + 1.7f;
+		worldhandler->update(deltaTime);
+	}	
+	else
+	{
+		menu->update();
+		cursor->update(cursor->mousePosition + mouseOffset);
+	}
 
-	Vec3f oldPosition = player->position;
-	if (keyboardState.keys['a']) player->setPosition(0, deltaTime*speed, false);
-	if (keyboardState.keys['d']) player->setPosition(180, deltaTime*speed, false);
-	if (keyboardState.keys['w']) player->setPosition(90, deltaTime*speed, false);
-	if (keyboardState.keys['s']) player->setPosition(270, deltaTime*speed, false);
-	if (keyboardState.keys['q']) player->setPosition(1, deltaTime*speed, true);
-	if (keyboardState.keys['e']) player->setPosition(-1, deltaTime*speed, true);
-
-	if (!worldhandler->isPlayerPositionValid())
-		player->position = oldPosition;
-
-	player->position.y = worldhandler->getHeight(player->position.x, player->position.z) + 1.7f;
-
-	worldhandler->update(deltaTime);
-
-	mousePosition = mousePosition + mouseOffset;
-	//cursor->update(mousePosition);
 
 	mouseOffset = Vec2f(0, 0);
 	prevKeyboardState = keyboardState;
@@ -96,6 +111,28 @@ void CrystalPoint::update()
 	sound_system.SetListener(player->position, Vec3f(), Vec3f());
 }
 
+void CrystalPoint::buildMenu()
+{
+	Button* start = new Button("Resume", Vec2f(1920 / 2 - 50, 1080 / 2 - 30), 100, 50);
+	auto toWorld = [](Button* b)
+	{
+		state = true;
+	};
+	start->addAction(toWorld);
+	menu->AddMenuElement(start);
+
+
+	Button* test = new Button("Exit", Vec2f(1920 / 2 - 50, 1080 / 2 + 30), 100, 50);
+	test->addAction([](Button* b)
+	{
+		exit(0);
+	});
+	menu->AddMenuElement(test);
+	Text* t = new Text("Pause", Vec2f(1920 / 2 - Util::glutTextWidth("Pause") / 2, 1080 / 2 - 75));
+	t->setColor(Vec3f(255, 255, 0));
+	menu->AddMenuElement(t);
+}
+
 
 
 KeyboardState::KeyboardState()

+ 7 - 0
CrystalPoint.h

@@ -3,6 +3,8 @@
 class WorldHandler;
 class SoundSystem;
 class Player;
+class Cursor;
+class Menu;
 #include "Vector.h"
 #include "SoundSystem.h"
 
@@ -25,6 +27,9 @@ public:
 
 	WorldHandler* worldhandler;
 	Player* player;
+	Cursor* cursor;
+
+	Menu* menu;
 
 	static int width, height;
 	KeyboardState keyboardState;
@@ -36,7 +41,9 @@ public:
 	float lastFrameTime;
 
 	static SoundSystem& GetSoundSystem() { return sound_system; }
+	
 
 private:
 	static SoundSystem sound_system;
+	void buildMenu();
 };

+ 12 - 4
CrystalPoint.vcxproj

@@ -154,6 +154,7 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="Button.cpp" />
     <ClCompile Include="Crystal.cpp" />
     <ClCompile Include="CrystalPoint.cpp" />
     <ClCompile Include="Cursor.cpp" />
@@ -164,18 +165,23 @@
     <ClCompile Include="json.cpp" />
     <ClCompile Include="LevelObject.cpp" />
     <ClCompile Include="Main.cpp" />
+    <ClCompile Include="Menu.cpp" />
+    <ClCompile Include="MenuElement.cpp" />
     <ClCompile Include="Model.cpp" />
     <ClCompile Include="Portal.cpp" />
     <ClCompile Include="Sound.cpp" />
     <ClCompile Include="SoundSystem.cpp" />
     <ClCompile Include="Player.cpp" />
     <ClCompile Include="Skybox.cpp" />
+    <ClCompile Include="Text.cpp" />
+    <ClCompile Include="Util.cpp" />
     <ClCompile Include="Vector.cpp" />
     <ClCompile Include="Vertex.cpp" />
     <ClCompile Include="World.cpp" />
     <ClCompile Include="WorldHandler.cpp" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="Button.h" />
     <ClInclude Include="Crystal.h" />
     <ClInclude Include="CrystalPoint.h" />
     <ClInclude Include="Cursor.h" />
@@ -186,6 +192,8 @@
     <ClInclude Include="json.h" />
     <ClInclude Include="LevelObject.h" />
     <ClInclude Include="Main.h" />
+    <ClInclude Include="Menu.h" />
+    <ClInclude Include="MenuElement.h" />
     <ClInclude Include="Model.h" />
     <ClInclude Include="Portal.h" />
     <ClInclude Include="Sound.h" />
@@ -193,6 +201,8 @@
     <ClInclude Include="Player.h" />
     <ClInclude Include="Skybox.h" />
     <ClInclude Include="stb_image.h" />
+    <ClInclude Include="Text.h" />
+    <ClInclude Include="Util.h" />
     <ClInclude Include="vector.h" />
     <ClInclude Include="Vertex.h" />
     <ClInclude Include="World.h" />
@@ -201,14 +211,12 @@
   <ItemGroup>
     <None Include="worlds\fire.json" />
     <None Include="worlds\ice.json" />
-    <None Include="worlds\rock.json" />
     <None Include="worlds\small.json" />
     <None Include="worlds\worlds.json" />
   </ItemGroup>
   <ItemGroup>
-    <Media Include="WAVE\enemy.wav" />
-    <Media Include="WAVE\test1.wav" />
-    <Media Include="WAVE\test2.wav" />
+    <Media Include="WAVE\bond.wav" />
+    <Media Include="WAVE\Sound.wav" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 35 - 8
CrystalPoint.vcxproj.filters

@@ -22,6 +22,9 @@
     <Filter Include="Source Files\json">
       <UniqueIdentifier>{9c655946-3f99-44ea-bc97-2817656954e0}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Source Files\Menu">
+      <UniqueIdentifier>{e7a88896-78e1-4544-bfc8-cfd55323728e}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Main.cpp">
@@ -87,6 +90,21 @@
     <ClCompile Include="Portal.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Button.cpp">
+      <Filter>Source Files\Menu</Filter>
+    </ClCompile>
+    <ClCompile Include="Menu.cpp">
+      <Filter>Source Files\Menu</Filter>
+    </ClCompile>
+    <ClCompile Include="MenuElement.cpp">
+      <Filter>Source Files\Menu</Filter>
+    </ClCompile>
+    <ClCompile Include="Text.cpp">
+      <Filter>Source Files\Menu</Filter>
+    </ClCompile>
+    <ClCompile Include="Util.cpp">
+      <Filter>Source Files\Menu</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="World.h">
@@ -152,6 +170,21 @@
     <ClInclude Include="Portal.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Text.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Util.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="MenuElement.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Menu.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Button.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="worlds\worlds.json">
@@ -166,18 +199,12 @@
     <None Include="worlds\small.json">
       <Filter>Source Files\json</Filter>
     </None>
-    <None Include="worlds\rock.json">
-      <Filter>Source Files\json</Filter>
-    </None>
   </ItemGroup>
   <ItemGroup>
-    <Media Include="WAVE\test1.wav">
-      <Filter>Resource Files</Filter>
-    </Media>
-    <Media Include="WAVE\test2.wav">
+    <Media Include="WAVE\Sound.wav">
       <Filter>Resource Files</Filter>
     </Media>
-    <Media Include="WAVE\enemy.wav">
+    <Media Include="WAVE\bond.wav">
       <Filter>Resource Files</Filter>
     </Media>
   </ItemGroup>

+ 22 - 0
Cursor.cpp

@@ -8,10 +8,13 @@ Cursor* Cursor::instance = NULL;
 Cursor::Cursor()
 {
 	enabled = false;
+	mousePosition = Vec2f(CrystalPoint::width / 2, CrystalPoint::height / 2);
+	clicked = false;
 }
 
 Cursor::~Cursor()
 {
+	
 }
 
 Cursor* Cursor::getInstance(void)
@@ -54,5 +57,24 @@ void Cursor::draw(void)
 
 void Cursor::update(Vec2f newPosition)
 {
+	if (newPosition.x < 0)
+		newPosition.x = 0;
+
+	if (newPosition.y < 0)
+		newPosition.y = 0;
+
+	if (newPosition.x > CrystalPoint::width)
+		newPosition.x = CrystalPoint::width;
+
+	if (newPosition.y > CrystalPoint::height)
+		newPosition.y = CrystalPoint::height;
+
 	mousePosition = newPosition;
+
+	if (clicked)
+		clicked = !clicked;
+	if (state != prev)
+		if(state == GLUT_UP)
+			clicked = true;
+	prev = state;
 }

+ 6 - 2
Cursor.h

@@ -8,9 +8,9 @@ private:
 
 	static Cursor* instance;
 	bool enabled;
-	Vec2f mousePosition;
-public:
 	
+public:
+	Vec2f mousePosition;
 	~Cursor();
 
 	static Cursor* getInstance(void);
@@ -18,6 +18,10 @@ public:
 	void enable(bool enable);
 	bool isEnabled(void);
 
+	bool clicked;
+	int state, prev;
+
+
 	void draw(void);
 	void update(Vec2f newPosition);
 };

+ 2 - 13
Interface.cpp

@@ -5,9 +5,7 @@
 #include <string>
 
 #include "Player.h"
-
-//Prototype
-void glutBitmapString(std::string str, int x, int y);
+#include "Util.h"
 
 Interface::Interface()
 {
@@ -87,7 +85,7 @@ void Interface::draw()
 
 	//Text: level
 	glColor4f(1.0f, 1.0f, 0.1f, 1.0);
-	glutBitmapString("Level: " + std::to_string(player->level), 490, 900);
+	Util::glutBitmapString("Level: " + std::to_string(player->level), 490, 900);
 
 	for (int i = 0; i < maxCrystals; i++)
 	{
@@ -118,13 +116,4 @@ void Interface::draw()
 void Interface::update(float deltaTime)
 {
 
-}
-
-void glutBitmapString(std::string str, int x, int y)
-{
-	glRasterPos2f(x, y);
-	for (int i = 0; i < str.size(); i++)
-	{
-		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, str[i]);
-	}
 }

+ 18 - 1
Main.cpp

@@ -4,6 +4,11 @@
 #include <stdio.h>
 #include "Vector.h"
 
+#define STB_IMAGE_IMPLEMENTATION
+#include "stb_image.h"
+
+#include "Cursor.h"
+
 void configureOpenGL(void);
 
 CrystalPoint* app;
@@ -50,6 +55,17 @@ int main(int argc, char* argv[])
 	glutPassiveMotionFunc(mousemotion);
 	glutMotionFunc(mousemotion);
 
+	auto mouseclick = [](int button, int state,
+		int x, int y)
+	{
+		if (button == GLUT_LEFT_BUTTON)
+			Cursor::getInstance()->state = state;
+
+			//std::cout << "Left button is down" << std::endl;
+	};
+
+	glutMouseFunc(mouseclick);
+
 	CrystalPoint::height = GLUT_WINDOW_HEIGHT;
 	CrystalPoint::width = GLUT_WINDOW_WIDTH;
 
@@ -66,7 +82,8 @@ void configureOpenGL()
 	glutInitWindowSize(800, 600);
 	//glutInitWindowPosition(glutGet(GLUT_WINDOW_WIDTH) / 2 - 800/2, glutGet(GLUT_WINDOW_HEIGHT) / 2 - 600/2);
 	glutCreateWindow("Crystal Point");	
-	//glutFullScreen();
+	glutFullScreen();
+
 
 	//Depth testing
 	glEnable(GL_DEPTH_TEST);

+ 59 - 0
Menu.cpp

@@ -0,0 +1,59 @@
+#include <GL\freeglut.h>
+#include "Menu.h"
+#include "CrystalPoint.h"
+
+Menu::Menu()
+{
+	cursor = Cursor::getInstance();
+}
+
+
+Menu::~Menu()
+{
+}
+
+void Menu::draw(void)
+{
+	//Switch view to Ortho
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrtho(0, CrystalPoint::width, CrystalPoint::height, 0, -10, 10);
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+
+	glDisable(GL_LIGHTING);
+	glDisable(GL_DEPTH_TEST);
+	glDisable(GL_TEXTURE_2D);
+
+	glColor4f(60/255.0f, 60/255.0f, 60/255.0f, 0.8f);
+	glBegin(GL_QUADS);
+	glVertex2f(0,0);
+	glVertex2f(0, CrystalPoint::height);
+	glVertex2f(CrystalPoint::width, CrystalPoint::height);
+	glVertex2f(CrystalPoint::width, 0);
+	glEnd();
+
+
+	for (MenuElement* e : elements)
+	{
+		e->draw();
+	}
+
+	cursor->draw();
+
+	glEnable(GL_LIGHTING);
+	glEnable(GL_DEPTH_TEST);
+}
+
+void Menu::update()
+{
+	for (MenuElement* e : elements)
+	{
+		e->update(cursor->mousePosition.x, cursor->mousePosition.y);
+	}
+}
+
+void Menu::AddMenuElement(MenuElement * e)
+{
+	elements.push_back(e);
+}

+ 20 - 0
Menu.h

@@ -0,0 +1,20 @@
+#pragma once
+#include <vector>
+#include "MenuElement.h"
+#include "Cursor.h"
+
+class Menu
+{
+private:
+	std::vector<MenuElement*> elements;
+	Cursor* cursor;
+public:
+	Menu();
+	~Menu();
+
+	void draw(void);
+	void update(void);
+
+	void AddMenuElement(MenuElement* e);
+};
+

+ 12 - 0
MenuElement.cpp

@@ -0,0 +1,12 @@
+#include "MenuElement.h"
+
+MenuElement::MenuElement(Vec2f position)
+{
+	hover = false;
+	this->position = position;
+}
+
+
+MenuElement::~MenuElement()
+{
+}

+ 17 - 0
MenuElement.h

@@ -0,0 +1,17 @@
+#pragma once
+#include "Vector.h"
+#include <string>
+
+class MenuElement
+{
+protected:
+	bool hover;
+	Vec2f position;
+public:
+	MenuElement(Vec2f position);
+	~MenuElement();
+
+	virtual void draw(void) {};
+	virtual void update(int x, int y) {};
+};
+

+ 0 - 1
Model.cpp

@@ -1,6 +1,5 @@
 #include "Model.h"
 
-#define STB_IMAGE_IMPLEMENTATION
 #include "stb_image.h"
 
 #include <iostream>

+ 7 - 6
Skybox.cpp

@@ -1,6 +1,7 @@
 #include "cmath"
 #include <GL/freeglut.h>
 
+#include "Util.h"
 #include "stb_image.h"
 #include "Skybox.h"
 #include <string>
@@ -25,12 +26,12 @@ Skybox::~Skybox()
 
 void Skybox::init() 
 {
-	skybox[SKY_LEFT] = loadTexture(folder + "left.png");
-	skybox[SKY_BACK] = loadTexture(folder + "back.png");
-	skybox[SKY_RIGHT] = loadTexture(folder + "right.png");
-	skybox[SKY_FRONT] = loadTexture(folder + "front.png");
-	skybox[SKY_TOP] = loadTexture(folder + "top.png");
-	skybox[SKY_BOTTOM] = loadTexture(folder + "bottom.png");
+	skybox[SKY_LEFT] = Util::loadTexture(folder + "left.png");
+	skybox[SKY_BACK] = Util::loadTexture(folder + "back.png");
+	skybox[SKY_RIGHT] = Util::loadTexture(folder + "right.png");
+	skybox[SKY_FRONT] = Util::loadTexture(folder + "front.png");
+	skybox[SKY_TOP] = Util::loadTexture(folder + "top.png");
+	skybox[SKY_BOTTOM] = Util::loadTexture(folder + "bottom.png");
 }
 
 void Skybox::draw()

+ 2 - 0
Skybox.h

@@ -14,6 +14,8 @@ public:
 
 	void init();
 	void draw();
+
 	void update(float deltaTime, int, int);
 	GLuint loadTexture(const std::string &fileName);
+
 };

+ 31 - 0
Text.cpp

@@ -0,0 +1,31 @@
+#include "Text.h"
+
+
+Text::Text(const std::string &text, Vec2f position) : MenuElement(position)
+{
+	this->text = text;
+	color = Vec3f(50, 150, 150);
+	textHeight = 14;
+	textWidth = Util::glutTextWidth(text);
+}
+
+
+Text::~Text()
+{
+}
+
+void Text::draw()
+{
+	glColor4f(color.x/255.0f, color.y/255.0f, color.z/255.0f, 1.0f);
+	Util::glutBitmapString(text, position.x-1, position.y+textHeight);
+}
+
+void Text::update(int x, int y)
+{
+	//Do nothing
+}
+
+void Text::setColor(Vec3f color)
+{
+	this->color = color;
+}

+ 23 - 0
Text.h

@@ -0,0 +1,23 @@
+#pragma once
+#include "MenuElement.h"
+#include "Vector.h"
+#include "Util.h"
+
+class Text : public MenuElement
+{
+private:
+	std::string text;
+	Vec3f color;	
+protected:
+	int textWidth;
+	int textHeight;
+public:
+	Text(const std::string &text, Vec2f position);
+	~Text();
+
+	virtual void draw();
+	virtual void update(int x, int y);
+
+	void setColor(Vec3f color);
+};
+

+ 65 - 0
Util.cpp

@@ -0,0 +1,65 @@
+#include "Util.h"
+#include "stb_image.h"
+
+Util::Util()
+{
+	
+}
+
+
+Util::~Util()
+{
+}
+
+GLuint Util::loadTexture(const std::string &filename)
+{
+	int width, height, bpp;
+
+	stbi_set_flip_vertically_on_load(true);
+	unsigned char* imgData = stbi_load(filename.c_str(), &width, &height, &bpp, 4);
+	GLuint num;
+	glGenTextures(1, &num);
+	glBindTexture(GL_TEXTURE_2D, num);
+
+	glTexImage2D(GL_TEXTURE_2D,
+		0,		//level
+		GL_RGBA,		//internal format
+		width,		//width
+		height,		//height
+		0,		//border
+		GL_RGBA,		//data format
+		GL_UNSIGNED_BYTE,	//data type
+		imgData);		//data
+	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+	stbi_image_free(imgData);
+	return num;
+}
+
+void Util::glutBitmapString(std::string str, int x, int y)
+{
+	glRasterPos2f(x, y);
+	for (int i = 0; i < str.size(); i++)
+	{
+		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, str[i]);
+	}
+}
+
+int Util::glutTextWidth(const std::string str)
+{
+	int total = 0;
+	for (int i = 0; i < str.size(); i++)
+	{
+		total += glutBitmapWidth(GLUT_BITMAP_HELVETICA_18, str[i]);
+	}
+	return total;
+}
+
+//int Util::glutTextHeight()
+//{
+//	return glutBitmapHeight(GLUT_BITMAP_HELVETICA_18);
+//}
+

+ 16 - 0
Util.h

@@ -0,0 +1,16 @@
+#pragma once
+#include <string>
+#include <GL\freeglut.h>
+
+class Util
+{
+private:
+	Util();
+	~Util();	
+public:
+	static GLuint loadTexture(const std::string &filename);
+	static void glutBitmapString(std::string str, int x, int y);
+	static int glutTextWidth(const std::string str);
+	//static int glutTextHeight();
+};
+

+ 1 - 0
World.cpp

@@ -214,6 +214,7 @@ World::~World()
 	music->Stop();
 	delete music;
 	delete skybox;
+	delete portal;
 }
 
 std::pair<std::string, bool> World::getObjectFromValue(int val)