Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/graphics_engine.cc @ 4833

Last change on this file since 4833 was 4833, checked in by bensch, 19 years ago

orxonox/trunk: fight against the mighty segfault

File size: 12.2 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
17
18#include "graphics_engine.h"
19#include "resource_manager.h"
20#include "event_handler.h"
21
22#include "debug.h"
23#include "text_engine.h"
24
25#include "ini_parser.h"
26#include "substring.h"
27
28using namespace std;
29
30
31/**
32   \brief standard constructor
33   \todo this constructor is not jet implemented - do it
34*/
35GraphicsEngine::GraphicsEngine ()
36{
37  this->setClassID(CL_GRAPHICS_ENGINE, "GraphicsEngine");
38  this->setName("GraphicsEngine");
39
40  this->isInit = false;
41
42  this->bDisplayFPS = false;
43  this->minFPS = 9999;
44  this->maxFPS = 0;
45
46  this->fullscreenFlag = 0;
47}
48
49/**
50   \brief The Pointer to this GraphicsEngine
51*/
52GraphicsEngine* GraphicsEngine::singletonRef = NULL;
53
54/**
55   \brief destructs the graphicsEngine.
56*/
57GraphicsEngine::~GraphicsEngine ()
58{
59  // delete what has to be deleted here
60  EventHandler::getInstance()->unsubscribe(this);
61}
62
63/**
64 * initializes the GraphicsEngine with default settings.
65 */
66int GraphicsEngine::init()
67{
68  if (this->isInit)
69    return -1;
70  this->initVideo(640, 480, 16);
71}
72
73/**
74 * loads the GraphicsEngine's settings from a given ini-file and section
75 * @param iniParser the iniParser to load from
76 * @param section the Section in the ini-file to load from
77 * @returns nothing usefull
78 */
79int GraphicsEngine::initFromIniFile(IniParser* iniParser)
80{
81  // looking if we are in fullscreen-mode
82  const char* fullscreen = iniParser->getVar(CONFIG_NAME_FULLSCREEN, CONFIG_SECTION_VIDEO, "0");
83  if (strchr(fullscreen, '1'))
84    this->fullscreenFlag = SDL_FULLSCREEN;
85
86
87
88  // looking if we are in fullscreen-mode
89  const char* textures = iniParser->getVar(CONFIG_NAME_TEXTURES, CONFIG_SECTION_VIDEO_ADVANCED, "0");
90  if (strchr(textures, '1'))
91    this->texturesEnabled = true;
92  else
93    this->texturesEnabled = false;
94
95  // searching for a usefull resolution
96//  SubString resolution(iniParser->getVar(CONFIG_NAME_RESOLUTION, CONFIG_SECTION_VIDEO, "640x480"), 'x');
97  //resolution.debug();
98
99  //this->initVideo(atoi(resolution.getString(0)), atoi(resolution.getString(1)), 16);
100  this->initVideo(640,480,16);
101}
102
103
104
105/**
106   \brief initializes the Video for openGL.
107
108   This has to be done only once when starting orxonox.
109*/
110int GraphicsEngine::initVideo(unsigned int resX, unsigned int resY, unsigned int bbp)
111{
112  if (this->isInit)
113    return -1;
114  // initialize SDL_VIDEO
115  if (SDL_Init(SDL_INIT_VIDEO) == -1)
116    {
117      PRINTF(1)("could not initialize SDL Video\n");
118      //      return -1;
119    }
120  // initialize SDL_GL-settings
121  this->setGLattribs();
122
123  // setting the Video Flags.
124  this->videoFlags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE | SDL_DOUBLEBUF;
125
126  /* query SDL for information about our video hardware */
127  const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo ();
128  if( videoInfo == NULL)
129    {
130      PRINTF(1)("Failed getting Video Info :%s\n", SDL_GetError());
131      SDL_Quit ();
132    }
133  if( videoInfo->hw_available)
134    this->videoFlags |= SDL_HWSURFACE;
135  else
136    this->videoFlags |= SDL_SWSURFACE;
137  /*
138  if(VideoInfo -> blit_hw)
139    VideoFlags |= SDL_HWACCEL;
140  */
141    // setting up the Resolution
142  this->setResolution(resX, resY, bbp);
143
144  // TO DO: Create a cool icon and use it here
145  char* loadPic = new char[strlen(ResourceManager::getInstance()->getDataDir())+ 100];
146  sprintf(loadPic, "%s%s", ResourceManager::getInstance()->getDataDir(),  "pictures/orxonox-icon32x32.bmp");
147  SDL_WM_SetIcon(SDL_LoadBMP(loadPic), NULL);
148  delete loadPic;
149  // Enable default GL stuff
150  glEnable(GL_DEPTH_TEST);
151
152
153  // subscribe the resolutionChanged-event
154  //EventHandler::getInstance()->subscribe(this, ES_GAME, EV_VIDEO_RESIZE);
155  //! @todo eventSystem craps up the Starting of orxonox -> see why.
156
157  this->isInit = true;
158}
159
160/**
161 * sets the Window Captions and the Name of the icon.
162 * @param windowName The name of the Window
163 * @param icon The name of the Icon on the Disc
164 */
165void GraphicsEngine::setWindowName(const char* windowName, const char* icon)
166{
167  // Set window labeling
168  SDL_WM_SetCaption (windowName, icon);
169}
170
171
172/**
173   \brief Sets the GL-attributes
174*/
175int GraphicsEngine::setGLattribs()
176{
177  // Set video mode
178  // TO DO: parse arguments for settings
179  //SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
180  //SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
181  //SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
182  //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
183
184
185  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
186  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
187  SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0);
188  SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0);
189  SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0);
190  SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
191  SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
192}
193
194/**
195   \brief sets the Resolution of the Screen to display the Graphics to.
196   \param width The width of the window
197   \param height The height of the window
198   \param bpp bits per pixel
199*/
200int GraphicsEngine::setResolution(int width, int height, int bpp)
201{
202  this->resolutionX = width;
203  this->resolutionY = height;
204  this->bitsPerPixel = bpp;
205
206  if((this->screen = SDL_SetVideoMode(this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags | this->fullscreenFlag)) == NULL)
207    {
208      PRINTF(1)("Could not SDL_SetVideoMode(%d, %d, %d, %d): %s\n", this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags, SDL_GetError());
209      SDL_Quit();
210      //    return -1;
211    }
212}
213
214/**
215   \brief sets Fullscreen mode
216   \param fullscreen true if fullscreen, false if windowed
217*/
218void GraphicsEngine::setFullscreen(bool fullscreen)
219{
220  if (fullscreen)
221    fullscreenFlag = SDL_FULLSCREEN;
222  else
223    fullscreenFlag = 0;
224  this->setResolution(this->resolutionX, this->resolutionY, this->bitsPerPixel);
225}
226
227/**
228   \brief sets the background color
229   \param red the red part of the background
230   \param blue the blue part of the background
231   \param green the green part of the background
232   \param alpha the alpha part of the background
233*/
234void GraphicsEngine::setBackgroundColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
235{
236  glClearColor(red, green, blue, alpha);
237}
238
239
240/**
241   \brief Signalhandler, for when the resolution has changed
242   \param resizeInfo SDL information about the size of the new screen size
243*/
244int GraphicsEngine::resolutionChanged(const SDL_ResizeEvent& resizeInfo)
245{
246  this->setResolution(resizeInfo.w, resizeInfo.h, this->bitsPerPixel);
247}
248
249/**
250 * if Textures should be enabled
251*/
252bool GraphicsEngine::texturesEnabled = true;
253
254
255
256/**
257 *
258 * @param show if The mouse-cursor should be visible
259 */
260void GraphicsEngine::showMouse(bool show)
261{
262  if (show)
263    SDL_ShowCursor(SDL_ENABLE);
264  else
265    SDL_ShowCursor(SDL_DISABLE);
266}
267
268/**
269 *
270 * @returns The Visinility of the mouse-cursor (true if visible, false if it is invisible)
271 */
272bool GraphicsEngine::isMouseVisible()
273{
274  if (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE)
275    return true;
276  else
277    return false;
278}
279
280/**
281 *
282 * @param steal If the Winodow-Managers Events should be stolen to this app
283 * (steals the mouse, and all WM-clicks)
284 *
285 * This only happens, if the HARD-Debug-level is set to 0,1,2, because otherwise a Segfault could
286 * result in the loss of System-controll
287 */
288void GraphicsEngine::stealWMEvents(bool steal)
289{
290#if DEBUG < 3
291   if (steal)
292     SDL_WM_GrabInput(SDL_GRAB_ON);
293   else SDL_WM_GrabInput(SDL_GRAB_OFF);
294#endif
295}
296
297/**
298 *
299 * @returns true if Events are stolen from the WM, false if not.
300 */
301bool GraphicsEngine::isStealingEvents()
302{
303   if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON)
304     return true;
305   else
306     return false;
307};
308
309
310/**
311   \brief entering 2D Mode
312
313   this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
314*/
315void GraphicsEngine::enter2DMode()
316{
317  GraphicsEngine::storeMatrices();
318  SDL_Surface *screen = SDL_GetVideoSurface();
319
320  /* Note, there may be other things you need to change,
321     depending on how you have your OpenGL state set up.
322  */
323  glPushAttrib(GL_ENABLE_BIT);
324  glDisable(GL_DEPTH_TEST);
325  glDisable(GL_CULL_FACE);
326  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
327  glEnable(GL_TEXTURE_2D);
328
329  /* This allows alpha blending of 2D textures with the scene */
330  glEnable(GL_BLEND);
331  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
332
333  glViewport(0, 0, screen->w, screen->h);
334
335  glMatrixMode(GL_PROJECTION);
336  glPushMatrix();
337  glLoadIdentity();
338
339  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
340
341  glMatrixMode(GL_MODELVIEW);
342  glPushMatrix();
343  glLoadIdentity();
344
345  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
346}
347
348/**
349   \brief leaves the 2DMode again also \see Font::enter2DMode()
350*/
351void GraphicsEngine::leave2DMode()
352{
353  glMatrixMode(GL_MODELVIEW);
354  glPopMatrix();
355
356  glMatrixMode(GL_PROJECTION);
357  glPopMatrix();
358
359  glPopAttrib();
360}
361
362/**
363   \brief stores the GL_matrices
364*/
365void GraphicsEngine::storeMatrices()
366{
367  glGetDoublev(GL_PROJECTION_MATRIX, GraphicsEngine::projMat);
368  glGetDoublev(GL_MODELVIEW_MATRIX, GraphicsEngine::modMat);
369  glGetIntegerv(GL_VIEWPORT, GraphicsEngine::viewPort);
370}
371
372//! the stored ModelView Matrix.
373GLdouble GraphicsEngine::modMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
374//! the stored Projection Matrix
375GLdouble GraphicsEngine::projMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
376//! The ViewPort
377GLint GraphicsEngine::viewPort[4] = {0,0,0,0};
378
379
380
381/**
382   \brief outputs all the Fullscreen modes.
383*/
384void GraphicsEngine::listModes()
385{
386  /* Get available fullscreen/hardware modes */
387  this->videoModes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
388
389  /* Check is there are any modes available */
390  if(this->videoModes == (SDL_Rect **)0){
391    PRINTF(1)("No modes available!\n");
392    exit(-1);
393  }
394
395  /* Check if our resolution is restricted */
396  if(this->videoModes == (SDL_Rect **)-1){
397    PRINTF(2)("All resolutions available.\n");
398  }
399  else{
400    /* Print valid modes */
401    PRINT(0)("Available Resoulution Modes are\n");
402    for(int i = 0; this->videoModes[i]; ++i)
403      PRINT(4)(" |  %d x %d\n", this->videoModes[i]->w, this->videoModes[i]->h);
404  }
405}
406
407/**
408   \brief ticks the Text
409   \param dt the time passed
410*/
411void GraphicsEngine::tick(float dt)
412{
413  if( unlikely(this->bDisplayFPS))
414    {
415      this->currentFPS = 1.0/dt;
416      if( unlikely(this->currentFPS > this->maxFPS)) this->maxFPS = this->currentFPS;
417      if( unlikely(this->currentFPS < this->minFPS)) this->minFPS = this->currentFPS;
418
419#ifndef NO_TEXT
420      char tmpChar1[20];
421      sprintf(tmpChar1, "Current:  %4.0f", this->currentFPS);
422      this->geTextCFPS->setText(tmpChar1);
423      char tmpChar2[20];
424      sprintf(tmpChar2, "Max:    %4.0f", this->maxFPS);
425      this->geTextMaxFPS->setText(tmpChar2);
426      char tmpChar3[20];
427      sprintf(tmpChar3, "Min:    %4.0f", this->minFPS);
428      this->geTextMinFPS->setText(tmpChar3);
429#endif /* NO_TEXT */
430    }
431}
432
433/**
434   \brief displays the Frames per second
435   \param display if the text should be displayed
436
437   \todo this is dangerous
438*/
439void GraphicsEngine::displayFPS(bool display)
440{
441  if( display)
442    {
443#ifndef NO_TEXT
444      this->geTextCFPS = TextEngine::getInstance()->createText("fonts/arial_black.ttf", 15, TEXT_DYNAMIC, 0, 255, 0);
445      this->geTextCFPS->setAlignment(TEXT_ALIGN_LEFT);
446      this->geTextCFPS->setPosition(5, 500);
447      this->geTextMaxFPS = TextEngine::getInstance()->createText("fonts/arial_black.ttf", 15, TEXT_DYNAMIC, 0, 255, 0);
448      this->geTextMaxFPS->setAlignment(TEXT_ALIGN_LEFT);
449      this->geTextMaxFPS->setPosition(5, 530);
450      this->geTextMinFPS = TextEngine::getInstance()->createText("fonts/arial_black.ttf", 35, TEXT_DYNAMIC, 0, 255, 0);
451      this->geTextMinFPS->setAlignment(TEXT_ALIGN_LEFT);
452      this->geTextMinFPS->setPosition(5, 560);
453#endif /* NO_TEXT */
454    }
455  this->bDisplayFPS = display;
456}
457
458
459/**
460  \brief processes the events for orxonox main class
461  \param the event to handle
462 */
463void GraphicsEngine::process(const Event &event)
464{
465  switch (event.type)
466  {
467    case EV_VIDEO_RESIZE:
468      this->resolutionChanged(event.resize);
469      break;
470  }
471
472}
473
Note: See TracBrowser for help on using the repository browser.