Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: crosshair in WeaponManager (instead of World) and implemented easy Cyling for LoadParam

File size: 12.0 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
328  glViewport(0, 0, screen->w, screen->h);
329
330  glMatrixMode(GL_PROJECTION);
331  glPushMatrix();
332  glLoadIdentity();
333
334  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
335
336  glMatrixMode(GL_MODELVIEW);
337  glPushMatrix();
338  glLoadIdentity();
339
340  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
341}
342
343/**
344   \brief leaves the 2DMode again also \see Font::enter2DMode()
345*/
346void GraphicsEngine::leave2DMode()
347{
348  glMatrixMode(GL_PROJECTION);
349  glPopMatrix();
350
351  glMatrixMode(GL_MODELVIEW);
352  glPopMatrix();
353
354  glPopAttrib();
355}
356
357/**
358   \brief stores the GL_matrices
359*/
360void GraphicsEngine::storeMatrices()
361{
362  glGetDoublev(GL_PROJECTION_MATRIX, GraphicsEngine::projMat);
363  glGetDoublev(GL_MODELVIEW_MATRIX, GraphicsEngine::modMat);
364  glGetIntegerv(GL_VIEWPORT, GraphicsEngine::viewPort);
365}
366
367//! the stored ModelView Matrix.
368GLdouble GraphicsEngine::modMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
369//! the stored Projection Matrix
370GLdouble GraphicsEngine::projMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
371//! The ViewPort
372GLint GraphicsEngine::viewPort[4] = {0,0,0,0};
373
374
375
376/**
377   \brief outputs all the Fullscreen modes.
378*/
379void GraphicsEngine::listModes()
380{
381  /* Get available fullscreen/hardware modes */
382  this->videoModes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
383
384  /* Check is there are any modes available */
385  if(this->videoModes == (SDL_Rect **)0){
386    PRINTF(1)("No modes available!\n");
387    exit(-1);
388  }
389
390  /* Check if our resolution is restricted */
391  if(this->videoModes == (SDL_Rect **)-1){
392    PRINTF(2)("All resolutions available.\n");
393  }
394  else{
395    /* Print valid modes */
396    PRINT(0)("Available Resoulution Modes are\n");
397    for(int i = 0; this->videoModes[i]; ++i)
398      PRINT(4)(" |  %d x %d\n", this->videoModes[i]->w, this->videoModes[i]->h);
399  }
400}
401
402/**
403   \brief ticks the Text
404   \param dt the time passed
405*/
406void GraphicsEngine::tick(float dt)
407{
408  if( unlikely(this->bDisplayFPS))
409    {
410      this->currentFPS = 1.0/dt;
411      if( unlikely(this->currentFPS > this->maxFPS)) this->maxFPS = this->currentFPS;
412      if( unlikely(this->currentFPS < this->minFPS)) this->minFPS = this->currentFPS;
413
414#ifndef NO_TEXT
415      char tmpChar1[20];
416      sprintf(tmpChar1, "Current:  %4.0f", this->currentFPS);
417      this->geTextCFPS->setText(tmpChar1);
418      char tmpChar2[20];
419      sprintf(tmpChar2, "Max:    %4.0f", this->maxFPS);
420      this->geTextMaxFPS->setText(tmpChar2);
421      char tmpChar3[20];
422      sprintf(tmpChar3, "Min:    %4.0f", this->minFPS);
423      this->geTextMinFPS->setText(tmpChar3);
424#endif /* NO_TEXT */
425    }
426}
427
428/**
429   \brief displays the Frames per second
430   \param display if the text should be displayed
431
432   \todo this is dangerous
433*/
434void GraphicsEngine::displayFPS(bool display)
435{
436  if( display)
437    {
438#ifndef NO_TEXT
439      this->geTextCFPS = TextEngine::getInstance()->createText("fonts/arial_black.ttf", 15, TEXT_DYNAMIC, 0, 255, 0);
440      this->geTextCFPS->setAlignment(TEXT_ALIGN_LEFT);
441      this->geTextCFPS->setPosition(5, 5);
442      this->geTextMaxFPS = TextEngine::getInstance()->createText("fonts/arial_black.ttf", 15, TEXT_DYNAMIC, 0, 255, 0);
443      this->geTextMaxFPS->setAlignment(TEXT_ALIGN_LEFT);
444      this->geTextMaxFPS->setPosition(5, 35);
445      this->geTextMinFPS = TextEngine::getInstance()->createText("fonts/arial_black.ttf", 35, TEXT_DYNAMIC, 0, 255, 0);
446      this->geTextMinFPS->setAlignment(TEXT_ALIGN_LEFT);
447      this->geTextMinFPS->setPosition(5, 65);
448#endif /* NO_TEXT */
449    }
450  this->bDisplayFPS = display;
451}
452
453
454/**
455  \brief processes the events for orxonox main class
456  \param the event to handle
457 */
458void GraphicsEngine::process(const Event &event)
459{
460  switch (event.type)
461  {
462    case EV_VIDEO_RESIZE:
463      this->resolutionChanged(event.resize);
464      break;
465  }
466
467}
468
Note: See TracBrowser for help on using the repository browser.