hx3d  1
2D/3D Simple Game Framework
sdl2_application.cpp
1 /*
2  SDL2 Application.
3  Copyright (C) 2015 Denis BOURGE
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
21 #include "hx3d/window/sdl2/sdl2_application.hpp"
22 #include "hx3d/window/sdl2/sdl2_events.hpp"
23 
24 #include "hx3d/utils/log.hpp"
25 #include "hx3d/utils/assets.hpp"
26 
27 #include "hx3d/graphics/texture.hpp"
28 #include "hx3d/graphics/framebuffer.hpp"
29 #include "hx3d/graphics/shader.hpp"
30 #include "hx3d/graphics/font.hpp"
31 
32 #include "hx3d/core/core.hpp"
33 #include "hx3d/window/game.hpp"
34 #include "hx3d/window/events.hpp"
35 
36 #include "hx3d/audio/audio.hpp"
37 
38 #include "hx3d/math/number_utils.hpp"
39 
40 #include "hx3d/net/net.hpp"
41 
42 #include <ctime>
43 
44 using namespace hx3d::graphics;
45 
46 namespace hx3d {
47 namespace window {
48 
49 SDL2Application::SDL2Application(ApplicationConfig config):
50  Application(config)
51 {
52  create(_width, _height, _title);
53 }
54 
55 SDL2Application::~SDL2Application() {
56 
58  _game.reset();
59 
60  SDL_GL_DeleteContext(_context);
61 
62  if (_window) {
63  SDL_DestroyWindow(_window);
64  }
65 
66  SDL_Quit();
67 
68  #if defined(__ANDROID__)
69  exit(0);
70  #endif
71 
72  /* Stop the static classes */
73  //.........
74 }
75 
76 void SDL2Application::start(const Ptr<Game>& game) {
77  _game = game;
78 
79  Core::setGame(_game.get());
80  _game->create();
81 
82  display();
83 }
84 
85 void SDL2Application::create(int width, int height, std::string title) {
86 
87  srand(time(0));
88 
89  if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0) {
90  Log.Error("SDL Init Error: %s", SDL_GetError());
91  SDL_Quit();
92 
93  exit(1);
94  }
95 
96  std::string hello =
97  "\n\
98  *++++++! +\n\
99  ++| */ + +\n\
100  * * * + /+\n\
101  * ***** *+/++++/+* /++++* +++++++!*\n\
102  **/ !* ++ + / |\n\
103  +/+ +/+ +/++++/+ */ + * +\n\
104  +/+ +/+ +/+ +/+ *+++++/ *++++++/\n";
105 
106  Log.Info(hello);
107 
108  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
109  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
110  SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
111 
112 #ifdef DESKTOP_OPENGL
113  auto window_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | (_fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
114  _window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, window_flags);
115 
116  _width = width;
117  _height = height;
118 
119  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
120  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0);
121 #else
122  _window = SDL_CreateWindow("", 0, 0, 0, 0, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
123 
124  SDL_GetWindowSize(_window, &_width, &_height);
125 
126  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
127  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
128  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
129 #endif
130 
131  _context = SDL_GL_CreateContext(_window);
132  if (_context == 0) {
133  Log.Error("OpenGL Context Error: %s", SDL_GetError());
134  SDL_Quit();
135  }
136 
137  SDL_GL_MakeCurrent(_window, _context);
138 
139  #ifdef DESKTOP_OPENGL
140  GLenum init = glewInit();
141  if (init != GLEW_OK) {
142  Log.Error("GLEW error: %s", glewGetErrorString(init));
143  exit(1);
144  }
145 #endif
146 
147  Log.Info("Screen: %d x %d", _width, _height);
148 
149  glViewport(0, 0, _width, _height);
150 
151  glEnable(GL_DEPTH_TEST);
152 
153  glEnable(GL_BLEND);
154  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
155 
156  // Stencil bitplanes
157  int bitplanes = 0;
158  glGetIntegerv(GL_STENCIL_BITS, &bitplanes);
159 
160  Log.Info("Stencil bitplanes: %d", bitplanes);
161 
164  Core::initialize(this, new SDL2EventManager());
165  Framebuffer::fetchDefaultFramebuffer();
166  Texture::generateBlankTexture();
167 
168  Core::Assets()->create<Shader>("base", "shaders/base");
169  Core::Assets()->create<Shader>("text", "shaders/text");
170  Core::Assets()->create<Font>("default", "fonts/default.otf", 14);
171 
172  /**********************/
173 }
174 
175 void SDL2Application::display() {
176 
177  Uint32 frameTime = 0;
178  Uint32 frameStart;
179  Uint32 frameEnd;
180  float deltaTime = 0.f;
181 
182  _running = true;
183  while (_running) {
184 
185  frameStart = SDL_GetTicks();
186 
187  update(deltaTime);
188  render();
189 
190  frameEnd = SDL_GetTicks();
191  frameTime = frameEnd - frameStart;
192  deltaTime = frameTime / 1000.f;
193 
194  _currentFPS = 1.f / deltaTime;
195  _elapsedTime = math::mclamp(_elapsedTime + deltaTime, 0.f, 3600.f);
196  }
197 }
198 void SDL2Application::update(float delta) {
199 
200  Core::Events()->poll();
201 
202  if (Core::Events()->isWindowState(WindowEvent::Type::Closed)) {
203  _game->stop();
204  } else {
205  _game->update(delta);
206  }
207 
208  if (!_game->isRunning())
209  _running = false;
210 }
211 
212 void SDL2Application::render() {
213 
214  _game->render();
215 
216  SDL_GL_SwapWindow(_window);
217 
218  if (!_game->isRunning())
219  _running = false;
220 }
221 
222 } /* window */
223 } /* hx3d */
SDL2 event manager implementation.
Definition: sdl2_events.hpp:32
static void setGame(window::Game *game)
Set the game.
Definition: core.cpp:110
float mclamp(float value, float min, float max)
Modulo clamp.
Application configuration.
static void shutdown()
Shutdown the core system.
Definition: core.cpp:114
2D and 3D graphics components.
Definition: animation.hpp:28
Application management.
Definition: application.hpp:42
static AssetManager * Assets()
Get the asset manager.
Definition: core.cpp:86
hx3d framework namespace
Definition: audio.hpp:26
bool _fullscreen
Is the application in fullscreen ?
void create(std::string name, Args...args)
Create an asset with arguments.
Definition: assets.hpp:23
int _width
Application width.
Font management.
Definition: font.hpp:39
bool _running
Is the application running ?
Ptr< Game > _game
Game pointer.
Definition: application.hpp:99
void Error(const std::string fmt,...)
Write an error message.
Definition: log.cpp:72
virtual void poll()=0
Poll the event queue.
static hx3d::LogImpl Log
Current log implementation.
Definition: log.hpp:91
int _height
Application height.
float _elapsedTime
Elapsed time since the beginning.
virtual void start(const Ptr< Game > &game) override
Start the window.
Shader definition class.
Definition: shader.hpp:42
std::string _title
Application title.
static void initialize(window::Application *app, window::EventManager *events)
Initialize the core system.
Definition: core.cpp:104
float _currentFPS
Current FPS.
static window::EventManager * Events()
Get the event manager.
Definition: core.cpp:90
std::shared_ptr< T > Ptr
Quick-typing shared ptr.
Definition: ptr.hpp:34
void Info(const std::string fmt,...)
Write an info message.
Definition: log.cpp:58