RenderWindow.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Graphics/RenderWindow.hpp>
00029 #include <SFML/Graphics/Drawable.hpp>
00030 #include <SFML/Graphics/GraphicsDevice.hpp>
00031 #include <SFML/Graphics/Image.hpp>
00032 #include <SFML/Graphics/OpenGL.hpp>
00033 #include <iostream>
00034 
00035 
00039 sfRenderWindow::sfRenderWindow() :
00040 myBackgroundColor(sfColor(0, 0, 0, 255)),
00041 myOpenGLMode     (false)
00042 {
00043 
00044 }
00045 
00046 
00050 sfRenderWindow::sfRenderWindow(sfVideoMode Mode, const std::string& Title, bool Fullscreen) :
00051 myBackgroundColor(sfColor(0, 0, 0, 255)),
00052 myOpenGLMode     (false)
00053 {
00054     Create(Mode, Title, Fullscreen);
00055 }
00056 
00057 
00061 sfRenderWindow::sfRenderWindow(sfWindowHandle Handle) :
00062 myBackgroundColor(sfColor(0, 0, 0, 255)),
00063 myOpenGLMode     (false)
00064 {
00065     Create(Handle);
00066 }
00067 
00068 
00072 sfRenderWindow::~sfRenderWindow()
00073 {
00074     // Nothing to do...
00075 }
00076 
00077 
00081 void sfRenderWindow::Create(sfVideoMode Mode, const std::string& Title, bool Fullscreen)
00082 {
00083     // Let the base class do the job
00084     sfWindow::Create(Mode, Title, Fullscreen);
00085 
00086     // Initialize the rendering states
00087     Initialize();
00088 }
00089 
00090 
00094 void sfRenderWindow::Create(sfWindowHandle Handle)
00095 {
00096     // Let base class do the job
00097     sfWindow::Create(Handle);
00098 
00099     // Initialize the rendering states
00100     Initialize();
00101 }
00102 
00103 
00107 void sfRenderWindow::Display()
00108 {
00109     // Discard display if we are in OpenGL custom rendering mode (it would mess up the render states)
00110     if (myOpenGLMode)
00111     {
00112         std::cerr << "You cannot display a window while in OpenGL mode ; call EndOpenGL() before calling Display()" << std::endl;
00113         return;
00114     }
00115 
00116     // Set our window as the current target for rendering
00117     if (sfWindow::SetCurrent())
00118     {
00119         // Display backbuffer on screen
00120         sfWindow::Display();
00121 
00122         // Find which buffers we must clear
00123         GLbitfield                ClearBits  = GL_COLOR_BUFFER_BIT;
00124         if (GetDepthBits()   > 0) ClearBits |= GL_DEPTH_BUFFER_BIT;
00125         if (GetStencilBits() > 0) ClearBits |= GL_STENCIL_BUFFER_BIT;
00126         
00127         // Clear the color/depth/stencil buffers for next frame
00128         sfGLCheck(glClearColor(myBackgroundColor.r / 255.f,
00129                                myBackgroundColor.g / 255.f,
00130                                myBackgroundColor.b / 255.f,
00131                                myBackgroundColor.a / 255.f));
00132         sfGLCheck(glClear(ClearBits));
00133     }
00134 }
00135 
00136 
00140 void sfRenderWindow::Draw(sfDrawable& Object)
00141 {
00142     // Discard draw if we are in OpenGL custom rendering mode (it would mess up the render states)
00143     if (myOpenGLMode)
00144     {
00145         std::cerr << "You cannot use SFML rendering while in OpenGL mode ; call EndOpenGL() before calling Draw()" << std::endl;
00146         return;
00147     }
00148 
00149     // Set our window as the current target for rendering
00150     if (sfWindow::SetCurrent())
00151     {
00152         // Let the object draw itself
00153         Object.Draw(*this);
00154     }
00155 }
00156 
00157 
00161 void sfRenderWindow::Capture(const std::string& Filename) const
00162 {
00163     // Set our window as the current target for rendering
00164     if (sfWindow::SetCurrent())
00165     {
00166         // Get the window dimensions
00167         const unsigned int Width  = GetWidth();
00168         const unsigned int Height = GetHeight();
00169 
00170         // Get pixels from the backbuffer
00171         std::vector<sfUint32> Pixels(Width * Height);
00172         glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Pixels[0]);
00173 
00174         // Create an image from it and save it to disk
00175         sfImage Screen(Width, Height, &Pixels[0]);
00176         Screen.SaveToFile(Filename);
00177     }
00178 }
00179 
00180 
00184 void sfRenderWindow::SetBackgroundColor(const sfColor& Color)
00185 {
00186     myBackgroundColor = Color;
00187 }
00188 
00189 
00193 bool sfRenderWindow::GetEvent(sfEvent& Event)
00194 {
00195     // Forward to base class
00196     if (sfWindow::GetEvent(Event))
00197     {
00198         // Intercept resize events, because we have to adjust the viewport to new size
00199         if (Event.Type == sfEvent::Resize)
00200             sfGLCheck(glViewport(0, 0, Event.Size.Width, Event.Size.Height));
00201 
00202         return true;
00203     }
00204 
00205     return false;
00206 }
00207 
00208 
00212 void sfRenderWindow::SetView(const sfView* View)
00213 {
00214     // Discard display if we are in OpenGL custom rendering mode (it would mess up the render states)
00215     if (myOpenGLMode)
00216     {
00217         std::cerr << "You cannot change the view while in OpenGL mode ; call EndOpenGL() before setting a new SFML view" << std::endl;
00218         return;
00219     }
00220 
00221     // Set our window as the current target for rendering
00222     if (sfWindow::SetCurrent())
00223     {
00224         // If a null pointer is passed, switch to default view
00225         if (View == NULL)
00226             View = &myDefaultView;
00227 
00228         // Compute view rectangle coordinates
00229         float X = View->Left + View->Width  / 2;
00230         float Y = View->Top  + View->Height / 2;
00231         float HalfWidth  = View->Width  / (2 * View->Zoom);
00232         float HalfHeight = View->Height / (2 * View->Zoom);
00233 
00234         // Store view rectangle for optimization purpose
00235         myCurrentRect = sfFloatRect(X - HalfWidth, Y - HalfHeight, X + HalfWidth, Y + HalfHeight);
00236 
00237         // Update the projection matrix according to the new view
00238         sfGLCheck(glMatrixMode(GL_PROJECTION));
00239         sfGLCheck(glLoadIdentity());
00240         sfGLCheck(glOrtho(myCurrentRect.Left, myCurrentRect.Right, myCurrentRect.Bottom, myCurrentRect.Top, -1, 1));
00241     }
00242 }
00243 
00244 
00248 const sfFloatRect& sfRenderWindow::GetViewRect() const
00249 {
00250     return myCurrentRect;
00251 }
00252 
00253 
00257 void sfRenderWindow::BeginOpenGL()
00258 {
00259     if (!myOpenGLMode && sfWindow::SetCurrent())
00260     {
00261         // Save current projection matrix
00262         sfGLCheck(glMatrixMode(GL_PROJECTION));
00263         sfGLCheck(glPushMatrix());
00264 
00265         // Save current render states
00266         sfGLCheck(glPushAttrib(GL_ALL_ATTRIB_BITS));
00267 
00268         // Set OpenGL mode flag
00269         myOpenGLMode = true;
00270     }
00271 }
00272 
00273 
00277 void sfRenderWindow::EndOpenGL()
00278 {
00279     if (myOpenGLMode && sfWindow::SetCurrent())
00280     {
00281         // Restore render states
00282         sfGLCheck(glPopAttrib());
00283 
00284         // Restore projection matrix
00285         sfGLCheck(glMatrixMode(GL_PROJECTION));
00286         sfGLCheck(glPopMatrix());
00287 
00288         // Clear OpenGL mode flag
00289         myOpenGLMode = false;
00290     }
00291 }
00292 
00293 
00297 void sfRenderWindow::Initialize()
00298 {
00299     if (sfWindow::SetCurrent())
00300     {
00301         // Set default OpenGL states
00302         sfGLCheck(glEnable(GL_ALPHA_TEST));
00303         sfGLCheck(glAlphaFunc(GL_GREATER, 0));
00304         sfGLCheck(glEnable(GL_BLEND));
00305         sfGLCheck(glEnable(GL_TEXTURE_2D));
00306         sfGLCheck(glDisable(GL_LIGHTING));
00307         sfGLCheck(glDisable(GL_DEPTH_TEST));
00308         sfGLCheck(glDisable(GL_CULL_FACE));
00309         sfGLCheck(glShadeModel(GL_SMOOTH));
00310         sfGLCheck(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST));
00311         sfGLCheck(glClearDepth(1.f));
00312         sfGLCheck(glClearStencil(0));
00313 
00314         // Setup the default view
00315         myDefaultView.Left   = 0;
00316         myDefaultView.Top    = 0;
00317         myDefaultView.Width  = static_cast<float>(GetWidth());
00318         myDefaultView.Height = static_cast<float>(GetHeight());
00319         myDefaultView.Zoom   = 1.f;
00320         SetView(NULL);
00321     }
00322 }