diff --git a/engines/myst3/gfx_tinygl.cpp b/engines/myst3/gfx_tinygl.cpp index 186a2124a19..35897ddb60b 100644 --- a/engines/myst3/gfx_tinygl.cpp +++ b/engines/myst3/gfx_tinygl.cpp @@ -152,7 +152,6 @@ void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint32 color) { void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture, float transparency) { - TinyGLTexture *glTexture = static_cast(texture); const float tLeft = textureRect.left / (float) glTexture->internalWidth; @@ -173,23 +172,9 @@ void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Co } tglEnable(TGL_TEXTURE_2D); - tglColor4f(1.0f, 1.0f, 1.0f, transparency); tglDepthMask(TGL_FALSE); - tglBindTexture(TGL_TEXTURE_2D, glTexture->id); - tglBegin(TGL_TRIANGLE_STRIP); - tglTexCoord2f(tLeft, tTop + tHeight); - tglVertex3f(sLeft + 0, sTop + sHeight, 1.0f); - - tglTexCoord2f(tLeft + tWidth, tTop + tHeight); - tglVertex3f(sLeft + sWidth, sTop + sHeight, 1.0f); - - tglTexCoord2f(tLeft, tTop); - tglVertex3f(sLeft + 0, sTop + 0, 1.0f); - - tglTexCoord2f(tLeft + tWidth, tTop); - tglVertex3f(sLeft + sWidth, sTop + 0, 1.0f); - tglEnd(); + blitScreen((TinyGLTexture *)texture, sLeft, sTop, textureRect.left, textureRect.top, sWidth, sHeight, transparency); tglDisable(TGL_BLEND); tglDepthMask(TGL_TRUE); @@ -224,16 +209,7 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point float cx = textureRect.left / (float) glFont->internalWidth; float cy = textureRect.top / (float) glFont->internalHeight; - tglBegin(TGL_QUADS); - tglTexCoord2f(cx, cy + ch); - tglVertex3f(x, y, 1.0f); - tglTexCoord2f(cx + cw, cy + ch); - tglVertex3f(x + w, y, 1.0f); - tglTexCoord2f(cx + cw, cy); - tglVertex3f(x + w, y + h, 1.0f); - tglTexCoord2f(cx, cy); - tglVertex3f(x, y + h, 1.0f); - tglEnd(); + blitScreen(glFont, x, y, textureRect.left, textureRect.top, w, h, 1.0f, true); x += textureRect.width() - 3; } @@ -366,6 +342,56 @@ void TinyGLRenderer::screenPosToDirection(const Common::Point screen, float &pit heading = 360 - heading; } +void TinyGLRenderer::blitScreen(Texture *texture, int dstX, int dstY, int srcX, int srcY, int width, int height, float transparency, bool invertY) { + int screenWidth = 640; + int screenHeight = 480; + + if (dstX >= screenWidth || dstY >= screenHeight) + return; + + int clampWidth, clampHeight; + + if (dstX + width > screenWidth) + clampWidth = screenWidth - dstX; + else + clampWidth = width; + + if (dstY + height > screenHeight) + clampHeight = screenHeight - dstY; + else + clampHeight = height; + + TinyGLTexture *internalTexture = (TinyGLTexture *)texture; + + byte *src = internalTexture->buffer.getRawBuffer(); + int srcWidth = internalTexture->width; + const Graphics::PixelFormat &format = internalTexture->buffer.getFormat(); + + src += (srcX + (srcY * srcWidth)) * format.bytesPerPixel; + Graphics::PixelBuffer srcBuf(format, src); + + if (invertY) { + srcBuf.shiftBy(srcWidth * (clampHeight - 1)); + for (int l = 0; l < clampHeight; l++) { + for (int r = 0; r < clampWidth; ++r) { + byte aDst, rDst, gDst, bDst; + srcBuf.getARGBAt(r, aDst, rDst, gDst, bDst); + _fb->writePixel((dstX + r) + (dstY + l) * screenWidth, aDst * transparency, rDst, gDst, bDst); + } + srcBuf.shiftBy(-srcWidth); + } + } else { + for (int l = 0; l < clampHeight; l++) { + for (int r = 0; r < clampWidth; ++r) { + byte aDst, rDst, gDst, bDst; + srcBuf.getARGBAt(r, aDst, rDst, gDst, bDst); + _fb->writePixel((dstX + r) + (dstY + l) * screenWidth, aDst * transparency, rDst, gDst, bDst); + } + srcBuf.shiftBy(srcWidth); + } + } +} + } // end of namespace Myst3 #endif diff --git a/engines/myst3/gfx_tinygl.h b/engines/myst3/gfx_tinygl.h index fd64832ccd1..dc65a27cb69 100644 --- a/engines/myst3/gfx_tinygl.h +++ b/engines/myst3/gfx_tinygl.h @@ -60,6 +60,8 @@ public: virtual void screenPosToDirection(const Common::Point screen, float &pitch, float &heading); private: + void blitScreen(Texture *texture, int dstX, int dstY, int srcX, int srcY, int width, int height, float transparency, bool invertY = false); + TinyGL::FrameBuffer *_fb; int _cubeViewport[4]; double _cubeProjectionMatrix[16]; diff --git a/engines/myst3/gfx_tinygl_texture.cpp b/engines/myst3/gfx_tinygl_texture.cpp index 408a697fd00..4233ea6d707 100644 --- a/engines/myst3/gfx_tinygl_texture.cpp +++ b/engines/myst3/gfx_tinygl_texture.cpp @@ -80,6 +80,9 @@ TinyGLTexture::~TinyGLTexture() { void TinyGLTexture::update(const Graphics::Surface *surface) { tglBindTexture(TGL_TEXTURE_2D, id); tglTexImage2D(TGL_TEXTURE_2D, 0, internalFormat, internalWidth, internalHeight, 0, internalFormat, sourceFormat, (void*)surface->getPixels()); // TESTME: Not sure if it works. + + buffer = Graphics::PixelBuffer(surface->format, surface->w * surface->h, DisposeAfterUse::NO); + memcpy(buffer.getRawBuffer(),surface->getPixels(),surface->w * surface->h * surface->format.bytesPerPixel); } } // end of namespace Myst3 diff --git a/engines/myst3/gfx_tinygl_texture.h b/engines/myst3/gfx_tinygl_texture.h index 837ed6749e6..50f5899a337 100644 --- a/engines/myst3/gfx_tinygl_texture.h +++ b/engines/myst3/gfx_tinygl_texture.h @@ -38,6 +38,7 @@ public: void update(const Graphics::Surface *surface); + Graphics::PixelBuffer buffer; TGLuint id; TGLuint internalFormat; TGLuint sourceFormat; diff --git a/graphics/tinygl/get.cpp b/graphics/tinygl/get.cpp index dd3cc89d165..728510977ee 100644 --- a/graphics/tinygl/get.cpp +++ b/graphics/tinygl/get.cpp @@ -23,7 +23,7 @@ void tglGetIntegerv(int pname, int *params) { *params = T_MAX_LIGHTS; break; case TGL_MAX_TEXTURE_SIZE: - *params = 256; // not completely true, but... + *params = MAX_TEXTURE_SIZE; // not completely true, but... break; case TGL_MAX_TEXTURE_STACK_DEPTH: *params = MAX_TEXTURE_STACK_DEPTH; diff --git a/graphics/tinygl/texture.cpp b/graphics/tinygl/texture.cpp index 41d253f2bf5..e5e46fb552d 100644 --- a/graphics/tinygl/texture.cpp +++ b/graphics/tinygl/texture.cpp @@ -152,18 +152,18 @@ void glopTexImage2D(GLContext *c, GLParam *p) { error("glTexImage2D: combination of parameters not handled"); } - pixels1 = new byte[256 * 256 * bytes]; + pixels1 = new byte[MAX_TEXTURE_SIZE * MAX_TEXTURE_SIZE * bytes]; if (pixels != NULL) { - if (width != 256 || height != 256) { + if (width != MAX_TEXTURE_SIZE || height != MAX_TEXTURE_SIZE) { // no interpolation is done here to respect the original image aliasing ! //gl_resizeImageNoInterpolate(pixels1, 256, 256, (unsigned char *)pixels, width, height); // used interpolation anyway, it look much better :) --- aquadran - gl_resizeImage(pixels1, 256, 256, pixels, width, height); - width = 256; - height = 256; + gl_resizeImage(pixels1, MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, pixels, width, height); + width = MAX_TEXTURE_SIZE; + height = MAX_TEXTURE_SIZE; } else { - memcpy(pixels1, pixels, 256 * 256 * bytes); + memcpy(pixels1, pixels, MAX_TEXTURE_SIZE * MAX_TEXTURE_SIZE * bytes); } } diff --git a/graphics/tinygl/zgl.h b/graphics/tinygl/zgl.h index d7baea79d36..839f38f849b 100644 --- a/graphics/tinygl/zgl.h +++ b/graphics/tinygl/zgl.h @@ -33,6 +33,7 @@ enum { #define MAX_MODELVIEW_STACK_DEPTH 35 #define MAX_PROJECTION_STACK_DEPTH 8 #define MAX_TEXTURE_STACK_DEPTH 8 +#define MAX_TEXTURE_SIZE 256 #define MAX_NAME_STACK_DEPTH 64 #define MAX_TEXTURE_LEVELS 11 #define T_MAX_LIGHTS 32