/* * mogltk * Copyright (C) 1999-2004 Nicolas "Pixel" Noble * * This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: glbase.cc,v 1.21 2004-10-19 01:27:30 pixel Exp $ */ #include #include #include #include #include #include "glbase.h" #include "engine.h" #include "generic.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif mogltk::glbase::glbase(int w, int h, int flags) throw (GeneralException) : mogltk::base(w, h, flags, 0), twoD(0), fovy(60.0) { SDL_Surface * surface; GLint bits; mogltk::engine::setup(); if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { throw GeneralException(String("Couldn't initialise Video SubSystem: ") + SDL_GetError()); } #if 1 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, 32); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8); #endif if (!(surface = SDL_SetVideoMode(w, h, 0, flags | SDL_OPENGL | SDL_HWSURFACE))) { throw GeneralException(String("Couldn't set GL mode: ") + SDL_GetError()); } mogltk::engine::glbase_o = this; mogltk::engine::base_o = this; ratio = (GLdouble) surface->w / surface->h; glGetIntegerv(GL_STENCIL_BITS, &bits); printm(M_INFO, "Video resolution: %dx%dx%d (ratio = %3.2f)\n", surface->w, surface->h, surface->format->BitsPerPixel, ratio); printm(M_INFO, "\n"); printm(M_INFO, "OpenGL infos\n"); printm(M_INFO, "------------\n"); printm(M_INFO, String("Vendor : ") + (char *) glGetString(GL_VENDOR) + "\n"); printm(M_INFO, String("Renderer : ") + (char *) glGetString(GL_RENDERER) + "\n"); printm(M_INFO, String("Version : ") + (char *) glGetString(GL_VERSION) + "\n"); printm(M_INFO, String("Extensions: ") + (char *) glGetString(GL_EXTENSIONS) + "\n"); glViewport(0, 0, surface->w, surface->h); glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glClearColor(0, 0, 0, 0); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(fovy, ratio, 1.0, 1024.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapBuffers(); SDL_ShowCursor(SDL_DISABLE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); setsurface(surface); mogltk::engine::postsetup(); } mogltk::glbase::~glbase() { } void mogltk::glbase::Enter2DMode(void) { if (twoD) return; glPushAttrib(GL_ENABLE_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0.0, GetWidth(), GetHeight(), 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); twoD = 1; } void mogltk::glbase::Leave2DMode(void) { if (!twoD) return; glMatrixMode(GL_MODELVIEW); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); twoD = 0; } void mogltk::glbase::Flip(bool clear) { mogltk::engine::pollevents(); SDL_GL_SwapBuffers(); if (clear) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } bool mogltk::glbase::is2D() { return twoD; } void mogltk::glbase::glVertex(GLshort x, GLshort y, GLshort z, GLshort w) { #ifdef DEBUG printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (shorts)\n", x, y, z, w); #endif glVertex4i(x, y, z, w); } void mogltk::glbase::glVertex(GLint x, GLint y, GLint z, GLint w) { #ifdef DEBUG printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (ints)\n", x, y, z, w); #endif glVertex4i(x, y, z, w); } void mogltk::glbase::glVertex(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { #ifdef DEBUG printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (floats)\n", x, y, z, w); #endif glVertex4f(x, y, z, w); } void mogltk::glbase::glVertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { #ifdef DEBUG printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (doubles)\n", x, y, z, w); #endif glVertex4d(x, y, z, w); } void mogltk::glbase::changeviewport(int x, int y, unsigned int w, unsigned int h) { #if 0 if ((w == 0) && (h == 0)) { w = GetWidth() - x; h = GetHeight() - y; } ratio = (GLdouble) w / h; glViewport(x, y, w, h); if (!engine::base_o->is2D()) gluPerspective(fovy, ratio, 1.0, 1024.0); #endif glScissor(x, GetHeight() - y - h - 1, w + 1, h + 1); glEnable(GL_SCISSOR_TEST); } void mogltk::glbase::changefovy(GLdouble nfoyv) { fovy = nfoyv; if (!engine::base_o->is2D()) gluPerspective(fovy, ratio, 1.0, 1024.0); } inline static unsigned int nextpower(unsigned int n) { unsigned int i; if (!n) return n; if (ISPOT(n)) return n; for (i = 31; i >= 0; i--) { if ((n >> i) & 1) { return 1 << (i + 1); } } } mogltk::texture * mogltk::glbase::GrabTexture() { int w = nextpower(GetWidth()); int h = nextpower(GetHeight()); texture * r = new texture(w, h); SDL_Surface * t; t = GrabSurface(); SDL_BlitSurface(t, NULL, r->GetSurface(), NULL); SDL_FreeSurface(t); return r; } SDL_Surface * mogltk::glbase::GrabSurface() { int i; SDL_Surface * r; Uint8 * pixels = (Uint8 *) malloc(GetWidth() * GetHeight() * 3); Uint8 * s, * d; glReadPixels(0, 0, GetWidth(), GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, pixels); r = SDL_CreateRGBSurface(SDL_SWSURFACE, GetWidth(), GetHeight(), 24, #if SDL_BYTEORDER == SDL_BIG_ENDIAN 0xff000000, 0x00ff0000, 0x0000ff00, 0x00000000 #else 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 #endif ); for (i = 0; i < GetHeight(); i++) { s = pixels + i * GetWidth() * 3; d = ((Uint8 *) r->pixels) + (GetHeight() - i - 1) * GetWidth() * 3; memcpy(d, s, GetWidth() * 3); } free(pixels); return r; }