Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/cleanup/src/lib/graphics/graphics_engine.cc @ 10596

Last change on this file since 10596 was 10571, checked in by bensch, 18 years ago

cleaned out unused defs files, and moved glincl to grafics, alincl.h to sound

File size: 17.8 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 "state.h"
20
21#include "world_entity.h"
22
23#include "render_2d.h"
24#include "text_engine.h"
25#include "light.h"
26#include "shader.h"
27#include "debug.h"
28
29#include "parser/preferences/preferences.h"
30#include "substring.h"
31#include "text.h"
32
33#include "orxonox_globals.h"
34#include "texture.h"
35
36#include "graphics_effect.h"
37
38#include "shell_command.h"
39#include "loading/load_param_xml.h"
40
41#include "parser/tinyxml/tinyxml.h"
42#include "util/loading/load_param.h"
43#include "util/loading/factory.h"
44
45#ifdef __WIN32__
46 #include "static_model.h"
47#endif
48
49SHELL_COMMAND(wireframe, GraphicsEngine, wireframe);
50SHELL_COMMAND(fps, GraphicsEngine, toggleFPSdisplay);
51
52ObjectListDefinition(GraphicsEngine);
53
54/**
55 * @brief standard constructor
56 */
57GraphicsEngine::GraphicsEngine ()
58{
59  this->registerObject(this, GraphicsEngine::_objectList);
60  this->setName("GraphicsEngine");
61
62  this->isInit = false;
63
64  this->bDisplayFPS = false;
65  this->bAntialiasing = false;
66  this->bDedicated = false;
67  this->minFPS = 9999;
68  this->maxFPS = 0;
69
70  this->geTextCFPS = NULL;
71  this->geTextMaxFPS = NULL;
72  this->geTextMinFPS = NULL;
73
74  this->fullscreenFlag = 0;
75  this->videoFlags = 0;
76  this->screen = NULL;
77
78  // initialize the Modules
79  TextEngine::getInstance();
80  this->graphicsEffects = NULL;
81
82}
83
84/**
85 * @brief The Pointer to this GraphicsEngine
86 */
87GraphicsEngine* GraphicsEngine::singletonRef = NULL;
88
89/**
90 * @brief destructs the graphicsEngine.
91*/
92GraphicsEngine::~GraphicsEngine ()
93{
94  // delete what has to be deleted here
95  this->displayFPS( false );
96
97  //TextEngine
98  delete TextEngine::getInstance();
99  // render 2D
100  delete Render2D::getInstance();
101
102  SDL_QuitSubSystem(SDL_INIT_VIDEO);
103  //   if (this->screen != NULL)
104  //     SDL_FreeSurface(this->screen);
105
106  GraphicsEngine::singletonRef = NULL;
107}
108
109
110/**
111 * @brief loads the GraphicsEngine Specific Parameters.
112 * @param root: the XML-Element to load the Data From
113 */
114void GraphicsEngine::loadParams(const TiXmlElement* root)
115{
116  LoadParamXML(root, "GraphicsEffect", this, GraphicsEngine, loadGraphicsEffects)
117   .describe("loads a graphics effect");
118}
119
120
121
122
123/**
124 * @param root The XML-element to load GraphicsEffects from
125 */
126void GraphicsEngine::loadGraphicsEffects(const TiXmlElement* root)
127{
128  LOAD_PARAM_START_CYCLE(root, element);
129  {
130    PRINTF(4)("element is: %s\n", element->Value());
131    Factory::fabricate(element);
132  }
133  LOAD_PARAM_END_CYCLE(element);
134}
135
136
137
138/**
139 * @brief initializes the GraphicsEngine with default settings.
140 */
141int GraphicsEngine::init()
142{
143  if (this->isInit)
144    return -1;
145  this->initVideo(640, 480, 16);
146  return 1;
147}
148
149/**
150 * @brief loads the GraphicsEngine's settings from a given ini-file and section
151 * @returns nothing usefull
152 */
153int GraphicsEngine::initFromPreferences()
154{
155  // looking if we are in fullscreen-mode
156  MultiType fullscreen = Preferences::getInstance()->getString(CONFIG_SECTION_VIDEO, CONFIG_NAME_FULLSCREEN, "0");
157
158  if (fullscreen.getBool())
159    this->fullscreenFlag = SDL_FULLSCREEN;
160
161  // looking if we are in fullscreen-mode
162  MultiType textures = Preferences::getInstance()->getString(CONFIG_SECTION_VIDEO_ADVANCED, CONFIG_NAME_TEXTURES, "1");
163  Texture::setTextureEnableState(textures.getBool());
164
165  // check it is a dedicated network node: so no drawings are made
166  MultiType dedicated = Preferences::getInstance()->getString(CONFIG_SECTION_VIDEO, CONFIG_NAME_NO_RENDER, "0");
167  this->bDedicated = dedicated.getBool();
168
169  // searching for a usefull resolution
170  SubString resolution(Preferences::getInstance()->getString(CONFIG_SECTION_VIDEO, CONFIG_NAME_RESOLUTION, "640x480").c_str(), 'x'); ///FIXME
171  //resolution.debug();
172  MultiType x = resolution.getString(0), y = resolution.getString(1);
173  return this->initVideo(x.getInt(), y.getInt(), 16);
174
175  //   GraphicsEffect* fe = new FogEffect(NULL);
176  //   this->loadGraphicsEffect(fe);
177  //   fe->activate();
178  //   PRINTF(0)("--------------------------------------------------------------\n");
179
180  //LenseFlare* ge = new LenseFlare();
181  //this->loadGraphicsEffect(ge);
182
183  //ge->addFlare("pictures/lense_flare/sun.png"); //sun
184  //ge->addFlare("pictures/lense_flare/lens2.png"); //first halo
185  //ge->addFlare("pictures/lense_flare/lens1.png"); //small birst
186  //ge->addFlare("pictures/lense_flare/lens3.png"); //second halo
187  //ge->addFlare("pictures/lense_flare/lens4.png");
188  //ge->addFlare("pictures/lense_flare/lens1.png");
189  //ge->addFlare("pictures/lense_flare/lens3.png");
190
191  //ge->activate();
192}
193
194
195
196/**
197 * @brief initializes the Video for openGL.
198 *
199 * This has to be done only once when starting orxonox.
200 */
201int GraphicsEngine::initVideo(unsigned int resX, unsigned int resY, unsigned int bbp)
202{
203  if (this->isInit)
204    return -1;
205  //   initialize SDL_VIDEO
206  if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
207  {
208    PRINTF(1)("could not initialize SDL Video\n");
209    return -1;
210  }
211  // initialize SDL_GL-settings
212  this->setGLattribs();
213
214  // setting the Video Flags.
215  this->videoFlags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE ;
216
217  /* query SDL for information about our video hardware */
218  const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo ();
219  if( videoInfo == NULL)
220  {
221    PRINTF(1)("Failed getting Video Info :%s\n", SDL_GetError());
222    SDL_Quit ();
223  }
224  if( videoInfo->hw_available)
225    this->videoFlags |= SDL_HWSURFACE;
226  else
227    this->videoFlags |= SDL_SWSURFACE;
228  /*
229  if(VideoInfo -> blit_hw)
230    VideoFlags |= SDL_HWACCEL;
231  */
232  // setting up the Resolution
233  this->setResolution(resX, resY, bbp);
234
235  // GRABBING ALL GL-extensions
236  this->grabHardwareSettings();
237
238  // Enable default GL stuff
239  glEnable(GL_DEPTH_TEST);
240
241  Render2D::getInstance();
242
243  this->isInit = true;
244  return 1;
245}
246
247/**
248 * @brief sets the Window Captions and the Name of the icon.
249 * @param windowName The name of the Window
250 * @param icon The name of the Icon on the Disc
251 */
252void GraphicsEngine::setWindowName(const std::string& windowName, const std::string& icon)
253{
254  SDL_Surface* iconSurf = SDL_LoadBMP(icon.c_str());
255  if (iconSurf != NULL)
256  {
257    Uint32 colorkey = SDL_MapRGB(iconSurf->format, 0, 0, 0);
258    SDL_SetColorKey(iconSurf, SDL_SRCCOLORKEY, colorkey);
259    SDL_WM_SetIcon(iconSurf, NULL);
260    SDL_FreeSurface(iconSurf);
261  }
262
263  SDL_WM_SetCaption (windowName.c_str(), icon.c_str());
264}
265
266
267/**
268 * @brief Sets the GL-attributes
269 */
270void GraphicsEngine::setGLattribs()
271{
272  // Set video mode
273  // TO DO: parse arguments for settings
274  //SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
275  //SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
276  //SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
277  //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
278
279
280  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
281  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
282  SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0);
283  SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0);
284  SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0);
285  SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
286  SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
287
288  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);      //Use at least 5 bits of Red
289  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);    //Use at least 5 bits of Green
290  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);     //Use at least 5 bits of Blue
291  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);   //Use at least 16 bits for the depth buffer
292  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);  //Enable double buffering
293
294  // enable antialiasing?
295  if( this->bAntialiasing)
296  {
297    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,4);
298    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1);
299  }
300
301  glEnable(GL_CULL_FACE);
302  glCullFace(GL_FRONT);
303}
304
305/**
306 * @brief grabs the Hardware Specifics
307 *
308 * checks for all the different HW-types
309 */
310void GraphicsEngine::grabHardwareSettings()
311{
312  const char* renderer = (const char*) glGetString(GL_RENDERER);
313  const char* vendor   = (const char*) glGetString(GL_VENDOR);
314  const char* version  = (const char*) glGetString(GL_VERSION);
315  const char* extensions = (const char*) glGetString(GL_EXTENSIONS);
316
317  //  printf("%s %s %s\n %s", renderer, vendor, version, extensions);
318
319  if (renderer != NULL)
320  {
321    this->hwRenderer == renderer;
322  }
323  if (vendor != NULL)
324  {
325    this->hwVendor == vendor;
326  }
327  if (version != NULL)
328  {
329    this->hwVersion == version;
330  }
331
332  if (extensions != NULL)
333    this->hwExtensions.split(extensions, " \n\t,");
334
335  PRINT(4)("Running on : vendor: %s,  renderer: %s,  version:%s\n", vendor, renderer, version);
336  PRINT(4)("Extensions:\n");
337  for (unsigned int i = 0; i < this->hwExtensions.size(); i++)
338    PRINT(4)("%d: %s\n", i, this->hwExtensions[i].c_str());
339
340
341  // inizializing GLEW
342  GLenum err = glewInit();
343  if (GLEW_OK != err)
344  {
345    /* Problem: glewInit failed, something is seriously wrong. */
346    PRINTF(1)("%s\n", glewGetErrorString(err));
347  }
348  PRINTF(4)("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
349}
350
351
352/**
353 * @brief sets the Resolution of the Screen to display the Graphics to.
354 * @param width The width of the window
355 * @param height The height of the window
356 * @param bpp bits per pixel
357 */
358int GraphicsEngine::setResolution(int width, int height, int bpp)
359{
360  this->resolutionX = width;
361  this->resolutionY = height;
362  this->bitsPerPixel = bpp;
363  State::setResolution( width, height);
364
365  if (this->screen != NULL)
366    SDL_FreeSurface(screen);
367  if((this->screen = SDL_SetVideoMode(this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags | this->fullscreenFlag)) == NULL)
368  {
369    PRINTF(1)("Could not SDL_SetVideoMode(%d, %d, %d, %d): %s\n", this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags, SDL_GetError());
370    //    SDL_Quit();
371    //    return -1;
372    return -1;
373  }
374  glViewport(0, 0, width, height);                     // Reset The Current Viewport
375
376#ifdef __WIN32__
377  // REBUILDING TEXTURES (ON WINDOWS CONTEXT SWITCH)
378  ObjectList<Texture>::const_iterator retex;
379  for (retex = Texture::objectList().begin(); retex != Texture::objectList().end(); ++retex)
380    (*retex)->rebuild();
381
382  // REBUILDING MODELS
383  ObjectList<StaticModel>::const_iterator remod;
384  for (remod = StaticModel::objectList().begin(); remod != StaticModel::objectList().end(); ++remod)
385    (*remod)->rebuild();
386
387#endif /* __WIN32__ */
388  return 1;
389}
390
391/**
392 * @brief sets Fullscreen mode
393 * @param fullscreen true if fullscreen, false if windowed
394*/
395void GraphicsEngine::setFullscreen(bool fullscreen)
396{
397  if (fullscreen)
398    this->fullscreenFlag = SDL_FULLSCREEN;
399  else
400    this->fullscreenFlag = 0;
401  this->setResolution(this->resolutionX, this->resolutionY, this->bitsPerPixel);
402}
403
404void GraphicsEngine::toggleFullscreen()
405{
406  if (this->fullscreenFlag == SDL_FULLSCREEN)
407    this->fullscreenFlag = 0;
408  else
409    this->fullscreenFlag = SDL_FULLSCREEN;
410  this->setResolution(this->resolutionX, this->resolutionY, this->bitsPerPixel);
411}
412
413
414/**
415 * @brief sets the background color
416 * @param red the red part of the background
417 * @param blue the blue part of the background
418 * @param green the green part of the background
419 * @param alpha the alpha part of the background
420 */
421void GraphicsEngine::setBackgroundColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
422{
423  glClearColor(red, green, blue, alpha);
424}
425
426/**
427 * @brief Signalhandler, for when the resolution has changed
428 * @param resizeInfo SDL information about the size of the new screen size
429 */
430void GraphicsEngine::resolutionChanged(const SDL_ResizeEvent& resizeInfo)
431{
432  this->setResolution(resizeInfo.w, resizeInfo.h, this->bitsPerPixel);
433}
434
435/**
436 * @brief entering 2D Mode
437 * this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
438 */
439void GraphicsEngine::enter2DMode()
440{
441  //GraphicsEngine::storeMatrices();
442  SDL_Surface *screen = SDL_GetVideoSurface();
443
444  /* Note, there may be other things you need to change,
445     depending on how you have your OpenGL state set up.
446  */
447  glPushAttrib(GL_ENABLE_BIT);
448  glDisable(GL_DEPTH_TEST);
449  glDisable(GL_CULL_FACE);
450  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
451
452  glMatrixMode(GL_PROJECTION);
453  glPushMatrix();
454  glLoadIdentity();
455  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
456
457  glMatrixMode(GL_MODELVIEW);
458  glPushMatrix();
459  glLoadIdentity();
460}
461
462/**
463 * @brief leaves the 2DMode again also @see Font::enter2DMode()
464 */
465void GraphicsEngine::leave2DMode()
466{
467
468  glMatrixMode(GL_MODELVIEW);
469  glPopMatrix();
470
471  glMatrixMode(GL_PROJECTION);
472  glPopMatrix();
473
474  glPopAttrib();
475}
476
477/**
478 * @brief changes to wireframe-mode.
479 */
480void GraphicsEngine::wireframe()
481{
482  glPolygonMode(GL_FRONT, GL_LINE);
483}
484
485/**
486 * @brief stores the GL_matrices
487 */
488void GraphicsEngine::storeMatrices()
489{
490  glGetDoublev(GL_PROJECTION_MATRIX, GraphicsEngine::projMat);
491  glGetDoublev(GL_MODELVIEW_MATRIX, GraphicsEngine::modMat);
492  glGetIntegerv(GL_VIEWPORT, GraphicsEngine::viewPort);
493}
494
495//! the stored ModelView Matrix.
496GLdouble GraphicsEngine::modMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
497//! the stored Projection Matrix
498GLdouble GraphicsEngine::projMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
499//! The ViewPort
500GLint GraphicsEngine::viewPort[4] = {0,0,0,0};
501
502
503
504/**
505 * @brief outputs all the Fullscreen modes.
506 */
507void GraphicsEngine::listModes()
508{
509  /* Get available fullscreen/hardware modes */
510  this->videoModes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
511
512  /* Check is there are any modes available */
513  if(this->videoModes == (SDL_Rect **)0)
514  {
515    PRINTF(1)("No modes available!\n");
516    exit(-1);
517  }
518
519  /* Check if our resolution is restricted */
520  if(this->videoModes == (SDL_Rect **)-1)
521  {
522    PRINTF(2)("All resolutions available.\n");
523  }
524  else
525  {
526    /* Print valid modes */
527    PRINT(0)("Available Resoulution Modes are\n");
528    for(int i = 0; this->videoModes[i]; ++i)
529      PRINT(4)(" |  %d x %d\n", this->videoModes[i]->w, this->videoModes[i]->h);
530  }
531}
532
533/**
534 * @brief checks wether a certain extension is availiable
535 * @param extension the Extension to check for (ex. GL_ARB_texture_env_dot3)
536 * @return true if it is, false otherwise
537 */
538bool GraphicsEngine::hwSupportsEXT(const std::string& extension)
539{
540  for (unsigned int i = 0; i < this->hwExtensions.size(); i++)
541    if ( this->hwExtensions.getString(i) == extension)
542      return true;
543  return false;
544}
545
546/**
547 * @brief updates everything that is to be updated in the GraphicsEngine
548 */
549void GraphicsEngine::update(float dt)
550{
551  Render2D::getInstance()->update(dt);
552}
553
554
555/**
556 * @brief ticks the Text
557 * @param dt the time passed
558 */
559void GraphicsEngine::tick(float dt)
560{
561  if( unlikely(this->bDisplayFPS))
562  {
563    this->currentFPS = 1.0/dt;
564    if( unlikely(this->currentFPS > this->maxFPS)) this->maxFPS = this->currentFPS;
565    if( unlikely(this->currentFPS < this->minFPS)) this->minFPS = this->currentFPS;
566
567#ifndef NO_TEXT
568    char tmpChar1[20];
569    sprintf(tmpChar1, "Current:  %4.0f", this->currentFPS);
570    this->geTextCFPS->setText(tmpChar1);
571    char tmpChar2[20];
572    sprintf(tmpChar2, "Max:    %4.0f", this->maxFPS);
573    this->geTextMaxFPS->setText(tmpChar2);
574    char tmpChar3[20];
575    sprintf(tmpChar3, "Min:    %4.0f", this->minFPS);
576    this->geTextMinFPS->setText(tmpChar3);
577#endif /* NO_TEXT */
578
579  }
580
581  Render2D::getInstance()->tick(dt);
582
583  // tick the graphics effects
584  for (ObjectList<GraphicsEffect>::const_iterator it = GraphicsEffect::objectList().begin();
585       it != GraphicsEffect::objectList().end();
586       ++it)
587    (*it)->tick(dt);
588}
589
590/**
591 * @brief draws all Elements that should be displayed on the Background.
592 */
593void GraphicsEngine::drawBackgroundElements() const
594{
595  GraphicsEngine::storeMatrices();
596
597  Render2D::getInstance()->draw(E2D_LAYER_BELOW_ALL, E2D_LAYER_BELOW_ALL);
598}
599
600/**
601 * this draws the graphics engines graphics effecs
602 */
603void GraphicsEngine::draw() const
604{
605  if( this->graphicsEffects != NULL)
606  {
607    //draw the graphics effects
608    std::list<BaseObject*>::const_iterator it;
609    for (it = this->graphicsEffects->begin(); it != this->graphicsEffects->end(); it++)
610      dynamic_cast<GraphicsEffect*>(*it)->draw();
611  }
612  Shader::suspendShader();
613  Render2D::getInstance()->draw(E2D_LAYER_BOTTOM, E2D_LAYER_ABOVE_ALL);
614  Shader::restoreShader();
615}
616
617
618void GraphicsEngine::toggleFPSdisplay()
619{
620  this->displayFPS(!this->bDisplayFPS);
621}
622
623
624/**
625 * @brief displays the Frames per second
626 * @param display if the text should be displayed
627*/
628void GraphicsEngine::displayFPS(bool display)
629{
630#ifndef NO_TEXT
631  if( display )
632  {
633    if (this->geTextCFPS == NULL)
634    {
635      this->geTextCFPS = new Text("fonts/final_frontier.ttf", 15);
636      this->geTextCFPS->setName("curFPS");
637      this->geTextCFPS->setAlignment(TEXT_ALIGN_LEFT);
638      this->geTextCFPS->setAbsCoor2D(5, 0);
639    }
640    if (this->geTextMaxFPS == NULL)
641    {
642      this->geTextMaxFPS = new Text("fonts/final_frontier.ttf", 15);
643      this->geTextMaxFPS->setName("MaxFPS");
644      this->geTextMaxFPS->setAlignment(TEXT_ALIGN_LEFT);
645      this->geTextMaxFPS->setAbsCoor2D(5, 20);
646    }
647    if (this->geTextMinFPS == NULL)
648    {
649      this->geTextMinFPS = new Text("fonts/final_frontier.ttf", 15);
650      this->geTextMinFPS->setName("MinFPS");
651      this->geTextMinFPS->setAlignment(TEXT_ALIGN_LEFT);
652      this->geTextMinFPS->setAbsCoor2D(5, 40);
653    }
654  }
655  else
656  {
657    delete this->geTextCFPS;
658    this->geTextCFPS = NULL;
659    delete this->geTextMaxFPS;
660    this->geTextMaxFPS = NULL;
661    delete this->geTextMinFPS;
662    this->geTextMinFPS = NULL;
663  }
664  this->bDisplayFPS = display;
665#else
666  this->bDisplayFPS = false;
667#endif /* NO_TEXT */
668}
669
670
671/**
672 * @brief processes the events for the GraphicsEngine class
673 * @param the event to handle
674 */
675void GraphicsEngine::process(const Event &event)
676{
677  switch (event.type)
678  {
679    case EV_VIDEO_RESIZE:
680    this->resolutionChanged(event.resize);
681    break;
682  }
683}
Note: See TracBrowser for help on using the repository browser.