ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

gfx_base.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 // Matrix calculations taken from the glm library
00024 // Which is covered by the MIT license
00025 // And has this additional copyright note:
00026 /* Copyright (c) 2005 - 2012 G-Truc Creation
00027  *
00028  * Permission is hereby granted, free of charge, to any person obtaining a copy
00029  * of this software and associated documentation files (the "Software"), to deal
00030  * in the Software without restriction, including without limitation the rights
00031  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00032  * copies of the Software, and to permit persons to whom the Software is
00033  * furnished to do so, subject to the following conditions:
00034  *
00035  * The above copyright notice and this permission notice shall be included in
00036  * all copies or substantial portions of the Software.
00037  */
00038 
00039 #include "engines/grim/gfx_base.h"
00040 #include "engines/grim/savegame.h"
00041 #include "engines/grim/bitmap.h"
00042 #include "engines/grim/grim.h"
00043 
00044 #include "engines/grim/model.h"
00045 
00046 namespace Grim {
00047 
00048 GfxBase::GfxBase() :
00049         _renderBitmaps(true), _renderZBitmaps(true), _shadowModeActive(false),
00050         _currentPos(0, 0, 0), _dimLevel(0.0f),
00051         _screenWidth(0), _screenHeight(0),
00052         _scaleW(1.0f), _scaleH(1.0f), _currentShadowArray(nullptr),
00053         _shadowColorR(255), _shadowColorG(255), _shadowColorB(255) {
00054             for (unsigned int i = 0; i < _numSpecialtyTextures; i++) {
00055                 _specialtyTextures[i]._isShared = true;
00056             }
00057 }
00058 
00059 void GfxBase::setShadowMode() {
00060     _shadowModeActive = true;
00061 }
00062 
00063 void GfxBase::clearShadowMode() {
00064     _shadowModeActive = false;
00065 }
00066 
00067 bool GfxBase::isShadowModeActive() {
00068     return _shadowModeActive;
00069 }
00070 
00071 void GfxBase::saveState(SaveGame *state) {
00072     state->beginSection('DRVR');
00073 
00074     byte r, g, b;
00075     getShadowColor(&r, &g, &b);
00076     state->writeByte(r);
00077     state->writeByte(g);
00078     state->writeByte(b);
00079     state->writeBool(_renderBitmaps);
00080     state->writeBool(_renderZBitmaps);
00081 
00082     state->endSection();
00083 }
00084 
00085 void GfxBase::restoreState(SaveGame *state) {
00086     state->beginSection('DRVR');
00087 
00088     byte r, g, b;
00089     r = state->readByte();
00090     g = state->readByte();
00091     b = state->readByte();
00092     setShadowColor(r, g , b);
00093     _renderBitmaps = state->readBool();
00094     _renderZBitmaps = state->readBool();
00095 
00096     state->endSection();
00097 }
00098 
00099 void GfxBase::renderBitmaps(bool render) {
00100     _renderBitmaps = render;
00101 }
00102 
00103 void GfxBase::renderZBitmaps(bool render) {
00104     _renderZBitmaps = render;
00105 }
00106 
00107 void GfxBase::drawMesh(const Mesh *mesh) {
00108     for (int i = 0; i < mesh->_numFaces; i++)
00109         mesh->_faces[i].draw(mesh);
00110 }
00111 
00112 #ifndef USE_OPENGL
00113 // Allow CreateGfxOpenGL to be called even if OpenGL isn't included
00114 GfxBase *CreateGfxOpenGL() {
00115     return CreateGfxTinyGL();
00116 }
00117 #endif // USE_OPENGL
00118 
00119 Math::Matrix4 GfxBase::makeLookMatrix(const Math::Vector3d& pos, const Math::Vector3d& interest, const Math::Vector3d& up) {
00120     Math::Vector3d f = (interest - pos).getNormalized();
00121     Math::Vector3d u = up.getNormalized();
00122     Math::Vector3d s = Math::Vector3d::crossProduct(f, u).getNormalized();
00123     u = Math::Vector3d::crossProduct(s, f);
00124 
00125     Math::Matrix4 look;
00126     look(0,0) = s.x();
00127     look(1,0) = s.y();
00128     look(2,0) = s.z();
00129     look(0,1) = u.x();
00130     look(1,1) = u.y();
00131     look(2,1) = u.z();
00132     look(0,2) = -f.x();
00133     look(1,2) = -f.y();
00134     look(2,2) = -f.z();
00135     look(3,0) = -Math::Vector3d::dotProduct(s, pos);
00136     look(3,1) = -Math::Vector3d::dotProduct(u, pos);
00137     look(3,2) =  Math::Vector3d::dotProduct(f, pos);
00138 
00139     look.transpose();
00140 
00141     return look;
00142 }
00143 
00144 Math::Matrix4 GfxBase::makeProjMatrix(float fov, float nclip, float fclip) {
00145     float right = nclip * tan(fov / 2 * (LOCAL_PI / 180));
00146     float left = -right;
00147     float top = right * 0.75;
00148     float bottom = -right * 0.75;
00149 
00150     Math::Matrix4 proj;
00151     proj(0,0) = (2.0f * nclip) / (right - left);
00152     proj(1,1) = (2.0f * nclip) / (top - bottom);
00153     proj(2,0) = (right + left) / (right - left);
00154     proj(2,1) = (top + bottom) / (top - bottom);
00155     proj(2,2) = -(fclip + nclip) / (fclip - nclip);
00156     proj(2,3) = -1.0f;
00157     proj(3,2) = -(2.0f * fclip * nclip) / (fclip - nclip);
00158     proj(3,3) = 0.0f;
00159 
00160     return proj;
00161 }
00162 
00163 
00164 void GfxBase::createSpecialtyTexture(uint id, const uint8 *data, int width, int height) {
00165     if (id >= _numSpecialtyTextures)
00166         return;
00167     if (_specialtyTextures[id]._texture) {
00168         destroyTexture(&_specialtyTextures[id]);
00169     }
00170     delete[] _specialtyTextures[id]._data;
00171     _specialtyTextures[id]._width = width;
00172     _specialtyTextures[id]._height = height;
00173     _specialtyTextures[id]._bpp = 4;
00174     _specialtyTextures[id]._colorFormat = BM_RGBA;
00175     createTexture(&_specialtyTextures[id], data, nullptr, true);
00176 }
00177 
00178 Bitmap *GfxBase::createScreenshotBitmap(const Graphics::PixelBuffer src, int w, int h, bool flipOrientation) {
00179         Graphics::PixelBuffer buffer = Graphics::PixelBuffer::createBuffer<565>(w * h, DisposeAfterUse::YES);
00180 
00181         int i1 = (_screenWidth * w - 1) / _screenWidth + 1;
00182         int j1 = (_screenHeight * h - 1) / _screenHeight + 1;
00183 
00184         for (int j = 0; j < j1; j++) {
00185                 for (int i = 0; i < i1; i++) {
00186                         int x0 = i * _screenWidth / w;
00187                         int x1 = ((i + 1) * _screenWidth - 1) / w + 1;
00188                         int y0 = j * _screenHeight / h;
00189                         int y1 = ((j + 1) * _screenHeight - 1) / h + 1;
00190                         uint16 sr = 0, sg = 0, sb = 0;
00191                         for (int y = y0; y < y1; y++) {
00192                                 for (int x = x0; x < x1; x++) {
00193                                         uint8 r, g, b;
00194                                         src.getRGBAt(y * _screenWidth + x, r, g, b);
00195                                         sr += r;
00196                                         sg += g;
00197                                         sb += b;
00198                                 }
00199                         }
00200                         sr /= (x1 - x0) * (y1 - y0);
00201                         sg /= (x1 - x0) * (y1 - y0);
00202                         sb /= (x1 - x0) * (y1 - y0);
00203                         if (g_grim->getGameType() == GType_MONKEY4) {
00204                                 buffer.setPixelAt( (flipOrientation ? j : (h - j - 1) ) * w + i, sr, sg, sb);
00205                         } else {
00206                                 uint32 color = (sr + sg + sb) / 3;
00207                                 buffer.setPixelAt( (flipOrientation ? j : (h - j - 1) ) * w + i, color, color, color);
00208                         }
00209                 }
00210         }
00211 
00212         Bitmap *screenshot = new Bitmap(buffer, w, h, "screenshot");
00213         return screenshot;
00214 }
00215 
00216 void GfxBase::makeScreenTextures() {
00217     //make a buffer big enough to hold any of the textures
00218     uint8 *buffer = new uint8[256 * 256 * 4];
00219 
00220     // TODO: Handle screen resolutions other than 640 x 480
00221     createSpecialtyTextureFromScreen(0, buffer, 0, 0, 256, 256);
00222     createSpecialtyTextureFromScreen(1, buffer, 256, 0, 256, 256);
00223     createSpecialtyTextureFromScreen(2, buffer, 512, 0, 128, 128);
00224     createSpecialtyTextureFromScreen(3, buffer, 512, 128, 128, 128);
00225     createSpecialtyTextureFromScreen(4, buffer, 0, 256, 256, 256);
00226     createSpecialtyTextureFromScreen(5, buffer, 256, 256, 256, 256);
00227     createSpecialtyTextureFromScreen(6, buffer, 512, 256, 128, 128);
00228     createSpecialtyTextureFromScreen(7, buffer, 512, 384, 128, 128);
00229 
00230     delete[] buffer;
00231 }
00232 
00233 Texture *GfxBase::getSpecialtyTexturePtr(Common::String name) {
00234     assert(name.hasPrefix("specialty"));
00235     name.erase(0, 9);
00236     unsigned int id;
00237     sscanf(name.c_str(), "%u", &id);
00238     if (id >= _numSpecialtyTextures) {
00239         return nullptr;
00240     }
00241     return &_specialtyTextures[id];
00242 }
00243 
00244 }


Generated on Sat Apr 20 2019 05:02:42 for ResidualVM by doxygen 1.7.1
curved edge   curved edge