Mercurial > fife-parpg
diff engine/core/video/opengl/renderbackendopengl.cpp @ 0:4a0efb7baf70
* Datasets becomes the new trunk and retires after that :-)
author | mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sun, 29 Jun 2008 18:44:17 +0000 |
parents | |
children | 90005975cdbb |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/core/video/opengl/renderbackendopengl.cpp Sun Jun 29 18:44:17 2008 +0000 @@ -0,0 +1,202 @@ +/*************************************************************************** + * Copyright (C) 2005-2008 by the FIFE team * + * http://www.fifengine.de * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +// Standard C++ library includes + +// Platform specific includes + +// 3rd party library includes +#include <SDL.h> + +// FIFE includes +#include "util/base/exception.h" + +#include "fife_opengl.h" +#include "glimage.h" +#include "renderbackendopengl.h" + +namespace FIFE { + + RenderBackendOpenGL::RenderBackendOpenGL() : RenderBackend() { + // Get the pixelformat we want. + SDL_Surface* testsurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 1, 1, 32, + RMASK, GMASK, BMASK ,AMASK); + + m_rgba_format = *(testsurface->format); + SDL_FreeSurface(testsurface); + } + + const std::string& RenderBackendOpenGL::getName() const { + static std::string backend_name = "OpenGL"; + return backend_name; + } + + RenderBackendOpenGL::~RenderBackendOpenGL() { + } + + + void RenderBackendOpenGL::init() { + Uint32 flags = SDL_INIT_VIDEO; + if (SDL_InitSubSystem(flags) < 0) + throw SDLException(SDL_GetError()); + + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); // temporary hack + } + + Image* RenderBackendOpenGL::createMainScreen(unsigned int width, unsigned int height, unsigned char bitsPerPixel, bool fs) { + delete m_screen; + m_screen = 0; + + Uint32 flags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE | SDL_HWACCEL; + if ( fs ) { + flags |= SDL_FULLSCREEN; + } + + SDL_Surface* screen = NULL; + + if( 0 == bitsPerPixel ) { + /// autodetect best mode + unsigned char possibleBitsPerPixel[] = {32, 24, 16, 0}; + int i = 0; + while( true ) { + bitsPerPixel = possibleBitsPerPixel[i]; + if( !bitsPerPixel ) { + throw SDLException("Videomode not available"); + } + + if ( SDL_VideoModeOK(width, height, bitsPerPixel, flags) ) { + screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags); + if( screen ) { + break; + } + } + ++i; + } + } else { + if ( !SDL_VideoModeOK(width, height, bitsPerPixel, flags) ) { + throw SDLException("Videomode not available"); + } + screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags); + } + + SDL_WM_SetCaption("FIFE", 0); + + if (!screen) { + throw SDLException(SDL_GetError()); + } + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + gluOrtho2D(0, width, height, 0); + glMatrixMode(GL_MODELVIEW); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_SCISSOR_TEST); + + glPointSize(1.0); + glLineWidth(1.0); + + m_screen = new GLImage(screen); + return m_screen; + } + + void RenderBackendOpenGL::startFrame() { + glClear(GL_COLOR_BUFFER_BIT); + } + + void RenderBackendOpenGL::endFrame() { + SDL_GL_SwapBuffers(); + } + + Image* RenderBackendOpenGL::createImage(SDL_Surface* surface) { + // Given an abritary surface, we must convert it to the format GLImage will understand. + // It's easiest to let SDL do this for us. + + // Uh. Gotta love this :-) + // Check for colorkey too? + // Leave out the loss/shift checks? + if( m_rgba_format.BitsPerPixel == surface->format->BitsPerPixel + && m_rgba_format.Rmask == surface->format->Rmask + && m_rgba_format.Gmask == surface->format->Gmask + && m_rgba_format.Bmask == surface->format->Bmask + && m_rgba_format.Amask == surface->format->Amask + && m_rgba_format.Rshift == surface->format->Rshift + && m_rgba_format.Gshift == surface->format->Gshift + && m_rgba_format.Bshift == surface->format->Bshift + && m_rgba_format.Ashift == surface->format->Ashift + && m_rgba_format.Rloss == surface->format->Rloss + && m_rgba_format.Gloss == surface->format->Gloss + && m_rgba_format.Bloss == surface->format->Bloss + && m_rgba_format.Aloss == surface->format->Aloss + && surface->flags & SDL_SRCALPHA ) { + + return new GLImage(surface); + } + + SDL_Surface* conv = SDL_ConvertSurface(surface, &m_rgba_format, SDL_SWSURFACE|SDL_SRCALPHA); + GLImage* image = new GLImage(conv); + SDL_FreeSurface( surface ); + return image; + } + + Image* RenderBackendOpenGL::createImage(const uint8_t* data, unsigned int width, unsigned int height) { + return new GLImage(data, width, height); + } + + bool RenderBackendOpenGL::putPixel(int x, int y, int r, int g, int b) { + if ((x < 0) || (x >= (int)getWidth()) || (y < 0) || (y >= (int)getHeight())) { + return false; + } + glColor4ub(r, g, b, 255); + glBegin(GL_POINTS); + glVertex2i(x, y); + glEnd(); + std::cout << x << ", "<< y << "\n"; + return true; + } + + void RenderBackendOpenGL::drawLine(const Point& p1, const Point& p2, int r, int g, int b) { + glColor4ub(r, g, b, 255); + glBegin(GL_LINES); + glVertex3f(p1.x+0.5f, p1.y+0.5f, 0); + glVertex3f(p2.x+0.5f, p2.y+0.5f, 0); + glEnd(); + + glBegin(GL_POINTS); + glVertex3f(p2.x+0.5f, p2.y+0.5f, 0); + glEnd(); + } + + void RenderBackendOpenGL::drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4, int r, int g, int b) { + glColor4ub(r, g, b, 165); + glBegin(GL_QUADS); + glVertex3f(p1.x, p1.y, 0); + glVertex3f(p2.x, p2.y, 0); + glVertex3f(p3.x, p3.y, 0); + glVertex3f(p4.x, p4.y, 0); + glEnd(); + } + +}