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

myst3/gfx_tinygl.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 AUTHORS
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 #if defined(WIN32)
00024 #include <windows.h>
00025 // winnt.h defines ARRAYSIZE, but we want our own one...
00026 #undef ARRAYSIZE
00027 #endif
00028 
00029 #include "common/config-manager.h"
00030 #include "common/rect.h"
00031 #include "common/textconsole.h"
00032 
00033 #include "graphics/colormasks.h"
00034 #include "graphics/surface.h"
00035 
00036 #include "math/vector2d.h"
00037 #include "math/glmath.h"
00038 
00039 #include "engines/myst3/gfx.h"
00040 #include "engines/myst3/gfx_tinygl.h"
00041 #include "engines/myst3/gfx_tinygl_texture.h"
00042 #include "graphics/tinygl/zblit.h"
00043 
00044 namespace Myst3 {
00045 
00046 Renderer *CreateGfxTinyGL(OSystem *system) {
00047     return new TinyGLRenderer(system);
00048 }
00049 
00050 TinyGLRenderer::TinyGLRenderer(OSystem *system) :
00051         Renderer(system),
00052         _fb(NULL) {
00053 }
00054 
00055 TinyGLRenderer::~TinyGLRenderer() {
00056 }
00057 
00058 Texture *TinyGLRenderer::createTexture(const Graphics::Surface *surface) {
00059     return new TinyGLTexture(surface);
00060 }
00061 
00062 void TinyGLRenderer::freeTexture(Texture *texture) {
00063     TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
00064     delete glTexture;
00065 }
00066 
00067 void TinyGLRenderer::init() {
00068     debug("Initializing Software 3D Renderer");
00069 
00070     computeScreenViewport();
00071 
00072     Graphics::PixelBuffer screenBuffer = _system->getScreenPixelBuffer();
00073     _fb = new TinyGL::FrameBuffer(kOriginalWidth, kOriginalHeight, screenBuffer);
00074     TinyGL::glInit(_fb, 512);
00075     tglEnableDirtyRects(ConfMan.getBool("dirtyrects"));
00076 
00077     tglMatrixMode(TGL_PROJECTION);
00078     tglLoadIdentity();
00079 
00080     tglMatrixMode(TGL_MODELVIEW);
00081     tglLoadIdentity();
00082 
00083     tglDisable(TGL_LIGHTING);
00084     tglEnable(TGL_TEXTURE_2D);
00085     tglEnable(TGL_DEPTH_TEST);
00086 }
00087 
00088 void TinyGLRenderer::clear() {
00089     tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
00090     tglColor3f(1.0f, 1.0f, 1.0f);
00091 }
00092 
00093 void TinyGLRenderer::selectTargetWindow(Window *window, bool is3D, bool scaled) {
00094     // NOTE: tinyGL viewport implementation needs to be checked as it doesn't behave the same as openGL
00095 
00096     if (!window) {
00097         // No window found ...
00098         if (scaled) {
00099             // ... in scaled mode draw in the original game screen area
00100             Common::Rect vp = viewport();
00101             tglViewport(vp.left, vp.top, vp.width(), vp.height());
00102             //tglViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
00103         } else {
00104             // ... otherwise, draw on the whole screen
00105             tglViewport(0, 0, _system->getWidth(), _system->getHeight());
00106         }
00107     } else {
00108         // Found a window, draw inside it
00109         Common::Rect vp = window->getPosition();
00110         tglViewport(vp.left, vp.top, vp.width(), vp.height());
00111         //tglViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
00112     }
00113 
00114     if (is3D) {
00115         tglMatrixMode(TGL_PROJECTION);
00116         tglLoadMatrixf(_projectionMatrix.getData());
00117 
00118         tglMatrixMode(TGL_MODELVIEW);
00119         tglLoadMatrixf(_modelViewMatrix.getData());
00120     } else {
00121         tglMatrixMode(TGL_PROJECTION);
00122         tglLoadIdentity();
00123 
00124         if (!window) {
00125             if (scaled) {
00126                 tglOrtho(0.0, kOriginalWidth, kOriginalHeight, 0.0, -1.0, 1.0);
00127             } else {
00128                 tglOrtho(0.0, _system->getWidth(), _system->getHeight(), 0.0, -1.0, 1.0);
00129             }
00130         } else {
00131             if (scaled) {
00132                 Common::Rect originalRect = window->getOriginalPosition();
00133                 tglOrtho(0.0, originalRect.width(), originalRect.height(), 0.0, -1.0, 1.0);
00134             } else {
00135                 Common::Rect vp = window->getPosition();
00136                 tglOrtho(0.0, vp.width(), vp.height(), 0.0, -1.0, 1.0);
00137             }
00138         }
00139 
00140         tglMatrixMode(TGL_MODELVIEW);
00141         tglLoadIdentity();
00142     }
00143 }
00144 
00145 void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint32 color) {
00146     uint8 a, r, g, b;
00147     Graphics::colorToARGB< Graphics::ColorMasks<8888> >(color, a, r, g, b);
00148 
00149     tglDisable(TGL_TEXTURE_2D);
00150     tglColor4f(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
00151 
00152     if (a != 255) {
00153         tglEnable(TGL_BLEND);
00154         tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
00155     }
00156 
00157     tglBegin(TGL_TRIANGLE_STRIP);
00158         tglVertex3f(rect.left, rect.bottom, 0.0f);
00159         tglVertex3f(rect.right, rect.bottom, 0.0f);
00160         tglVertex3f(rect.left, rect.top, 0.0f);
00161         tglVertex3f(rect.right, rect.top, 0.0f);
00162     tglEnd();
00163 
00164     tglDisable(TGL_BLEND);
00165 }
00166 
00167 void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect,
00168         Texture *texture, float transparency, bool additiveBlending) {
00169     const float sLeft = screenRect.left;
00170     const float sTop = screenRect.top;
00171     const float sWidth = screenRect.width();
00172     const float sHeight = screenRect.height();
00173 
00174     if (transparency >= 0.0) {
00175         if (additiveBlending) {
00176             tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE);
00177         } else {
00178             tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
00179         }
00180         tglEnable(TGL_BLEND);
00181     } else {
00182         transparency = 1.0;
00183     }
00184 
00185     // HACK: tglBlit is not affected by the viewport, so we offset the draw coordinates here
00186     int viewPort[4];
00187     tglGetIntegerv(TGL_VIEWPORT, viewPort);
00188 
00189     tglEnable(TGL_TEXTURE_2D);
00190     tglDepthMask(TGL_FALSE);
00191 
00192     Graphics::BlitTransform transform(sLeft + viewPort[0], sTop + viewPort[1]);
00193     transform.sourceRectangle(textureRect.left, textureRect.top, sWidth, sHeight);
00194     transform.tint(transparency);
00195     tglBlit(((TinyGLTexture *)texture)->getBlitTexture(), transform);
00196 
00197     tglDisable(TGL_BLEND);
00198     tglDepthMask(TGL_TRUE);
00199 }
00200 
00201 void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point &position) {
00202     TinyGLTexture *glFont = static_cast<TinyGLTexture *>(_font);
00203 
00204     // The font only has uppercase letters
00205     Common::String textToDraw = text;
00206     textToDraw.toUppercase();
00207 
00208     tglEnable(TGL_BLEND);
00209     tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
00210 
00211     tglEnable(TGL_TEXTURE_2D);
00212     tglDepthMask(TGL_FALSE);
00213 
00214     tglColor3f(1.0f, 1.0f, 1.0f);
00215     tglBindTexture(TGL_TEXTURE_2D, glFont->id);
00216 
00217     int x = position.x;
00218     int y = position.y;
00219 
00220     for (uint i = 0; i < textToDraw.size(); i++) {
00221         Common::Rect textureRect = getFontCharacterRect(textToDraw[i]);
00222         int w = textureRect.width();
00223         int h = textureRect.height();
00224 
00225         Graphics::BlitTransform transform(x, y);
00226         transform.sourceRectangle(textureRect.left, textureRect.top, w, h);
00227         transform.flip(true, false);
00228         Graphics::tglBlit(glFont->getBlitTexture(), transform);
00229 
00230         x += textureRect.width() - 3;
00231     }
00232 
00233     tglDisable(TGL_TEXTURE_2D);
00234     tglDisable(TGL_BLEND);
00235     tglDepthMask(TGL_TRUE);
00236 }
00237 
00238 void TinyGLRenderer::drawFace(uint face, Texture *texture) {
00239     TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
00240 
00241     tglBindTexture(TGL_TEXTURE_2D, glTexture->id);
00242     tglBegin(TGL_TRIANGLE_STRIP);
00243     for (uint i = 0; i < 4; i++) {
00244         tglTexCoord2f(cubeVertices[5 * (4 * face + i) + 0], cubeVertices[5 * (4 * face + i) + 1]);
00245         tglVertex3f(cubeVertices[5 * (4 * face + i) + 2], cubeVertices[5 * (4 * face + i) + 3], cubeVertices[5 * (4 * face + i) + 4]);
00246     }
00247     tglEnd();
00248 }
00249 
00250 void TinyGLRenderer::drawCube(Texture **textures) {
00251     tglEnable(TGL_TEXTURE_2D);
00252     tglDepthMask(TGL_FALSE);
00253 
00254     for (uint i = 0; i < 6; i++) {
00255         drawFace(i, textures[i]);
00256     }
00257 
00258     tglDepthMask(TGL_TRUE);
00259 }
00260 
00261 void TinyGLRenderer::drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vector3d &bottomLeft,
00262         const Math::Vector3d &topRight, const Math::Vector3d &bottomRight, Texture *texture) {
00263 
00264     TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
00265 
00266     tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
00267     tglEnable(TGL_BLEND);
00268     tglDepthMask(TGL_FALSE);
00269 
00270     tglBindTexture(TGL_TEXTURE_2D, glTexture->id);
00271 
00272     tglBegin(TGL_TRIANGLE_STRIP);
00273         tglTexCoord2f(0, 0);
00274         tglVertex3f(-topLeft.x(), topLeft.y(), topLeft.z());
00275 
00276         tglTexCoord2f(0, 1);
00277         tglVertex3f(-bottomLeft.x(), bottomLeft.y(), bottomLeft.z());
00278 
00279         tglTexCoord2f(1, 0);
00280         tglVertex3f(-topRight.x(), topRight.y(), topRight.z());
00281 
00282         tglTexCoord2f(1, 1);
00283         tglVertex3f(-bottomRight.x(), bottomRight.y(), bottomRight.z());
00284     tglEnd();
00285 
00286     tglDisable(TGL_BLEND);
00287     tglDepthMask(TGL_TRUE);
00288 }
00289 
00290 Graphics::Surface *TinyGLRenderer::getScreenshot() {
00291     Graphics::Surface *s = new Graphics::Surface();
00292     s->create(kOriginalWidth, kOriginalHeight, Texture::getRGBAPixelFormat());
00293     Graphics::PixelBuffer buf(s->format, (byte *)s->getPixels());
00294     _fb->copyToBuffer(buf);
00295     return s;
00296 }
00297 
00298 void TinyGLRenderer::flipBuffer() {
00299     TinyGL::tglPresentBuffer();
00300 }
00301 
00302 } // End of namespace Myst3


Generated on Sat Mar 16 2019 05:01:34 for ResidualVM by doxygen 1.7.1
curved edge   curved edge