2004-02-24 21:09:53 +00:00
|
|
|
// Residual - Virtual machine to run LucasArts' 3D adventure games
|
2005-01-01 10:23:18 +00:00
|
|
|
// Copyright (C) 2003-2005 The ScummVM-Residual Team (www.scummvm.org)
|
2004-02-24 21:09:53 +00:00
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2.1 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library 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
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
2005-01-01 12:27:57 +00:00
|
|
|
#include "debug.h"
|
2004-04-19 09:56:34 +00:00
|
|
|
#include "colormap.h"
|
|
|
|
#include "material.h"
|
2005-01-12 18:06:43 +00:00
|
|
|
#include "driver_gl.h"
|
2004-01-23 11:10:59 +00:00
|
|
|
|
2005-03-28 01:54:21 +00:00
|
|
|
// Constructor. Should create the driver and open screens, etc.
|
|
|
|
DriverGL::DriverGL(int screenW, int screenH, int screenBPP, bool fullscreen) {
|
2004-02-24 21:09:53 +00:00
|
|
|
char GLDriver[1024];
|
|
|
|
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
|
|
|
2005-04-08 10:17:31 +00:00
|
|
|
uint32 flags = SDL_OPENGL;
|
2005-03-28 01:54:21 +00:00
|
|
|
if (fullscreen)
|
|
|
|
flags |= SDL_FULLSCREEN;
|
|
|
|
if (SDL_SetVideoMode(screenW, screenH, screenBPP, flags) == 0)
|
2004-02-24 21:09:53 +00:00
|
|
|
error("Could not initialize video");
|
2005-03-28 01:54:21 +00:00
|
|
|
_screenWidth = screenW;
|
|
|
|
_screenHeight = screenH;
|
|
|
|
_screenBPP = screenBPP;
|
|
|
|
_isFullscreen = fullscreen;
|
2004-02-24 21:09:53 +00:00
|
|
|
|
|
|
|
sprintf(GLDriver, "Residual: %s/%s", glGetString(GL_VENDOR), glGetString(GL_RENDERER));
|
|
|
|
SDL_WM_SetCaption(GLDriver, "Residual");
|
|
|
|
|
2004-03-28 11:00:16 +00:00
|
|
|
// Load emergency built-in font
|
|
|
|
loadEmergFont();
|
2004-01-23 11:10:59 +00:00
|
|
|
|
2004-02-29 18:38:26 +00:00
|
|
|
_smushNumTex = 0;
|
|
|
|
}
|
2004-01-23 11:10:59 +00:00
|
|
|
|
2005-03-28 01:54:21 +00:00
|
|
|
void DriverGL::toggleFullscreenMode() {
|
2005-04-08 10:17:31 +00:00
|
|
|
warning("Switching on fly to Fullscreen mode is not allowed");
|
|
|
|
// switching to fullscreen mode it cause lost of texture
|
|
|
|
// and after that recreating
|
|
|
|
// for now it's not allowed
|
|
|
|
/*
|
|
|
|
uint32 flags = SDL_OPENGL;
|
|
|
|
if (!_isFullscreen)
|
2005-03-28 01:54:21 +00:00
|
|
|
flags |= SDL_FULLSCREEN;
|
|
|
|
if (SDL_SetVideoMode(_screenWidth, _screenHeight, _screenBPP, flags) == 0)
|
|
|
|
warning("Could not change fullscreen mode");
|
|
|
|
else
|
2005-04-08 10:17:31 +00:00
|
|
|
_isFullscreen = !_isFullscreen;
|
|
|
|
*/
|
2005-03-28 01:54:21 +00:00
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::setupCamera(float fov, float nclip, float fclip, float roll) {
|
2004-02-24 21:09:53 +00:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
2004-01-23 11:10:59 +00:00
|
|
|
|
2004-02-24 21:09:53 +00:00
|
|
|
float right = nclip * std::tan(fov / 2 * (M_PI / 180));
|
|
|
|
glFrustum(-right, right, -right * 0.75, right * 0.75, nclip, fclip);
|
2004-01-23 11:10:59 +00:00
|
|
|
|
2004-02-24 21:09:53 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
2004-01-23 11:10:59 +00:00
|
|
|
|
2004-02-24 21:09:53 +00:00
|
|
|
glRotatef(roll, 0, 0, -1);
|
2004-02-29 18:38:26 +00:00
|
|
|
}
|
2004-01-28 06:16:33 +00:00
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::positionCamera(Vector3d pos, Vector3d interest) {
|
2004-02-24 21:09:53 +00:00
|
|
|
Vector3d up_vec(0, 0, 1);
|
2004-01-23 11:10:59 +00:00
|
|
|
|
2004-02-24 21:09:53 +00:00
|
|
|
if (pos.x() == interest.x() && pos.y() == interest.y())
|
|
|
|
up_vec = Vector3d(0, 1, 0);
|
2004-01-23 11:10:59 +00:00
|
|
|
|
2005-01-10 09:07:46 +00:00
|
|
|
gluLookAt(pos.x(), pos.y(), pos.z(), interest.x(), interest.y(), interest.z(), up_vec.x(), up_vec.y(), up_vec.z());
|
2004-01-23 11:10:59 +00:00
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::clearScreen() {
|
2004-02-24 21:09:53 +00:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
2004-01-23 11:10:59 +00:00
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::flipBuffer() {
|
2004-02-24 21:09:53 +00:00
|
|
|
SDL_GL_SwapBuffers();
|
2004-01-23 11:10:59 +00:00
|
|
|
}
|
|
|
|
|
2005-04-07 20:06:27 +00:00
|
|
|
bool DriverGL::isHardwareAccelerated() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::startActorDraw(Vector3d pos, float yaw, float pitch, float roll) {
|
2004-04-19 09:56:34 +00:00
|
|
|
glEnable(GL_TEXTURE_2D);
|
2004-02-24 21:09:53 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
|
|
|
glTranslatef(pos.x(), pos.y(), pos.z());
|
|
|
|
glRotatef(yaw, 0, 0, 1);
|
|
|
|
glRotatef(pitch, 1, 0, 0);
|
|
|
|
glRotatef(roll, 0, 1, 0);
|
2004-01-23 11:10:59 +00:00
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::finishActorDraw() {
|
2004-02-24 21:09:53 +00:00
|
|
|
glPopMatrix();
|
2004-04-19 09:56:34 +00:00
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::set3DMode() {
|
2004-04-19 09:56:34 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2005-07-10 18:57:27 +00:00
|
|
|
glDepthFunc(GL_LESS);
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::drawModelFace(const Model::Face *face, float *vertices, float *vertNormals, float *textureVerts) {
|
2005-07-10 18:57:27 +00:00
|
|
|
// Support transparency in actor objects, such as the message tube
|
|
|
|
// in Manny's Office
|
|
|
|
glAlphaFunc(GL_GREATER, 0.5);
|
|
|
|
glEnable(GL_ALPHA_TEST);
|
2004-12-09 23:55:43 +00:00
|
|
|
glNormal3fv(face->_normal._coords);
|
2004-04-19 09:56:34 +00:00
|
|
|
glBegin(GL_POLYGON);
|
2004-12-09 23:55:43 +00:00
|
|
|
for (int i = 0; i < face->_numVertices; i++) {
|
|
|
|
glNormal3fv(vertNormals + 3 * face->_vertices[i]);
|
2005-01-10 09:09:42 +00:00
|
|
|
|
2005-01-18 17:28:02 +00:00
|
|
|
if (face->_texVertices != NULL)
|
|
|
|
glTexCoord2fv(textureVerts + 2 * face->_texVertices[i]);
|
2005-01-10 09:09:42 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
glVertex3fv(vertices + 3 * face->_vertices[i]);
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
|
|
|
glEnd();
|
2005-07-10 18:57:27 +00:00
|
|
|
// Done with transparency-capable objects
|
|
|
|
glDisable( GL_ALPHA_TEST );
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::drawHierachyNode(const Model::HierNode *node) {
|
2004-12-09 23:55:43 +00:00
|
|
|
if (node->_hierVisible) {
|
2004-04-19 09:56:34 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPushMatrix();
|
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
glTranslatef(node->_animPos.x() / node->_totalWeight, node->_animPos.y() / node->_totalWeight, node->_animPos.z() / node->_totalWeight);
|
|
|
|
glRotatef(node->_animYaw / node->_totalWeight, 0, 0, 1);
|
|
|
|
glRotatef(node->_animPitch / node->_totalWeight, 1, 0, 0);
|
|
|
|
glRotatef(node->_animRoll / node->_totalWeight, 0, 1, 0);
|
2004-04-19 09:56:34 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (node->_mesh != NULL && node->_meshVisible) {
|
2004-04-19 09:56:34 +00:00
|
|
|
glPushMatrix();
|
2004-12-09 23:55:43 +00:00
|
|
|
glTranslatef(node->_pivot.x(), node->_pivot.y(), node->_pivot.z());
|
|
|
|
node->_mesh->draw();
|
2004-04-19 09:56:34 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
|
|
|
}
|
2005-01-10 09:09:42 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (node->_child != NULL) {
|
|
|
|
node->_child->draw();
|
2004-04-19 09:56:34 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
}
|
|
|
|
glPopMatrix();
|
|
|
|
}
|
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
if (node->_sibling != NULL)
|
|
|
|
node->_sibling->draw();
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
|
|
|
|
2005-01-18 17:25:04 +00:00
|
|
|
void DriverGL::disableLights() {
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DriverGL::setupLight(Scene::Light *light, int lightId) {
|
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
float ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
|
|
|
|
float diffuseLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
|
|
|
float specularLight[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
|
|
float lightPos[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
|
|
float lightDir[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
|
|
lightPos[0] = light->_pos.x();
|
|
|
|
lightPos[1] = light->_pos.y();
|
|
|
|
lightPos[2] = light->_pos.z();
|
|
|
|
ambientLight[0] = (float)light->_color.red() / 256.0f;
|
|
|
|
ambientLight[1] = (float)light->_color.blue() / 256.0f;
|
|
|
|
ambientLight[2] = (float)light->_color.green() / 256.0f;
|
|
|
|
// diffuseLight[0] = (float)light->_intensity;
|
|
|
|
// diffuseLight[1] = (float)light->_intensity;
|
|
|
|
// diffuseLight[2] = (float)light->_intensity;
|
|
|
|
|
|
|
|
if (strcmp(light->_type.c_str(), "omni") == 0) {
|
|
|
|
// glLightfv(GL_LIGHT0 + lightId, GL_AMBIENT, ambientLight);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_DIFFUSE, diffuseLight);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_SPECULAR, specularLight);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_POSITION, lightPos);
|
|
|
|
// glLightf(GL_LIGHT0 + lightId, GL_SPOT_CUTOFF, 1.8f);
|
|
|
|
// glLightf(GL_LIGHT0 + lightId, GL_LINEAR_ATTENUATION, light->_intensity);
|
|
|
|
glEnable(GL_LIGHT0 + lightId);
|
|
|
|
} else if (strcmp(light->_type.c_str(), "direct") == 0) {
|
|
|
|
lightDir[0] = light->_dir.x();
|
|
|
|
lightDir[1] = light->_dir.y();
|
|
|
|
lightDir[2] = light->_dir.z();
|
|
|
|
lightDir[3] = 0.0f;
|
|
|
|
// glLightfv(GL_LIGHT0 + lightId, GL_AMBIENT, ambientLight);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_DIFFUSE, diffuseLight);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_SPECULAR, specularLight);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_POSITION, lightPos);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_SPOT_DIRECTION, lightDir);
|
|
|
|
// glLightf(GL_LIGHT0 + lightId, GL_SPOT_CUTOFF, 1.8f);
|
|
|
|
// glLightf(GL_LIGHT0 + lightId, GL_SPOT_EXPONENT, 2.0f);
|
2005-01-19 09:24:40 +00:00
|
|
|
// glLightf(GL_LIGHT0 + lightId, GL_LINEAR_ATTENUATION, light->_intensity);
|
|
|
|
glEnable(GL_LIGHT0 + lightId);
|
2005-01-26 19:25:29 +00:00
|
|
|
} else if (strcmp(light->_type.c_str(), "spot") == 0) {
|
2005-01-19 09:24:40 +00:00
|
|
|
lightDir[0] = light->_dir.x();
|
|
|
|
lightDir[1] = light->_dir.y();
|
|
|
|
lightDir[2] = light->_dir.z();
|
|
|
|
lightDir[3] = 0.0f;
|
|
|
|
// glLightfv(GL_LIGHT0 + lightId, GL_AMBIENT, ambientLight);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_DIFFUSE, diffuseLight);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_SPECULAR, specularLight);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_POSITION, lightPos);
|
|
|
|
glLightfv(GL_LIGHT0 + lightId, GL_SPOT_DIRECTION, lightDir);
|
|
|
|
// glLightf(GL_LIGHT0 + lightId, GL_SPOT_CUTOFF, 1.8f);
|
|
|
|
// glLightf(GL_LIGHT0 + lightId, GL_SPOT_EXPONENT, 2.0f);
|
2005-01-18 17:25:04 +00:00
|
|
|
// glLightf(GL_LIGHT0 + lightId, GL_LINEAR_ATTENUATION, light->_intensity);
|
|
|
|
glEnable(GL_LIGHT0 + lightId);
|
|
|
|
} else {
|
2005-02-26 21:54:21 +00:00
|
|
|
error("Scene::setupLights() Unknown type of light: %s", light->_type.c_str());
|
2005-01-18 17:25:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define BITMAP_TEXTURE_SIZE 256
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::createBitmap(Bitmap *bitmap) {
|
|
|
|
GLuint *textures;
|
2004-12-09 23:55:43 +00:00
|
|
|
if (bitmap->_format == 1) {
|
|
|
|
bitmap->_hasTransparency = false;
|
2004-12-10 07:26:03 +00:00
|
|
|
bitmap->_numTex = ((bitmap->_width + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE) *
|
2004-12-09 23:55:43 +00:00
|
|
|
((bitmap->_height + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE);
|
2004-12-10 07:26:03 +00:00
|
|
|
bitmap->_texIds = new GLuint[bitmap->_numTex * bitmap->_numImages];
|
2005-01-12 18:06:43 +00:00
|
|
|
textures = (GLuint *)bitmap->_texIds;
|
|
|
|
glGenTextures(bitmap->_numTex * bitmap->_numImages, textures);
|
2004-04-19 09:56:34 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
byte *texData = new byte[4 * bitmap->_width * bitmap->_height];
|
2004-04-19 09:56:34 +00:00
|
|
|
|
2004-12-10 07:26:03 +00:00
|
|
|
for (int pic = 0; pic < bitmap->_numImages; pic++) {
|
2004-04-19 09:56:34 +00:00
|
|
|
// Convert data to 32-bit RGBA format
|
2004-12-09 23:55:43 +00:00
|
|
|
byte *texDataPtr = texData;
|
|
|
|
uint16 *bitmapData = reinterpret_cast<uint16 *>(bitmap->_data[pic]);
|
|
|
|
for (int i = 0; i < bitmap->_width * bitmap->_height; i++, texDataPtr += 4, bitmapData++) {
|
2004-04-19 09:56:34 +00:00
|
|
|
uint16 pixel = *bitmapData;
|
|
|
|
int r = pixel >> 11;
|
|
|
|
texDataPtr[0] = (r << 3) | (r >> 2);
|
|
|
|
int g = (pixel >> 5) & 0x3f;
|
|
|
|
texDataPtr[1] = (g << 2) | (g >> 4);
|
|
|
|
int b = pixel & 0x1f;
|
|
|
|
texDataPtr[2] = (b << 3) | (b >> 2);
|
|
|
|
if (pixel == 0xf81f) { // transparent
|
|
|
|
texDataPtr[3] = 0;
|
2004-12-09 23:55:43 +00:00
|
|
|
bitmap->_hasTransparency = true;
|
2004-04-19 09:56:34 +00:00
|
|
|
} else {
|
|
|
|
texDataPtr[3] = 255;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-10 07:26:03 +00:00
|
|
|
for (int i = 0; i < bitmap->_numTex; i++) {
|
2005-01-12 18:06:43 +00:00
|
|
|
textures = (GLuint *)bitmap->_texIds;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textures[bitmap->_numTex * pic + i]);
|
2004-04-19 09:56:34 +00:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
2004-12-09 23:55:43 +00:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
|
|
|
|
2005-03-19 21:48:23 +00:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
2004-12-09 23:55:43 +00:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap->_width);
|
|
|
|
|
2004-12-10 07:26:03 +00:00
|
|
|
int cur_tex_idx = bitmap->_numTex * pic;
|
2004-12-09 23:55:43 +00:00
|
|
|
|
|
|
|
for (int y = 0; y < bitmap->_height; y += BITMAP_TEXTURE_SIZE) {
|
|
|
|
for (int x = 0; x < bitmap->_width; x += BITMAP_TEXTURE_SIZE) {
|
|
|
|
int width = (x + BITMAP_TEXTURE_SIZE >= bitmap->_width) ? (bitmap->_width - x) : BITMAP_TEXTURE_SIZE;
|
|
|
|
int height = (y + BITMAP_TEXTURE_SIZE >= bitmap->_height) ? (bitmap->_height - y) : BITMAP_TEXTURE_SIZE;
|
2005-01-12 18:06:43 +00:00
|
|
|
textures = (GLuint *)bitmap->_texIds;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textures[cur_tex_idx]);
|
2004-12-09 23:55:43 +00:00
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
|
|
|
|
texData + (y * 4 * bitmap->_width) + (4 * x));
|
2004-04-19 09:56:34 +00:00
|
|
|
cur_tex_idx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
delete [] texData;
|
|
|
|
} else {
|
2004-12-10 07:26:03 +00:00
|
|
|
for (int pic = 0; pic < bitmap->_numImages; pic++) {
|
2004-12-09 23:55:43 +00:00
|
|
|
uint16 *zbufPtr = reinterpret_cast<uint16 *>(bitmap->_data[pic]);
|
|
|
|
for (int i = 0; i < (bitmap->_width * bitmap->_height); i++) {
|
|
|
|
uint16 val = READ_LE_UINT16(bitmap->_data[pic] + 2 * i);
|
2004-04-19 09:56:34 +00:00
|
|
|
zbufPtr[i] = 0xffff - ((uint32) val) * 0x10000 / 100 / (0x10000 - val);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flip the zbuffer image to match what GL expects
|
2004-12-09 23:55:43 +00:00
|
|
|
for (int y = 0; y < bitmap->_height / 2; y++) {
|
|
|
|
uint16 *ptr1 = zbufPtr + y * bitmap->_width;
|
|
|
|
uint16 *ptr2 = zbufPtr + (bitmap->_height - 1 - y) * bitmap->_width;
|
|
|
|
for (int x = 0; x < bitmap->_width; x++, ptr1++, ptr2++) {
|
2004-04-19 09:56:34 +00:00
|
|
|
uint16 tmp = *ptr1;
|
|
|
|
*ptr1 = *ptr2;
|
|
|
|
*ptr2 = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-12-10 07:26:03 +00:00
|
|
|
bitmap->_texIds = NULL;
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::drawBitmap(const Bitmap *bitmap) {
|
|
|
|
GLuint *textures;
|
2004-04-19 09:56:34 +00:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
2005-03-28 01:54:21 +00:00
|
|
|
glOrtho(0, _screenWidth, _screenHeight, 0, 0, 1);
|
2004-04-19 09:56:34 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadIdentity();
|
|
|
|
// A lot more may need to be put there : disabling Alpha test, blending, ...
|
|
|
|
// For now, just keep this here :-)
|
2004-12-09 23:55:43 +00:00
|
|
|
if (bitmap->_format == 1 && bitmap->_hasTransparency) {
|
2004-04-19 09:56:34 +00:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
2004-12-09 23:55:43 +00:00
|
|
|
} else
|
2004-04-19 09:56:34 +00:00
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
2004-12-09 23:55:43 +00:00
|
|
|
if (bitmap->_format == 1) { // Normal image
|
2004-04-19 09:56:34 +00:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
glEnable(GL_SCISSOR_TEST);
|
2005-03-28 01:54:21 +00:00
|
|
|
glScissor(bitmap->_x, _screenHeight - (bitmap->_y + bitmap->_height), bitmap->_width, bitmap->_height);
|
2004-12-10 07:26:03 +00:00
|
|
|
int cur_tex_idx = bitmap->_numTex * (bitmap->_currImage - 1);
|
2004-12-09 23:55:43 +00:00
|
|
|
for (int y = bitmap->_y; y < (bitmap->_y + bitmap->_height); y += BITMAP_TEXTURE_SIZE) {
|
|
|
|
for (int x = bitmap->_x; x < (bitmap->_x + bitmap->_width); x += BITMAP_TEXTURE_SIZE) {
|
2005-01-12 18:06:43 +00:00
|
|
|
textures = (GLuint *)bitmap->_texIds;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textures[cur_tex_idx]);
|
2004-04-19 09:56:34 +00:00
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2f(0.0, 0.0);
|
|
|
|
glVertex2i(x, y);
|
|
|
|
glTexCoord2f(1.0, 0.0);
|
|
|
|
glVertex2i(x + BITMAP_TEXTURE_SIZE, y);
|
|
|
|
glTexCoord2f(1.0, 1.0);
|
|
|
|
glVertex2i(x + BITMAP_TEXTURE_SIZE, y + BITMAP_TEXTURE_SIZE);
|
|
|
|
glTexCoord2f(0.0, 1.0);
|
|
|
|
glVertex2i(x, y + BITMAP_TEXTURE_SIZE);
|
|
|
|
glEnd();
|
|
|
|
cur_tex_idx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glDisable(GL_SCISSOR_TEST);
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2004-12-09 23:55:43 +00:00
|
|
|
} else if (bitmap->_format == 5) { // ZBuffer image
|
2005-01-10 09:07:46 +00:00
|
|
|
// Only draw the manual zbuffer when enabled
|
2005-07-17 23:40:22 +00:00
|
|
|
if (ZBUFFER_GLOBAL) {
|
|
|
|
if (bitmap->_currImage - 1 < bitmap->_numImages) {
|
|
|
|
drawDepthBitmap(bitmap->_x, bitmap->_y, bitmap->_width, bitmap->_height, bitmap->_data[bitmap->_currImage - 1]);
|
|
|
|
} else {
|
|
|
|
warning("zbuffer image has index out of bounds! %d/%d\n", bitmap->_currImage, bitmap->_numImages);
|
|
|
|
}
|
|
|
|
}
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
2005-01-12 18:06:43 +00:00
|
|
|
glEnable(GL_LIGHTING);
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::destroyBitmap(Bitmap *bitmap) {
|
|
|
|
GLuint *textures;
|
|
|
|
textures = (GLuint *)bitmap->_texIds;
|
|
|
|
if (textures) {
|
|
|
|
glDeleteTextures(bitmap->_numTex * bitmap->_numImages, textures);
|
2005-01-12 23:28:47 +00:00
|
|
|
delete[] textures;
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::createMaterial(Material *material, const char *data, const CMap *cmap) {
|
2004-12-10 07:26:03 +00:00
|
|
|
material->_textures = new GLuint[material->_numImages];
|
2005-01-12 18:06:43 +00:00
|
|
|
GLuint *textures;
|
|
|
|
glGenTextures(material->_numImages, (GLuint *)material->_textures);
|
2004-12-09 23:55:43 +00:00
|
|
|
char *texdata = new char[material->_width * material->_height * 4];
|
2004-12-10 07:26:03 +00:00
|
|
|
for (int i = 0; i < material->_numImages; i++) {
|
2004-04-19 09:56:34 +00:00
|
|
|
char *texdatapos = texdata;
|
2004-12-09 23:55:43 +00:00
|
|
|
for (int y = 0; y < material->_height; y++) {
|
|
|
|
for (int x = 0; x < material->_width; x++) {
|
2004-04-19 09:56:34 +00:00
|
|
|
int col = *(uint8 *)(data);
|
|
|
|
if (col == 0)
|
|
|
|
memset(texdatapos, 0, 4); // transparent
|
|
|
|
else {
|
2004-12-09 23:55:43 +00:00
|
|
|
memcpy(texdatapos, cmap->_colors + 3 * (*(uint8 *)(data)), 3);
|
2004-04-19 09:56:34 +00:00
|
|
|
texdatapos[3] = '\xff'; // fully opaque
|
|
|
|
}
|
|
|
|
texdatapos += 4;
|
|
|
|
data++;
|
|
|
|
}
|
|
|
|
}
|
2005-01-12 18:06:43 +00:00
|
|
|
textures = (GLuint *)material->_textures;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textures[i]);
|
2004-04-19 09:56:34 +00:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
2004-12-09 23:55:43 +00:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, material->_width, material->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
|
2004-04-19 09:56:34 +00:00
|
|
|
data += 24;
|
|
|
|
}
|
|
|
|
delete[] texdata;
|
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::selectMaterial(const Material *material) {
|
|
|
|
GLuint *textures;
|
|
|
|
textures = (GLuint *)material->_textures;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textures[material->_currImage]);
|
2004-04-19 09:56:34 +00:00
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadIdentity();
|
2004-12-09 23:55:43 +00:00
|
|
|
glScalef(1.0f / material->_width, 1.0f / material->_height, 1);
|
2004-04-19 09:56:34 +00:00
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::destroyMaterial(Material *material) {
|
|
|
|
GLuint *textures;
|
|
|
|
textures = (GLuint *)material->_textures;
|
|
|
|
glDeleteTextures(material->_numImages, textures);
|
|
|
|
delete[] textures;
|
2004-01-23 11:10:59 +00:00
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::drawDepthBitmap(int x, int y, int w, int h, char *data) {
|
2004-03-23 10:38:02 +00:00
|
|
|
// if (num != 0) {
|
|
|
|
// warning("Animation not handled yet in GL texture path !\n");
|
|
|
|
// }
|
|
|
|
if (y + h == 480) {
|
2005-03-28 01:54:21 +00:00
|
|
|
glRasterPos2i(x, _screenHeight - 1);
|
2004-03-23 10:38:02 +00:00
|
|
|
glBitmap(0, 0, 0, 0, 0, -1, NULL);
|
2004-12-09 23:55:43 +00:00
|
|
|
} else
|
2004-03-23 10:38:02 +00:00
|
|
|
glRasterPos2i(x, y + h);
|
2004-02-24 21:09:53 +00:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glDepthFunc(GL_ALWAYS);
|
|
|
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
|
2004-03-23 10:38:02 +00:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
|
|
|
glDrawPixels(w, h, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
2004-02-24 21:09:53 +00:00
|
|
|
|
|
|
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
|
|
glDepthFunc(GL_LESS);
|
|
|
|
}
|
2004-01-23 11:10:59 +00:00
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::prepareSmushFrame(int width, int height, byte *bitmap) {
|
2004-02-29 18:38:26 +00:00
|
|
|
// remove if already exist
|
|
|
|
if (_smushNumTex > 0) {
|
|
|
|
glDeleteTextures(_smushNumTex, _smushTexIds);
|
|
|
|
delete[] _smushTexIds;
|
|
|
|
_smushNumTex = 0;
|
|
|
|
}
|
2004-02-24 21:09:53 +00:00
|
|
|
|
|
|
|
// create texture
|
2004-02-29 18:38:26 +00:00
|
|
|
_smushNumTex = ((width + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE) *
|
|
|
|
((height + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE);
|
|
|
|
_smushTexIds = new GLuint[_smushNumTex];
|
|
|
|
glGenTextures(_smushNumTex, _smushTexIds);
|
|
|
|
for (int i = 0; i < _smushNumTex; i++) {
|
|
|
|
glBindTexture(GL_TEXTURE_2D, _smushTexIds[i]);
|
2004-02-24 21:09:53 +00:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
2004-12-09 23:55:43 +00:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
|
2004-02-24 21:09:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
2004-02-29 18:38:26 +00:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
|
|
|
|
|
|
|
|
int curTexIdx = 0;
|
|
|
|
for (int y = 0; y < height; y += BITMAP_TEXTURE_SIZE) {
|
|
|
|
for (int x = 0; x < width; x += BITMAP_TEXTURE_SIZE) {
|
|
|
|
int t_width = (x + BITMAP_TEXTURE_SIZE >= width) ? (width - x) : BITMAP_TEXTURE_SIZE;
|
|
|
|
int t_height = (y + BITMAP_TEXTURE_SIZE >= height) ? (height - y) : BITMAP_TEXTURE_SIZE;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, _smushTexIds[curTexIdx]);
|
2004-12-09 23:55:43 +00:00
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, t_width, t_height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bitmap + (y * 2 * width) + (2 * x));
|
2004-02-29 18:38:26 +00:00
|
|
|
curTexIdx++;
|
2004-02-24 21:09:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
2004-02-29 18:38:26 +00:00
|
|
|
_smushWidth = width;
|
|
|
|
_smushHeight = height;
|
|
|
|
}
|
2004-02-24 21:09:53 +00:00
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::drawSmushFrame(int offsetX, int offsetY) {
|
2004-02-24 21:09:53 +00:00
|
|
|
// prepare view
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
2005-03-28 01:54:21 +00:00
|
|
|
glOrtho(0, _screenWidth, _screenHeight, 0, 0, 1);
|
2004-02-24 21:09:53 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadIdentity();
|
|
|
|
// A lot more may need to be put there : disabling Alpha test, blending, ...
|
|
|
|
// For now, just keep this here :-)
|
|
|
|
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
// draw
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
|
2005-03-28 01:54:21 +00:00
|
|
|
glScissor(offsetX, _screenHeight - (offsetY + _smushHeight), _smushWidth, _smushHeight);
|
2004-03-24 13:02:14 +00:00
|
|
|
|
2004-02-29 18:38:26 +00:00
|
|
|
int curTexIdx = 0;
|
|
|
|
for (int y = 0; y < _smushHeight; y += BITMAP_TEXTURE_SIZE) {
|
|
|
|
for (int x = 0; x < _smushWidth; x += BITMAP_TEXTURE_SIZE) {
|
|
|
|
glBindTexture(GL_TEXTURE_2D, _smushTexIds[curTexIdx]);
|
2004-02-24 21:09:53 +00:00
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2f(0, 0);
|
2004-03-20 07:45:34 +00:00
|
|
|
glVertex2i(x + offsetX, y + offsetY);
|
2004-02-24 21:09:53 +00:00
|
|
|
glTexCoord2f(1.0, 0.0);
|
2004-03-20 07:45:34 +00:00
|
|
|
glVertex2i(x + offsetX + BITMAP_TEXTURE_SIZE, y + offsetY);
|
2004-02-24 21:09:53 +00:00
|
|
|
glTexCoord2f(1.0, 1.0);
|
2004-03-20 07:45:34 +00:00
|
|
|
glVertex2i(x + offsetX + BITMAP_TEXTURE_SIZE, y + offsetY + BITMAP_TEXTURE_SIZE);
|
2004-02-24 21:09:53 +00:00
|
|
|
glTexCoord2f(0.0, 1.0);
|
2004-03-20 07:45:34 +00:00
|
|
|
glVertex2i(x + offsetX, y + offsetY + BITMAP_TEXTURE_SIZE);
|
2004-02-24 21:09:53 +00:00
|
|
|
glEnd();
|
2004-02-29 18:38:26 +00:00
|
|
|
curTexIdx++;
|
2004-02-24 21:09:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glDisable(GL_SCISSOR_TEST);
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2005-01-12 18:06:43 +00:00
|
|
|
glEnable(GL_LIGHTING);
|
2004-01-23 11:10:59 +00:00
|
|
|
}
|
2004-03-28 11:00:16 +00:00
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::loadEmergFont() {
|
2004-03-28 11:00:16 +00:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
_emergFont = glGenLists(128);
|
|
|
|
for (int i = 32; i < 127; i++) {
|
|
|
|
glNewList(_emergFont + i, GL_COMPILE);
|
2005-03-18 19:54:40 +00:00
|
|
|
glBitmap(8, 13, 0, 2, 10, 0, Font::emerFont[i - 32]);
|
2004-03-28 11:00:16 +00:00
|
|
|
glEndList();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
void DriverGL::drawEmergString(int x, int y, const char *text, const Color &fgColor) {
|
2004-04-19 09:56:34 +00:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPushMatrix();
|
|
|
|
glLoadIdentity();
|
2005-03-28 01:54:21 +00:00
|
|
|
glOrtho(0, _screenWidth, _screenHeight, 0, 0, 1);
|
2004-03-28 11:00:16 +00:00
|
|
|
|
2004-04-19 09:56:34 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
2004-03-28 11:00:16 +00:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
2005-01-12 18:06:43 +00:00
|
|
|
glDisable(GL_LIGHTING);
|
2004-03-28 11:00:16 +00:00
|
|
|
|
2004-04-19 09:56:34 +00:00
|
|
|
glColor3f(fgColor.red(), fgColor.green(), fgColor.blue());
|
|
|
|
glRasterPos2i(x, y);
|
2004-03-28 11:00:16 +00:00
|
|
|
|
2004-12-09 23:55:43 +00:00
|
|
|
glListBase(_emergFont);
|
2004-04-19 09:56:34 +00:00
|
|
|
//glCallLists(strlen(strrchr(text, '/')) - 1, GL_UNSIGNED_BYTE, strrchr(text, '/') + 1);
|
|
|
|
glCallLists(strlen(text), GL_UNSIGNED_BYTE, (GLubyte *) text);
|
2004-03-28 11:00:16 +00:00
|
|
|
|
2005-01-12 18:06:43 +00:00
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
|
2005-01-10 09:07:46 +00:00
|
|
|
glMatrixMode(GL_PROJECTION);
|
2004-04-19 09:56:34 +00:00
|
|
|
glPopMatrix();
|
2004-03-28 11:00:16 +00:00
|
|
|
}
|
2005-03-19 21:48:23 +00:00
|
|
|
|
2005-03-20 14:03:08 +00:00
|
|
|
Driver::TextObjectHandle *DriverGL::createTextBitmap(uint8 *data, int width, int height, const Color &fgColor) {
|
2005-03-20 18:43:56 +00:00
|
|
|
TextObjectHandle *handle = new TextObjectHandle;
|
2005-03-19 21:48:23 +00:00
|
|
|
handle->width = width;
|
|
|
|
handle->height = height;
|
|
|
|
handle->bitmapData = NULL;
|
|
|
|
handle->surface = NULL;
|
|
|
|
|
|
|
|
// create texture
|
|
|
|
handle->numTex = ((width + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE) *
|
|
|
|
((height + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE);
|
|
|
|
handle->texIds = (GLuint *)new GLuint[handle->numTex];
|
|
|
|
glGenTextures(handle->numTex, (GLuint *)handle->texIds);
|
|
|
|
|
|
|
|
// Convert data to 32-bit RGBA format
|
|
|
|
byte *texData = new byte[4 * width * height];
|
|
|
|
byte *texDataPtr = texData;
|
|
|
|
uint8 *bitmapData = data;
|
2005-04-05 04:33:56 +00:00
|
|
|
uint8 r = fgColor.red();
|
|
|
|
uint8 g = fgColor.green();
|
|
|
|
uint8 b = fgColor.blue();
|
|
|
|
|
2005-03-19 21:48:23 +00:00
|
|
|
for (int i = 0; i < width * height; i++, texDataPtr += 4, bitmapData++) {
|
|
|
|
byte pixel = *bitmapData;
|
|
|
|
if (pixel == 0x00) {
|
|
|
|
texDataPtr[0] = 0;
|
|
|
|
texDataPtr[1] = 0;
|
|
|
|
texDataPtr[2] = 0;
|
|
|
|
texDataPtr[3] = 0;
|
|
|
|
} else if (pixel == 0x80) {
|
|
|
|
texDataPtr[0] = 0;
|
|
|
|
texDataPtr[1] = 0;
|
|
|
|
texDataPtr[2] = 0;
|
|
|
|
texDataPtr[3] = 255;
|
|
|
|
} else if (pixel == 0xFF) {
|
2005-04-05 04:33:56 +00:00
|
|
|
texDataPtr[0] = r;
|
|
|
|
texDataPtr[1] = g;
|
|
|
|
texDataPtr[2] = b;
|
2005-03-19 21:48:23 +00:00
|
|
|
texDataPtr[3] = 255;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < handle->numTex; i++) {
|
|
|
|
glBindTexture(GL_TEXTURE_2D, ((GLuint *)handle->texIds)[i]);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
|
|
|
|
|
|
|
|
int curTexIdx = 0;
|
|
|
|
for (int y = 0; y < height; y += BITMAP_TEXTURE_SIZE) {
|
|
|
|
for (int x = 0; x < width; x += BITMAP_TEXTURE_SIZE) {
|
|
|
|
int t_width = (x + BITMAP_TEXTURE_SIZE >= width) ? (width - x) : BITMAP_TEXTURE_SIZE;
|
|
|
|
int t_height = (y + BITMAP_TEXTURE_SIZE >= height) ? (height - y) : BITMAP_TEXTURE_SIZE;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, ((GLuint *)handle->texIds)[curTexIdx]);
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, t_width, t_height, GL_RGBA, GL_UNSIGNED_BYTE, texData + (y * 4 * width) + (4 * x));
|
|
|
|
curTexIdx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
delete [] texData;
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
return handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DriverGL::drawTextBitmap(int x, int y, TextObjectHandle *handle) {
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
|
|
glOrtho(0, 640, 480, 0, 0, 1);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadIdentity();
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
glScissor(x, 480 - (y + handle->height), handle->width, handle->height);
|
|
|
|
int curTexIdx = 0;
|
|
|
|
for (int t_y = 0; t_y < handle->height; t_y += BITMAP_TEXTURE_SIZE) {
|
|
|
|
for (int t_x = 0; t_x < handle->width; t_x += BITMAP_TEXTURE_SIZE) {
|
|
|
|
GLuint *textures = (GLuint *)handle->texIds;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textures[curTexIdx]);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2f(0.0, 0.0);
|
|
|
|
glVertex2i(t_x + x, t_y + y);
|
|
|
|
glTexCoord2f(1.0, 0.0);
|
|
|
|
glVertex2i(t_x + x + BITMAP_TEXTURE_SIZE, y + t_y);
|
|
|
|
glTexCoord2f(1.0, 1.0);
|
|
|
|
glVertex2i(t_x + x + BITMAP_TEXTURE_SIZE, y + t_y + BITMAP_TEXTURE_SIZE);
|
|
|
|
glTexCoord2f(0.0, 1.0);
|
|
|
|
glVertex2i(t_x + x, t_y + y + BITMAP_TEXTURE_SIZE);
|
|
|
|
glEnd();
|
|
|
|
curTexIdx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glDisable(GL_SCISSOR_TEST);
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
}
|
2005-03-20 13:51:40 +00:00
|
|
|
|
|
|
|
void DriverGL::destroyTextBitmap(TextObjectHandle *handle) {
|
|
|
|
glDeleteTextures(handle->numTex, (GLuint *)handle->texIds);
|
2005-03-20 16:48:26 +00:00
|
|
|
delete[] (GLuint *)handle->texIds;
|
2005-03-20 13:51:40 +00:00
|
|
|
}
|
2005-04-07 07:04:36 +00:00
|
|
|
|
2005-08-10 08:33:45 +00:00
|
|
|
Bitmap *DriverGL::getScreenshot(int /*w*/, int /*h*/) {
|
2005-04-08 18:29:13 +00:00
|
|
|
return NULL;
|
2005-04-07 07:04:36 +00:00
|
|
|
}
|
|
|
|
|
2005-08-28 23:25:14 +00:00
|
|
|
void DriverGL::storeDisplay() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void DriverGL::copyStoredToDisplay() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void DriverGL::dimScreen() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void DriverGL::dimRegion(int x, int y, int w, int h, float level) {
|
2005-04-07 07:04:36 +00:00
|
|
|
}
|
2005-04-07 19:29:06 +00:00
|
|
|
|
|
|
|
void DriverGL::drawRectangle(PrimitiveObject *primitive) {
|
|
|
|
int x1 = primitive->getX1();
|
|
|
|
int x2 = primitive->getX2();
|
|
|
|
int y1 = primitive->getY1();
|
|
|
|
int y2 = primitive->getY2();
|
|
|
|
|
|
|
|
Color color = primitive->getColor();
|
|
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
|
|
glOrtho(0, 640, 480, 0, 0, 1);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
2005-04-08 10:17:31 +00:00
|
|
|
|
2005-04-07 19:29:06 +00:00
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
|
2005-04-08 10:17:31 +00:00
|
|
|
glColor3f(color.red() / 255.0f, color.green() / 255.0f, color.blue() / 255.0f);
|
|
|
|
|
2005-04-07 19:29:06 +00:00
|
|
|
if (primitive->isFilled()) {
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
} else {
|
2005-04-09 05:03:39 +00:00
|
|
|
glBegin(GL_LINE_LOOP);
|
2005-04-07 19:29:06 +00:00
|
|
|
}
|
|
|
|
|
2005-04-08 10:17:31 +00:00
|
|
|
glVertex2f(x1, y1);
|
|
|
|
glVertex2f(x2, y1);
|
|
|
|
glVertex2f(x2, y2);
|
|
|
|
glVertex2f(x1, y2);
|
2005-04-07 19:29:06 +00:00
|
|
|
glEnd();
|
|
|
|
|
2005-04-08 10:17:31 +00:00
|
|
|
glColor3f(1.0f, 1.0f, 1.0f);
|
|
|
|
|
2005-04-07 19:29:06 +00:00
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
}
|
2005-05-05 21:23:17 +00:00
|
|
|
|
|
|
|
void DriverGL::drawLine(PrimitiveObject *primitive) {
|
|
|
|
int x1 = primitive->getX1();
|
|
|
|
int x2 = primitive->getX2();
|
|
|
|
int y1 = primitive->getY1();
|
|
|
|
int y2 = primitive->getY2();
|
|
|
|
|
|
|
|
Color color = primitive->getColor();
|
|
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
|
|
glOrtho(0, 640, 480, 0, 0, 1);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
|
|
|
|
glColor3f(color.red() / 255.0f, color.green() / 255.0f, color.blue() / 255.0f);
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex2f(x1, y1);
|
|
|
|
glVertex2f(x2, y1);
|
|
|
|
glVertex2f(x2, y2);
|
|
|
|
glVertex2f(x1, y2);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glColor3f(1.0f, 1.0f, 1.0f);
|
|
|
|
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
}
|