OpenGTA/gl_screen.cpp

186 lines
5.9 KiB
C++
Raw Normal View History

2015-12-03 00:37:02 +00:00
/************************************************************************
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
* *
* This software is provided as-is, without any express or implied *
* warranty. In no event will the authors be held liable for any *
* damages arising from the use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute *
* it freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must *
* not claim that you wrote the original software. If you use this *
* software in a product, an acknowledgment in the product documentation *
* would be appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must *
* not be misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source *
* distribution. *
************************************************************************/
#include <string>
#include "gl_screen.h"
#include "log.h"
#include "buffercache.h"
#include "m_exceptions.h"
namespace OpenGL {
#ifndef DEFAULT_SCREEN_WIDTH
#define DEFAULT_SCREEN_WIDTH 640
#endif
#ifndef DEFAULT_SCREEN_HEIGHT
#define DEFAULT_SCREEN_HEIGHT 480
#endif
Screen::Screen() {
surface = NULL;
videoFlags = defaultVideoFlags;
width = DEFAULT_SCREEN_WIDTH;
height = DEFAULT_SCREEN_HEIGHT;
bpp = 32;
fieldOfView = 60.0f;
nearPlane = 0.1f;
farPlane = 250.0f;
}
void Screen::activate(Uint32 w, Uint32 h) {
if (w)
width = w;
if (h)
height = h;
initSDL();
resize(width, height);
initGL();
setSystemMouseCursor(false);
}
void Screen::setSystemMouseCursor(bool visible) {
SDL_ShowCursor((visible ? SDL_ENABLE : SDL_DISABLE));
}
Uint32 Screen::getWidth() {
return width;
}
Uint32 Screen::getHeight() {
return height;
}
bool Screen::getFullscreen() {
return (videoFlags & SDL_FULLSCREEN);
}
void Screen::setFullScreenFlag(bool v) {
if (v && getFullscreen())
return;
else if (!v && !getFullscreen())
return;
if (v)
videoFlags |= SDL_FULLSCREEN;
else
videoFlags ^= SDL_FULLSCREEN;
}
Screen::~Screen() {
setSystemMouseCursor(true);
if (SDL_WasInit(SDL_INIT_VIDEO))
SDL_Quit();
surface = NULL;
}
void Screen::toggleFullscreen() {
if (videoFlags & SDL_FULLSCREEN)
videoFlags ^= SDL_FULLSCREEN;
else
videoFlags |= SDL_FULLSCREEN;
resize(width, height);
}
void Screen::initSDL() {
int err = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
if (err)
//throw "SDL_Init failed: " + std::string(SDL_GetError());
throw E_INVALIDFORMAT("SDL_Init failed: " + std::string(SDL_GetError()));
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1);
}
void Screen::initGL() {
//GLfloat LightAmbient[] = { 0.8f, 0.8f, 0.8f, 1.0f };
//GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
//GLfloat LightPosition[] = { 128.0f, 200.0f, 128.0f, 1.0f };
//glShadeModel( GL_SMOOTH );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glEnable( GL_DEPTH_TEST );
//glEnable( GL_LIGHTING );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
//glLightfv( GL_LIGHT0, GL_AMBIENT, LightAmbient );
//glLightfv( GL_LIGHT0, GL_DIFFUSE, LightDiffuse );
//glLightfv( GL_LIGHT0, GL_POSITION, LightPosition );
//glEnable( GL_LIGHT0 );
glEnable( GL_COLOR_MATERIAL);
glCullFace(GL_BACK);
//glPolygonMode(GL_FRONT, GL_FILL);
//glPolygonMode(GL_BACK, GL_LINE);
}
void Screen::resize(Uint32 w, Uint32 h) {
if (h == 0)
h = 1;
surface = SDL_SetVideoMode(w, h, bpp, videoFlags);
glViewport(0, 0, w, h);
width = w;
height = h;
}
void Screen::set3DProjection() {
float ratio = float(width) / float(height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( fieldOfView, ratio, nearPlane, farPlane);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Screen::setFlatProjection() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Screen::makeScreenshot(const char* filename) {
INFO << "saving screen as: " << filename << std::endl;
uint8_t *pixels = Util::BufferCacheHolder::Instance().requestBuffer(width * height * 3);
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(pixels));
SDL_Surface* image = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24,
255U << (0),
255U << (8),
255U << (16),
0);
SDL_LockSurface(image);
uint8_t *imagepixels = reinterpret_cast<uint8_t*>(image->pixels);
for (int y = (height - 1); y >= 0; --y) {
uint8_t *row_begin = pixels + y * width * 3;
uint8_t *row_end = row_begin + width * 3;
std::copy(row_begin, row_end, imagepixels);
imagepixels += image->pitch;
}
SDL_UnlockSurface(image);
SDL_SaveBMP(image, filename);
SDL_FreeSurface( image );
}
}