[Scummvm-git-logs] scummvm master -> 7dbed4d4f644d425a344ad2ea960ff679f8f2481
aquadran
noreply at scummvm.org
Thu Oct 31 14:28:54 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
7dbed4d4f6 WINTERMUTE: Rearrange functions to match original code
Commit: 7dbed4d4f644d425a344ad2ea960ff679f8f2481
https://github.com/scummvm/scummvm/commit/7dbed4d4f644d425a344ad2ea960ff679f8f2481
Author: PaweÅ KoÅodziejski (aquadran at gmail.com)
Date: 2024-10-31T15:28:48+01:00
Commit Message:
WINTERMUTE: Rearrange functions to match original code
Changed paths:
engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
index fea1891f7f4..373229e2abd 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
@@ -44,382 +44,31 @@
namespace Wintermute {
-BaseRenderer3D *makeOpenGL3DRenderer(BaseGame *inGame) {
- return new BaseRenderOpenGL3D(inGame);
-}
-
-BaseRenderOpenGL3D::BaseRenderOpenGL3D(BaseGame *inGame) : BaseRenderer3D(inGame) {
- setDefaultAmbientLightColor();
-
- _lightPositions.resize(getMaxActiveLights());
- _lightDirections.resize(getMaxActiveLights());
-}
-
-BaseRenderOpenGL3D::~BaseRenderOpenGL3D() {
- _camera = nullptr;
-}
-
-void BaseRenderOpenGL3D::setSpriteBlendMode(Graphics::TSpriteBlendMode blendMode) {
- switch (blendMode) {
- case Graphics::BLEND_NORMAL:
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- break;
-
- case Graphics::BLEND_ADDITIVE:
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- break;
-
- case Graphics::BLEND_SUBTRACTIVE:
- // wme3d takes the color value here
- glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
- break;
-
- default:
- warning("BaseRenderOpenGL3D::setSpriteBlendMode unsupported blend mode %i", blendMode);
- }
-}
-
-void BaseRenderOpenGL3D::setAmbientLightRenderState() {
- byte a = 0;
- byte r = 0;
- byte g = 0;
- byte b = 0;
-
- if (_ambientLightOverride) {
- a = RGBCOLGetA(_ambientLightColor);
- r = RGBCOLGetR(_ambientLightColor);
- g = RGBCOLGetG(_ambientLightColor);
- b = RGBCOLGetB(_ambientLightColor);
- } else {
- uint32 color = _gameRef->getAmbientLightColor();
-
- a = RGBCOLGetA(color);
- r = RGBCOLGetR(color);
- g = RGBCOLGetG(color);
- b = RGBCOLGetB(color);
- }
-
- float value[] = { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f };
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, value);
-}
-
-int BaseRenderOpenGL3D::getMaxActiveLights() {
- GLint maxLightCount = 0;
- glGetIntegerv(GL_MAX_LIGHTS, &maxLightCount);
- return maxLightCount;
-}
-
-void BaseRenderOpenGL3D::lightEnable(int index, bool enable) {
- if (enable)
- glEnable(GL_LIGHT0 + index);
- else
- glDisable(GL_LIGHT0 + index);
-}
-
-void BaseRenderOpenGL3D::setLightParameters(int index, const DXVector3 &position, const DXVector3 &direction, const DXVector4 &diffuse, bool spotlight) {
- float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
-
- glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, diffuse);
- glLightfv(GL_LIGHT0 + index, GL_AMBIENT, zero);
- glLightfv(GL_LIGHT0 + index, GL_SPECULAR, zero);
-
- _lightPositions[index]._x = position._x;
- _lightPositions[index]._y = position._y;
- _lightPositions[index]._z = position._z;
- _lightPositions[index]._w = 1.0f;
-
- if (spotlight) {
- _lightDirections[index] = direction;
- glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
-
- glLightf(GL_LIGHT0 + index, GL_SPOT_EXPONENT, 0.0f);
- // WME sets the theta angle to 0.5 (radians) and (28.64789 degree) - inner cone
- // WME sets the phi angle to 1.0 (radians) and (57.29578 degree) - outer cone
- // inner cone - angle within which the spotlight has maximum intensity
- // outer cone - angle at the edge of the spotlight's cone
- // 0 <-> 28.64789 - maximum light intensity
- // 28.64789 <-> 57.29578 - light fades smoothly to zero
- // 57.29578 <-> 90 - there is no light
- // The smooth transition between inner code and outer cone create soft spotlight
- // There is no replacement for smooth transition in fixed OpenGL lights.
- // So, inner cone angle is used instead for better visual match
- glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 0.5f * (180.0f / (float)M_PI));
- } else {
- glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 180.0f);
- }
-}
-
-void BaseRenderOpenGL3D::enableCulling() {
- glFrontFace(GL_CW);
- glEnable(GL_CULL_FACE);
-}
-
-void BaseRenderOpenGL3D::disableCulling() {
- glDisable(GL_CULL_FACE);
-}
-
-bool BaseRenderOpenGL3D::enableShadows() {
- warning("BaseRenderOpenGL3D::enableShadows not implemented yet");
- return true;
-}
-
-bool BaseRenderOpenGL3D::disableShadows() {
- warning("BaseRenderOpenGL3D::disableShadows not implemented yet");
- return true;
-}
-
-void BaseRenderOpenGL3D::displayShadow(BaseObject *object, const DXVector3 *lightPos, bool lightPosRelative) {
- BaseSurface *shadowImage;
- if (object->_shadowImage) {
- shadowImage = object->_shadowImage;
- } else {
- shadowImage = _gameRef->_shadowImage;
- }
-
- if (!shadowImage) {
- return;
- }
-
-
- DXMatrix scale, trans, rot, finalm;
- DXMatrixScaling(&scale, object->_shadowSize * object->_scale3D, 1.0f, object->_shadowSize * object->_scale3D);
- DXMatrixRotationY(&rot, degToRad(object->_angle));
- DXMatrixTranslation(&trans, object->_posVector._x, object->_posVector._y, object->_posVector._z);
- DXMatrixMultiply(&finalm, &scale, &rot);
- DXMatrixMultiply(&finalm, &finalm, &trans);
- setWorldTransform(finalm);
-
- glDepthMask(GL_FALSE);
- glEnable(GL_TEXTURE_2D);
- static_cast<BaseSurfaceOpenGL3D *>(shadowImage)->setTexture();
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glVertexPointer(3, GL_FLOAT, sizeof(SimpleShadowVertex), &_simpleShadow[0].x);
- glNormalPointer(GL_FLOAT, sizeof(SimpleShadowVertex), &_simpleShadow[0].nx);
- glTexCoordPointer(2, GL_FLOAT, sizeof(SimpleShadowVertex), &_simpleShadow[0].u);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glDepthMask(GL_TRUE);
-}
-
-bool BaseRenderOpenGL3D::stencilSupported() {
- // assume that we have a stencil buffer
- return true;
-}
-
-BaseImage *BaseRenderOpenGL3D::takeScreenshot() {
- BaseImage *screenshot = new BaseImage();
- Graphics::Surface *surface = new Graphics::Surface();
-#ifdef SCUMM_BIG_ENDIAN
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
-#else
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 0, 8, 16, 24);
-#endif
- surface->create(_viewportRect.width(), _viewportRect.height(), format);
-
- glReadPixels(_viewportRect.left, _viewportRect.height() - _viewportRect.bottom, _viewportRect.width(), _viewportRect.height(),
- GL_RGBA, GL_UNSIGNED_BYTE, surface->getPixels());
- flipVertical(surface);
- Graphics::Surface *converted = surface->convertTo(getPixelFormat());
- screenshot->copyFrom(converted);
- delete surface;
- delete converted;
- return screenshot;
-}
-
-void BaseRenderOpenGL3D::setWindowed(bool windowed) {
- ConfMan.setBool("fullscreen", !windowed);
- g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !windowed);
- g_system->endGFXTransaction();
-}
-
-void BaseRenderOpenGL3D::fadeToColor(byte r, byte g, byte b, byte a) {
- setProjection2D();
-
- const int vertexSize = 16;
- byte vertices[4 * vertexSize];
- float *vertexCoords = reinterpret_cast<float *>(vertices);
-
- vertexCoords[0 * 4 + 1] = _viewportRect.left;
- vertexCoords[0 * 4 + 2] = _viewportRect.bottom;
- vertexCoords[0 * 4 + 3] = 0.0f;
- vertexCoords[1 * 4 + 1] = _viewportRect.left;
- vertexCoords[1 * 4 + 2] = _viewportRect.top;
- vertexCoords[1 * 4 + 3] = 0.0f;
- vertexCoords[2 * 4 + 1] = _viewportRect.right;
- vertexCoords[2 * 4 + 2] = _viewportRect.bottom;
- vertexCoords[2 * 4 + 3] = 0.0f;
- vertexCoords[3 * 4 + 1] = _viewportRect.right;
- vertexCoords[3 * 4 + 2] = _viewportRect.top;
- vertexCoords[3 * 4 + 3] = 0.0f;
-
- vertices[0 * vertexSize + 0] = r;
- vertices[0 * vertexSize + 1] = g;
- vertices[0 * vertexSize + 2] = b;
- vertices[0 * vertexSize + 3] = a;
- vertices[1 * vertexSize + 0] = r;
- vertices[1 * vertexSize + 1] = g;
- vertices[1 * vertexSize + 2] = b;
- vertices[1 * vertexSize + 3] = a;
- vertices[2 * vertexSize + 0] = r;
- vertices[2 * vertexSize + 1] = g;
- vertices[2 * vertexSize + 2] = b;
- vertices[2 * vertexSize + 3] = a;
- vertices[3 * vertexSize + 0] = r;
- vertices[3 * vertexSize + 1] = g;
- vertices[3 * vertexSize + 2] = b;
- vertices[3 * vertexSize + 3] = a;
-
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
-
- glVertexPointer(3, GL_FLOAT, vertexSize, vertices + 4);
- glColorPointer(4, GL_UNSIGNED_BYTE, vertexSize, vertices);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
- setup2D(true);
-}
-
-bool BaseRenderOpenGL3D::fill(byte r, byte g, byte b, Common::Rect *rect) {
- glClearColor(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- return true;
-}
-
-bool BaseRenderOpenGL3D::setViewport(int left, int top, int right, int bottom) {
- _viewportRect.setRect(left, top, right, bottom);
- _viewport._x = left;
- _viewport._y = top;
- _viewport._width = right - left;
- _viewport._height = bottom - top;
- _viewport._minZ = 0.0f;
- _viewport._maxZ = 1.0f;
- glViewport(left, _height - bottom, right - left, bottom - top);
- glDepthRange(_viewport._minZ, _viewport._maxZ);
- return true;
-}
-
-bool BaseRenderOpenGL3D::setViewport3D(DXViewport *viewport) {
- _viewport = *viewport;
- glViewport(_viewport._x, _height - _viewport._height, _viewport._width, _viewport._height);
- glDepthRange(_viewport._minZ, _viewport._maxZ);
- return true;
-}
-
-bool BaseRenderOpenGL3D::drawLine(int x1, int y1, int x2, int y2, uint32 color) {
- byte a = RGBCOLGetA(color);
- byte r = RGBCOLGetR(color);
- byte g = RGBCOLGetG(color);
- byte b = RGBCOLGetB(color);
-
- glBegin(GL_LINES);
- glColor4ub(r, g, b, a);
- glVertex3f(x1, _height - y1, 0.9f);
- glVertex3f(x2, _height - y2, 0.9f);
- glEnd();
-
- return true;
-}
-
-bool BaseRenderOpenGL3D::setProjection() {
- DXMatrix matProj;
-
- float resWidth, resHeight;
- float layerWidth, layerHeight;
- float modWidth, modHeight;
- bool customViewport;
- getProjectionParams(&resWidth, &resHeight, &layerWidth, &layerHeight, &modWidth, &modHeight, &customViewport);
-
- Rect32 rc;
- _gameRef->getCurrentViewportRect(&rc);
- float viewportWidth = (float)rc.right - (float)rc.left;
- float viewportHeight = (float)rc.bottom - (float)rc.top;
-
- // margins
- int mleft = rc.left;
- int mright = resWidth - viewportWidth - rc.left;
- int mtop = rc.top;
- int mbottom = resHeight - viewportHeight - rc.top;
-
- DXMatrixPerspectiveFovLH(&matProj, _fov, viewportWidth / viewportHeight, _nearClipPlane, _farClipPlane);
-
- float scaleMod = resHeight / viewportHeight;
- float scaleRatio = MAX(layerWidth / resWidth, layerHeight / resHeight) /** 1.05*/;
-
- float offsetX = (float)_gameRef->_offsetX;
- float offsetY = (float)_gameRef->_offsetY;
-
- if (!customViewport) {
- offsetX -= _drawOffsetX;
- offsetY -= _drawOffsetY;
- }
-
- matProj.matrix._11 *= scaleRatio * scaleMod;
- matProj.matrix._22 *= scaleRatio * scaleMod;
- matProj.matrix._31 = -(offsetX + (mleft - mright) / 2 - modWidth) / viewportWidth * 2.0f;
- matProj.matrix._32 = (offsetY + (mtop - mbottom) / 2 - modHeight) / viewportHeight * 2.0f;
-
- return setProjectionTransform(matProj);
-}
-
-bool BaseRenderOpenGL3D::setProjection2D() {
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, _width, 0, _height, -1.0, 100.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- return true;
-}
-
-bool BaseRenderOpenGL3D::setWorldTransform(const DXMatrix &transform) {
- _worldMatrix = transform;
- DXMatrix newModelViewTransform, world = transform;
- DXMatrixMultiply(&newModelViewTransform, &world, &_viewMatrix);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(newModelViewTransform);
- return true;
-}
-
-bool BaseRenderOpenGL3D::setViewTransform(const DXMatrix &transform) {
- _viewMatrix = transform;
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(transform);
- return true;
-}
+struct SpriteVertex {
+ float u;
+ float v;
+ float x;
+ float y;
+ float z;
+ uint8 r;
+ uint8 g;
+ uint8 b;
+ uint8 a;
+};
-bool BaseRenderOpenGL3D::setProjectionTransform(const DXMatrix &transform) {
- _projectionMatrix = transform;
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(transform);
- return true;
+BaseRenderer3D *makeOpenGL3DRenderer(BaseGame *inGame) {
+ return new BaseRenderOpenGL3D(inGame);
}
-bool BaseRenderOpenGL3D::windowedBlt() {
- flip();
- return true;
+BaseRenderOpenGL3D::BaseRenderOpenGL3D(BaseGame *inGame) : BaseRenderer3D(inGame) {
+ setDefaultAmbientLightColor();
+
+ _lightPositions.resize(getMaxActiveLights());
+ _lightDirections.resize(getMaxActiveLights());
}
-void Wintermute::BaseRenderOpenGL3D::onWindowChange() {
- _windowed = !g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
+BaseRenderOpenGL3D::~BaseRenderOpenGL3D() {
+ _camera = nullptr;
}
bool BaseRenderOpenGL3D::initRenderer(int width, int height, bool windowed) {
@@ -477,18 +126,18 @@ bool BaseRenderOpenGL3D::initRenderer(int width, int height, bool windowed) {
return true;
}
-bool Wintermute::BaseRenderOpenGL3D::flip() {
- g_system->updateScreen();
- return true;
+void Wintermute::BaseRenderOpenGL3D::onWindowChange() {
+ _windowed = !g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
}
-bool BaseRenderOpenGL3D::indicatorFlip() {
- flip();
+bool Wintermute::BaseRenderOpenGL3D::flip() {
+ g_system->updateScreen();
return true;
}
-bool BaseRenderOpenGL3D::forcedFlip() {
- flip();
+bool BaseRenderOpenGL3D::fill(byte r, byte g, byte b, Common::Rect *rect) {
+ glClearColor(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
return true;
}
@@ -626,6 +275,30 @@ bool BaseRenderOpenGL3D::setup3D(Camera3D *camera, bool force) {
return true;
}
+void BaseRenderOpenGL3D::setAmbientLightRenderState() {
+ byte a = 0;
+ byte r = 0;
+ byte g = 0;
+ byte b = 0;
+
+ if (_ambientLightOverride) {
+ a = RGBCOLGetA(_ambientLightColor);
+ r = RGBCOLGetR(_ambientLightColor);
+ g = RGBCOLGetG(_ambientLightColor);
+ b = RGBCOLGetB(_ambientLightColor);
+ } else {
+ uint32 color = _gameRef->getAmbientLightColor();
+
+ a = RGBCOLGetA(color);
+ r = RGBCOLGetR(color);
+ g = RGBCOLGetG(color);
+ b = RGBCOLGetB(color);
+ }
+
+ float value[] = { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f };
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, value);
+}
+
bool BaseRenderOpenGL3D::setupLines() {
if (_state != RSTATE_LINES) {
_state = RSTATE_LINES;
@@ -641,26 +314,10 @@ bool BaseRenderOpenGL3D::setupLines() {
return true;
}
-BaseSurface *Wintermute::BaseRenderOpenGL3D::createSurface() {
- return new BaseSurfaceOpenGL3D(_gameRef, this);
-}
-
-struct SpriteVertex {
- float u;
- float v;
- float x;
- float y;
- float z;
- uint8 r;
- uint8 g;
- uint8 b;
- uint8 a;
-};
-
bool BaseRenderOpenGL3D::drawSpriteEx(BaseSurfaceOpenGL3D &tex, const Wintermute::Rect32 &rect,
- const Wintermute::Vector2 &pos, const Wintermute::Vector2 &rot, const Wintermute::Vector2 &scale,
- float angle, uint32 color, bool alphaDisable, Graphics::TSpriteBlendMode blendMode,
- bool mirrorX, bool mirrorY) {
+ const Wintermute::Vector2 &pos, const Wintermute::Vector2 &rot, const Wintermute::Vector2 &scale,
+ float angle, uint32 color, bool alphaDisable, Graphics::TSpriteBlendMode blendMode,
+ bool mirrorX, bool mirrorY) {
// original wme has a batch mode for sprites, we ignore this for the moment
if (_forceAlphaColor != 0) {
@@ -709,84 +366,348 @@ bool BaseRenderOpenGL3D::drawSpriteEx(BaseSurfaceOpenGL3D &tex, const Wintermute
vertices[2].u = texRight;
vertices[2].v = texTop;
- vertices[3].u = texRight;
- vertices[3].v = texBottom;
+ vertices[3].u = texRight;
+ vertices[3].v = texBottom;
+
+ // position coords
+ vertices[0].x = pos.x;
+ vertices[0].y = correctedYPos;
+ vertices[0].z = -0.9f;
+
+ vertices[1].x = pos.x;
+ vertices[1].y = correctedYPos - height;
+ vertices[1].z = -0.9f;
+
+ vertices[2].x = pos.x + width;
+ vertices[2].y = correctedYPos;
+ vertices[2].z = -0.9f;
+
+ vertices[3].x = pos.x + width;
+ vertices[3].y = correctedYPos - height;
+ vertices[3].z = -0.9f;
+
+ // not exactly sure about the color format, but this seems to work
+ byte a = RGBCOLGetA(color);
+ byte r = RGBCOLGetR(color);
+ byte g = RGBCOLGetG(color);
+ byte b = RGBCOLGetB(color);
+
+ for (int i = 0; i < 4; ++i) {
+ vertices[i].r = r;
+ vertices[i].g = g;
+ vertices[i].b = b;
+ vertices[i].a = a;
+ }
+
+ if (angle != 0) {
+ Vector2 correctedRot(rot.x, (rot.y - offset) * -1.0f + offset);
+ Math::Matrix3 transform = build2dTransformation(correctedRot, angle);
+
+ for (int i = 0; i < 4; ++i) {
+ Math::Vector3d vertexPostion(vertices[i].x, vertices[i].y, 1.0f);
+ transform.transformVector(&vertexPostion);
+
+ vertices[i].x = vertexPostion.x();
+ vertices[i].y = vertexPostion.y();
+ }
+ }
+
+ if (alphaDisable) {
+ glDisable(GL_ALPHA_TEST);
+ }
+
+ setSpriteBlendMode(blendMode);
+
+ glEnable(GL_TEXTURE_2D);
+
+ glEnableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+
+ glVertexPointer(3, GL_FLOAT, sizeof(SpriteVertex), &vertices[0].x);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(SpriteVertex), &vertices[0].u);
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(SpriteVertex), &vertices[0].r);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ if (alphaDisable) {
+ glEnable(GL_ALPHA_TEST);
+ }
+
+ return true;
+}
+
+bool BaseRenderOpenGL3D::setProjection() {
+ DXMatrix matProj;
+
+ float resWidth, resHeight;
+ float layerWidth, layerHeight;
+ float modWidth, modHeight;
+ bool customViewport;
+ getProjectionParams(&resWidth, &resHeight, &layerWidth, &layerHeight, &modWidth, &modHeight, &customViewport);
+
+ Rect32 rc;
+ _gameRef->getCurrentViewportRect(&rc);
+ float viewportWidth = (float)rc.right - (float)rc.left;
+ float viewportHeight = (float)rc.bottom - (float)rc.top;
+
+ // margins
+ int mleft = rc.left;
+ int mright = resWidth - viewportWidth - rc.left;
+ int mtop = rc.top;
+ int mbottom = resHeight - viewportHeight - rc.top;
+
+ DXMatrixPerspectiveFovLH(&matProj, _fov, viewportWidth / viewportHeight, _nearClipPlane, _farClipPlane);
+
+ float scaleMod = resHeight / viewportHeight;
+ float scaleRatio = MAX(layerWidth / resWidth, layerHeight / resHeight) /** 1.05*/;
+
+ float offsetX = (float)_gameRef->_offsetX;
+ float offsetY = (float)_gameRef->_offsetY;
+
+ if (!customViewport) {
+ offsetX -= _drawOffsetX;
+ offsetY -= _drawOffsetY;
+ }
+
+ matProj.matrix._11 *= scaleRatio * scaleMod;
+ matProj.matrix._22 *= scaleRatio * scaleMod;
+ matProj.matrix._31 = -(offsetX + (mleft - mright) / 2 - modWidth) / viewportWidth * 2.0f;
+ matProj.matrix._32 = (offsetY + (mtop - mbottom) / 2 - modHeight) / viewportHeight * 2.0f;
+
+ return setProjectionTransform(matProj);
+}
+
+bool BaseRenderOpenGL3D::drawLine(int x1, int y1, int x2, int y2, uint32 color) {
+ byte a = RGBCOLGetA(color);
+ byte r = RGBCOLGetR(color);
+ byte g = RGBCOLGetG(color);
+ byte b = RGBCOLGetB(color);
+
+ glBegin(GL_LINES);
+ glColor4ub(r, g, b, a);
+ glVertex3f(x1, _height - y1, 0.9f);
+ glVertex3f(x2, _height - y2, 0.9f);
+ glEnd();
+
+ return true;
+}
+
+bool BaseRenderOpenGL3D::windowedBlt() {
+ flip();
+ return true;
+}
+
+void BaseRenderOpenGL3D::fadeToColor(byte r, byte g, byte b, byte a) {
+ setProjection2D();
+
+ const int vertexSize = 16;
+ byte vertices[4 * vertexSize];
+ float *vertexCoords = reinterpret_cast<float *>(vertices);
+
+ vertexCoords[0 * 4 + 1] = _viewportRect.left;
+ vertexCoords[0 * 4 + 2] = _viewportRect.bottom;
+ vertexCoords[0 * 4 + 3] = 0.0f;
+ vertexCoords[1 * 4 + 1] = _viewportRect.left;
+ vertexCoords[1 * 4 + 2] = _viewportRect.top;
+ vertexCoords[1 * 4 + 3] = 0.0f;
+ vertexCoords[2 * 4 + 1] = _viewportRect.right;
+ vertexCoords[2 * 4 + 2] = _viewportRect.bottom;
+ vertexCoords[2 * 4 + 3] = 0.0f;
+ vertexCoords[3 * 4 + 1] = _viewportRect.right;
+ vertexCoords[3 * 4 + 2] = _viewportRect.top;
+ vertexCoords[3 * 4 + 3] = 0.0f;
+
+ vertices[0 * vertexSize + 0] = r;
+ vertices[0 * vertexSize + 1] = g;
+ vertices[0 * vertexSize + 2] = b;
+ vertices[0 * vertexSize + 3] = a;
+ vertices[1 * vertexSize + 0] = r;
+ vertices[1 * vertexSize + 1] = g;
+ vertices[1 * vertexSize + 2] = b;
+ vertices[1 * vertexSize + 3] = a;
+ vertices[2 * vertexSize + 0] = r;
+ vertices[2 * vertexSize + 1] = g;
+ vertices[2 * vertexSize + 2] = b;
+ vertices[2 * vertexSize + 3] = a;
+ vertices[3 * vertexSize + 0] = r;
+ vertices[3 * vertexSize + 1] = g;
+ vertices[3 * vertexSize + 2] = b;
+ vertices[3 * vertexSize + 3] = a;
+
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
- // position coords
- vertices[0].x = pos.x;
- vertices[0].y = correctedYPos;
- vertices[0].z = -0.9f;
+ glVertexPointer(3, GL_FLOAT, vertexSize, vertices + 4);
+ glColorPointer(4, GL_UNSIGNED_BYTE, vertexSize, vertices);
- vertices[1].x = pos.x;
- vertices[1].y = correctedYPos - height;
- vertices[1].z = -0.9f;
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- vertices[2].x = pos.x + width;
- vertices[2].y = correctedYPos;
- vertices[2].z = -0.9f;
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
- vertices[3].x = pos.x + width;
- vertices[3].y = correctedYPos - height;
- vertices[3].z = -0.9f;
+ setup2D(true);
+}
- // not exactly sure about the color format, but this seems to work
- byte a = RGBCOLGetA(color);
- byte r = RGBCOLGetR(color);
- byte g = RGBCOLGetG(color);
- byte b = RGBCOLGetB(color);
+BaseImage *BaseRenderOpenGL3D::takeScreenshot() {
+ BaseImage *screenshot = new BaseImage();
+ Graphics::Surface *surface = new Graphics::Surface();
+#ifdef SCUMM_BIG_ENDIAN
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+ surface->create(_viewportRect.width(), _viewportRect.height(), format);
- for (int i = 0; i < 4; ++i) {
- vertices[i].r = r;
- vertices[i].g = g;
- vertices[i].b = b;
- vertices[i].a = a;
- }
+ glReadPixels(_viewportRect.left, _viewportRect.height() - _viewportRect.bottom, _viewportRect.width(), _viewportRect.height(),
+ GL_RGBA, GL_UNSIGNED_BYTE, surface->getPixels());
+ flipVertical(surface);
+ Graphics::Surface *converted = surface->convertTo(getPixelFormat());
+ screenshot->copyFrom(converted);
+ delete surface;
+ delete converted;
+ return screenshot;
+}
- if (angle != 0) {
- Vector2 correctedRot(rot.x, (rot.y - offset) * -1.0f + offset);
- Math::Matrix3 transform = build2dTransformation(correctedRot, angle);
+bool BaseRenderOpenGL3D::enableShadows() {
+ warning("BaseRenderOpenGL3D::enableShadows not implemented yet");
+ return true;
+}
- for (int i = 0; i < 4; ++i) {
- Math::Vector3d vertexPostion(vertices[i].x, vertices[i].y, 1.0f);
- transform.transformVector(&vertexPostion);
+bool BaseRenderOpenGL3D::disableShadows() {
+ warning("BaseRenderOpenGL3D::disableShadows not implemented yet");
+ return true;
+}
- vertices[i].x = vertexPostion.x();
- vertices[i].y = vertexPostion.y();
- }
+void BaseRenderOpenGL3D::displayShadow(BaseObject *object, const DXVector3 *lightPos, bool lightPosRelative) {
+ BaseSurface *shadowImage;
+ if (object->_shadowImage) {
+ shadowImage = object->_shadowImage;
+ } else {
+ shadowImage = _gameRef->_shadowImage;
}
- if (alphaDisable) {
- glDisable(GL_ALPHA_TEST);
+ if (!shadowImage) {
+ return;
}
- setSpriteBlendMode(blendMode);
+ DXMatrix scale, trans, rot, finalm;
+ DXMatrixScaling(&scale, object->_shadowSize * object->_scale3D, 1.0f, object->_shadowSize * object->_scale3D);
+ DXMatrixRotationY(&rot, degToRad(object->_angle));
+ DXMatrixTranslation(&trans, object->_posVector._x, object->_posVector._y, object->_posVector._z);
+ DXMatrixMultiply(&finalm, &scale, &rot);
+ DXMatrixMultiply(&finalm, &finalm, &trans);
+ setWorldTransform(finalm);
+
+ glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
+ static_cast<BaseSurfaceOpenGL3D *>(shadowImage)->setTexture();
- glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glVertexPointer(3, GL_FLOAT, sizeof(SpriteVertex), &vertices[0].x);
- glTexCoordPointer(2, GL_FLOAT, sizeof(SpriteVertex), &vertices[0].u);
- glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(SpriteVertex), &vertices[0].r);
+ glVertexPointer(3, GL_FLOAT, sizeof(SimpleShadowVertex), &_simpleShadow[0].x);
+ glNormalPointer(GL_FLOAT, sizeof(SimpleShadowVertex), &_simpleShadow[0].nx);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(SimpleShadowVertex), &_simpleShadow[0].u);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- if (alphaDisable) {
- glEnable(GL_ALPHA_TEST);
+ glDepthMask(GL_TRUE);
+}
+
+void BaseRenderOpenGL3D::setSpriteBlendMode(Graphics::TSpriteBlendMode blendMode) {
+ switch (blendMode) {
+ case Graphics::BLEND_NORMAL:
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ break;
+
+ case Graphics::BLEND_ADDITIVE:
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ break;
+
+ case Graphics::BLEND_SUBTRACTIVE:
+ // wme3d takes the color value here
+ glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
+ break;
+
+ default:
+ warning("BaseRenderOpenGL3D::setSpriteBlendMode unsupported blend mode %i", blendMode);
}
+}
+bool BaseRenderOpenGL3D::stencilSupported() {
+ // assume that we have a stencil buffer
return true;
}
+int BaseRenderOpenGL3D::getMaxActiveLights() {
+ GLint maxLightCount = 0;
+ glGetIntegerv(GL_MAX_LIGHTS, &maxLightCount);
+ return maxLightCount;
+}
+
+// implements D3D LightEnable()
+void BaseRenderOpenGL3D::lightEnable(int index, bool enable) {
+ if (enable)
+ glEnable(GL_LIGHT0 + index);
+ else
+ glDisable(GL_LIGHT0 + index);
+}
+
+// backend layer 3DLight::SetLight
+void BaseRenderOpenGL3D::setLightParameters(int index, const DXVector3 &position, const DXVector3 &direction, const DXVector4 &diffuse, bool spotlight) {
+ float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+
+ glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, diffuse);
+ glLightfv(GL_LIGHT0 + index, GL_AMBIENT, zero);
+ glLightfv(GL_LIGHT0 + index, GL_SPECULAR, zero);
+
+ _lightPositions[index]._x = position._x;
+ _lightPositions[index]._y = position._y;
+ _lightPositions[index]._z = position._z;
+ _lightPositions[index]._w = 1.0f;
+
+ if (spotlight) {
+ _lightDirections[index] = direction;
+ glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
+
+ glLightf(GL_LIGHT0 + index, GL_SPOT_EXPONENT, 0.0f);
+ // WME sets the theta angle to 0.5 (radians) and (28.64789 degree) - inner cone
+ // WME sets the phi angle to 1.0 (radians) and (57.29578 degree) - outer cone
+ // inner cone - angle within which the spotlight has maximum intensity
+ // outer cone - angle at the edge of the spotlight's cone
+ // 0 <-> 28.64789 - maximum light intensity
+ // 28.64789 <-> 57.29578 - light fades smoothly to zero
+ // 57.29578 <-> 90 - there is no light
+ // The smooth transition between inner code and outer cone create soft spotlight
+ // There is no replacement for smooth transition in fixed OpenGL lights.
+ // So, inner cone angle is used instead for better visual match
+ glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 0.5f * (180.0f / (float)M_PI));
+ } else {
+ glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 180.0f);
+ }
+}
+
+// backend layer AdSceneGeometry::Render
void BaseRenderOpenGL3D::renderSceneGeometry(const BaseArray<AdWalkplane *> &planes, const BaseArray<AdBlock *> &blocks,
- const BaseArray<AdGeneric *> &generics, const BaseArray<Light3D *> &lights, Camera3D *camera) {
+ const BaseArray<AdGeneric *> &generics, const BaseArray<Light3D *> &lights, Camera3D *camera) {
DXMatrix matIdentity;
DXMatrixIdentity(&matIdentity);
@@ -857,9 +778,10 @@ void BaseRenderOpenGL3D::renderSceneGeometry(const BaseArray<AdWalkplane *> &pla
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
+// backend layer 3DShadowVolume::Render()
void BaseRenderOpenGL3D::renderShadowGeometry(const BaseArray<AdWalkplane *> &planes,
- const BaseArray<AdBlock *> &blocks,
- const BaseArray<AdGeneric *> &generics, Camera3D *camera) {
+ const BaseArray<AdBlock *> &blocks,
+ const BaseArray<AdGeneric *> &generics, Camera3D *camera) {
DXMatrix matIdentity;
DXMatrixIdentity(&matIdentity);
@@ -899,6 +821,95 @@ void BaseRenderOpenGL3D::renderShadowGeometry(const BaseArray<AdWalkplane *> &pl
setSpriteBlendMode(Graphics::BLEND_NORMAL);
}
+// implements D3D SetRenderState() D3DRS_CULLMODE - CCW
+void BaseRenderOpenGL3D::enableCulling() {
+ glFrontFace(GL_CW);
+ glEnable(GL_CULL_FACE);
+}
+
+// implements D3D SetRenderState() D3DRS_CULLMODE - NONE
+void BaseRenderOpenGL3D::disableCulling() {
+ glDisable(GL_CULL_FACE);
+}
+
+void BaseRenderOpenGL3D::setWindowed(bool windowed) {
+ ConfMan.setBool("fullscreen", !windowed);
+ g_system->beginGFXTransaction();
+ g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !windowed);
+ g_system->endGFXTransaction();
+}
+
+// implements D3D SetViewport() for 2D viewport
+bool BaseRenderOpenGL3D::setViewport(int left, int top, int right, int bottom) {
+ _viewportRect.setRect(left, top, right, bottom);
+ _viewport._x = left;
+ _viewport._y = top;
+ _viewport._width = right - left;
+ _viewport._height = bottom - top;
+ _viewport._minZ = 0.0f;
+ _viewport._maxZ = 1.0f;
+ glViewport(left, _height - bottom, right - left, bottom - top);
+ glDepthRange(_viewport._minZ, _viewport._maxZ);
+ return true;
+}
+
+// implements D3D SetViewport() for 3D viewport
+bool BaseRenderOpenGL3D::setViewport3D(DXViewport *viewport) {
+ _viewport = *viewport;
+ glViewport(_viewport._x, _height - _viewport._height, _viewport._width, _viewport._height);
+ glDepthRange(_viewport._minZ, _viewport._maxZ);
+ return true;
+}
+
+bool BaseRenderOpenGL3D::setProjection2D() {
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, _width, 0, _height, -1.0, 100.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ return true;
+}
+
+// implements SetTransform() D3DTS_WORLD
+bool BaseRenderOpenGL3D::setWorldTransform(const DXMatrix &transform) {
+ _worldMatrix = transform;
+ DXMatrix newModelViewTransform, world = transform;
+ DXMatrixMultiply(&newModelViewTransform, &world, &_viewMatrix);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(newModelViewTransform);
+ return true;
+}
+
+// implements SetTransform() D3DTS_WIEW
+bool BaseRenderOpenGL3D::setViewTransform(const DXMatrix &transform) {
+ _viewMatrix = transform;
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(transform);
+ return true;
+}
+
+// implements SetTransform() D3DTS_PROJECTION
+bool BaseRenderOpenGL3D::setProjectionTransform(const DXMatrix &transform) {
+ _projectionMatrix = transform;
+ glMatrixMode(GL_PROJECTION);
+ glLoadMatrixf(transform);
+ return true;
+}
+
+bool BaseRenderOpenGL3D::indicatorFlip() {
+ flip();
+ return true;
+}
+
+bool BaseRenderOpenGL3D::forcedFlip() {
+ flip();
+ return true;
+}
+
+BaseSurface *Wintermute::BaseRenderOpenGL3D::createSurface() {
+ return new BaseSurfaceOpenGL3D(_gameRef, this);
+}
+
Mesh3DS *BaseRenderOpenGL3D::createMesh3DS() {
return new Mesh3DSOpenGL(_gameRef);
}
@@ -911,6 +922,8 @@ ShadowVolume *BaseRenderOpenGL3D::createShadowVolume() {
return new ShadowVolumeOpenGL(_gameRef);
}
+// ScummVM specific ends <--
+
} // namespace Wintermute
#endif // defined(USE_OPENGL_GAME)
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
index d3cd3917b83..4efc5edb45e 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
@@ -42,10 +42,6 @@
namespace Wintermute {
-BaseRenderer3D *makeOpenGL3DShaderRenderer(BaseGame *inGame) {
- return new BaseRenderOpenGL3DShader(inGame);
-}
-
struct SpriteVertexShader {
float x;
float y;
@@ -57,6 +53,10 @@ struct SpriteVertexShader {
float a;
};
+BaseRenderer3D *makeOpenGL3DShaderRenderer(BaseGame *inGame) {
+ return new BaseRenderOpenGL3DShader(inGame);
+}
+
BaseRenderOpenGL3DShader::BaseRenderOpenGL3DShader(BaseGame *inGame) : BaseRenderer3D(inGame) {
_flatShadowMaskShader = nullptr;
}
@@ -70,396 +70,344 @@ BaseRenderOpenGL3DShader::~BaseRenderOpenGL3DShader() {
glDeleteFramebuffers(1, &_flatShadowFrameBuffer);
}
-void BaseRenderOpenGL3DShader::setSpriteBlendMode(Graphics::TSpriteBlendMode blendMode) {
- switch (blendMode) {
- case Graphics::BLEND_NORMAL:
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- break;
-
- case Graphics::BLEND_ADDITIVE:
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- break;
-
- case Graphics::BLEND_SUBTRACTIVE:
- // wme3d takes the color value here
- glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
- break;
-
- default:
- warning("BaseRenderOpenGL3DShader::setSpriteBlendMode unsupported blend mode %i", blendMode);
- }
-}
-
-void BaseRenderOpenGL3DShader::setAmbientLightRenderState() {
- byte a = RGBCOLGetA(_ambientLightColor);
- byte r = RGBCOLGetR(_ambientLightColor);
- byte g = RGBCOLGetG(_ambientLightColor);
- byte b = RGBCOLGetB(_ambientLightColor);
+bool BaseRenderOpenGL3DShader::initRenderer(int width, int height, bool windowed) {
+ glGenBuffers(1, &_spriteVBO);
+ glBindBuffer(GL_ARRAY_BUFFER, _spriteVBO);
+ glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(SpriteVertexShader), nullptr, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
- if (!_ambientLightOverride) {
- uint32 color = _gameRef->getAmbientLightColor();
+ static const char *spriteAttributes[] = {"position", "texcoord", "color", nullptr};
+ _spriteShader = OpenGL::Shader::fromFiles("wme_sprite", spriteAttributes);
- a = RGBCOLGetA(color);
- r = RGBCOLGetR(color);
- g = RGBCOLGetG(color);
- b = RGBCOLGetB(color);
- }
+ _spriteShader->enableVertexAttribute("position", _spriteVBO, 2, GL_FLOAT, false, sizeof(SpriteVertexShader), 0);
+ _spriteShader->enableVertexAttribute("texcoord", _spriteVBO, 2, GL_FLOAT, false, sizeof(SpriteVertexShader), 8);
+ _spriteShader->enableVertexAttribute("color", _spriteVBO, 4, GL_FLOAT, false, sizeof(SpriteVertexShader), 16);
- Math::Vector4d value;
- value.x() = r / 255.0f;
- value.y() = g / 255.0f;
- value.z() = b / 255.0f;
- value.w() = a / 255.0f;
+ static const char *geometryAttributes[] = { "position", "color", nullptr };
+ _geometryShader = OpenGL::Shader::fromFiles("wme_geometry", geometryAttributes);
- _xmodelShader->use();
- _xmodelShader->setUniform("ambientLight", value);
-}
+ static const char *shadowVolumeAttributes[] = { "position", nullptr };
+ _shadowVolumeShader = OpenGL::Shader::fromFiles("wme_shadow_volume", shadowVolumeAttributes);
-int BaseRenderOpenGL3DShader::getMaxActiveLights() {
- return 8;
-}
+ static const char *shadowMaskAttributes[] = { "position", nullptr };
+ _shadowMaskShader = OpenGL::Shader::fromFiles("wme_shadow_mask", shadowMaskAttributes);
-void BaseRenderOpenGL3DShader::lightEnable(int index, bool enable) {
- _xmodelShader->use();
- Common::String uniform = Common::String::format("lights[%i].enabled", index);
- if (enable)
- _xmodelShader->setUniform1f(uniform.c_str(), 1.0f);
- else
- _xmodelShader->setUniform1f(uniform.c_str(), -1.0f);
-}
+ DXMatrix m;
+ DXMatrixIdentity(&m);
+ _transformStack.push_back(m);
-void BaseRenderOpenGL3DShader::setLightParameters(int index, const DXVector3 &position,
- const DXVector3 &direction,
- const DXVector4 &diffuse, bool spotlight) {
- Math::Vector4d position4d;
- position4d.x() = position._x;
- position4d.y() = position._y;
- position4d.z() = position._z;
- position4d.w() = 1.0f;
+ static const char *XModelAttributes[] = {"position", "texcoord", "normal", nullptr};
+ _xmodelShader = OpenGL::Shader::fromFiles("wme_modelx", XModelAttributes);
- Math::Vector4d direction4d;
- direction4d.x() = direction._x;
- direction4d.y() = direction._y;
- direction4d.z() = direction._z;
- direction4d.w() = 0.0f;
+ setDefaultAmbientLightColor();
- if (spotlight) {
- direction4d.w() = -1.0f;
+ for (int i = 0; i < getMaxActiveLights(); ++i) {
+ setLightParameters(i, DXVector3(0, 0, 0), DXVector3(0, 0, 0), DXVector4(0, 0, 0, 0), false);
+ lightEnable(i, false);
}
- Math::Vector4d diffuse4d;
- diffuse4d.x() = diffuse._x;
- diffuse4d.y() = diffuse._y;
- diffuse4d.z() = diffuse._z;
- diffuse4d.w() = 0.0f;
-
-
- _xmodelShader->use();
-
- Common::String uniform = Common::String::format("lights[%i]._position", index);
- _xmodelShader->setUniform(uniform.c_str(), position4d);
-
- uniform = Common::String::format("lights[%i]._direction", index);
- _xmodelShader->setUniform(uniform.c_str(), direction4d);
-
- uniform = Common::String::format("lights[%i]._color", index);
- _xmodelShader->setUniform(uniform.c_str(), diffuse4d);
-}
+ _windowed = !ConfMan.getBool("fullscreen");
+ _width = width;
+ _height = height;
-void BaseRenderOpenGL3DShader::enableCulling() {
- glFrontFace(GL_CW);
- glEnable(GL_CULL_FACE);
-}
+ _nearClipPlane = 90.0f;
+ _farClipPlane = 10000.0f;
-void BaseRenderOpenGL3DShader::disableCulling() {
- glDisable(GL_CULL_FACE);
-}
+ setViewport(0, 0, width, height);
-bool BaseRenderOpenGL3DShader::enableShadows() {
- return true; // TODO: reimplement. Shadows are broken for a while since it use not allowed binding to frame buffer
- if (_flatShadowMaskShader == nullptr) {
- _flatShadowColor = Math::Vector4d(0.0f, 0.0f, 0.0f, 0.5f);
+ float fadeVertexCoords[8];
- _shadowTextureWidth = 512;
- _shadowTextureHeight = 512;
+ fadeVertexCoords[0 * 2 + 0] = _viewportRect.left;
+ fadeVertexCoords[0 * 2 + 1] = _viewportRect.bottom;
+ fadeVertexCoords[1 * 2 + 0] = _viewportRect.left;
+ fadeVertexCoords[1 * 2 + 1] = _viewportRect.top;
+ fadeVertexCoords[2 * 2 + 0] = _viewportRect.right;
+ fadeVertexCoords[2 * 2 + 1] = _viewportRect.bottom;
+ fadeVertexCoords[3 * 2 + 0] = _viewportRect.right;
+ fadeVertexCoords[3 * 2 + 1] = _viewportRect.top;
- float nearPlane = 1.0f;
- float farPlane = 10000.0f;
- float fovy = static_cast<float>(M_PI / 4.0f);
+ glGenBuffers(1, &_fadeVBO);
+ glBindBuffer(GL_ARRAY_BUFFER, _fadeVBO);
+ glBufferData(GL_ARRAY_BUFFER, 4 * 8, fadeVertexCoords, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
- float top = nearPlane * tanf(fovy * 0.5f);
- float bottom = -top;
- float right = top;
- float left = -right;
+ static const char *fadeAttributes[] = { "position", nullptr };
+ _fadeShader = OpenGL::Shader::fromFiles("wme_fade", fadeAttributes);
+ _fadeShader->enableVertexAttribute("position", _fadeVBO, 2, GL_FLOAT, false, 8, 0);
- float deltaX = (-0.5f * (right - left)) / _shadowTextureWidth;
- float deltaY = (0.5f * (top - bottom)) / _shadowTextureHeight;
+ glGenBuffers(1, &_lineVBO);
+ glBindBuffer(GL_ARRAY_BUFFER, _lineVBO);
+ glBufferData(GL_ARRAY_BUFFER, 2 * 8, nullptr, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
- Math::Matrix4 lightProjection = Math::makeFrustumMatrix(left + deltaX, right + deltaX, bottom + deltaY, top + deltaY, nearPlane, farPlane);
+ static const char *lineAttributes[] = { "position", nullptr };
+ _lineShader = OpenGL::Shader::fromFiles("wme_line", lineAttributes);
+ _lineShader->enableVertexAttribute("position", _lineVBO, 2, GL_FLOAT, false, 8, 0);
- _flatShadowXModelShader->use();
- _flatShadowXModelShader->setUniform("projMatrix", lightProjection);
+ static const char *flatShadowXModelAttributes[] = { "position", nullptr };
+ _flatShadowXModelShader = OpenGL::Shader::fromFiles("wme_flat_shadow_modelx", flatShadowXModelAttributes);
- glGenTextures(1, &_flatShadowRenderTexture);
- glBindTexture(GL_TEXTURE_2D, _flatShadowRenderTexture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _shadowTextureWidth, _shadowTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ _active = true;
- glGenRenderbuffers(1, &_flatShadowDepthBuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, _flatShadowDepthBuffer);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _shadowTextureWidth, _shadowTextureHeight);
+ setProjection();
- glGenFramebuffers(1, &_flatShadowFrameBuffer);
- glBindFramebuffer(GL_FRAMEBUFFER, _flatShadowFrameBuffer);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _flatShadowRenderTexture, 0);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _flatShadowDepthBuffer);
+ return true;
+}
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+void Wintermute::BaseRenderOpenGL3DShader::onWindowChange() {
+ _windowed = !g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
+}
- float flatShadowMaskVertices[12];
- flatShadowMaskVertices[0] = -250.0f;
- flatShadowMaskVertices[1] = 0.0f;
- flatShadowMaskVertices[2] = -250.0f;
+bool Wintermute::BaseRenderOpenGL3DShader::flip() {
+ g_system->updateScreen();
+ return true;
+}
- flatShadowMaskVertices[3] = -250.0f;
- flatShadowMaskVertices[4] = 0.0f;
- flatShadowMaskVertices[5] = 250.0f;
+bool BaseRenderOpenGL3DShader::fill(byte r, byte g, byte b, Common::Rect *rect) {
+ glClearColor(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ return true;
+}
- flatShadowMaskVertices[6] = 250.0f;
- flatShadowMaskVertices[7] = 0.0f;
- flatShadowMaskVertices[8] = -250.0f;
+bool BaseRenderOpenGL3DShader::setup2D(bool force) {
+ if (_state != RSTATE_2D || force) {
+ _state = RSTATE_2D;
- flatShadowMaskVertices[9] = 250.0f;
- flatShadowMaskVertices[10] = 0.0f;
- flatShadowMaskVertices[11] = 250.0f;
+ // some states are still missing here
- glGenBuffers(1, &_flatShadowMaskVBO);
- glBindBuffer(GL_ARRAY_BUFFER, _flatShadowMaskVBO);
- glBufferData(GL_ARRAY_BUFFER, 4 * 12, flatShadowMaskVertices, GL_STATIC_DRAW);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_STENCIL_TEST);
- static const char *flatShadowMaskAttributes[] = { "position", nullptr };
- _flatShadowMaskShader = OpenGL::Shader::fromFiles("wme_flat_shadow_mask", flatShadowMaskAttributes);
- _flatShadowMaskShader->enableVertexAttribute("position", _flatShadowMaskVBO, 3, GL_FLOAT, false, 12, 0);
+ glEnable(GL_CULL_FACE);
+ glFrontFace(GL_CCW);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- _flatShadowMaskShader->use();
- _flatShadowMaskShader->setUniform("lightProjMatrix", lightProjection);
+ glViewport(0, 0, _width, _height);
- _gameRef->_supportsRealTimeShadows = true;
+ setProjection2D();
}
return true;
}
-bool BaseRenderOpenGL3DShader::disableShadows() {
- warning("BaseRenderOpenGL3DShader::disableShadows not implemented yet");
- return true;
-}
-
-void BaseRenderOpenGL3DShader::displayShadow(BaseObject *object, const DXVector3 *lightPos, bool lightPosRelative) {
- return; // TODO: reimplement. Shadows are broken for a while since it use not allowed binding to frame buffer
- if (_flatShadowMaskShader) {
- if (object->_shadowType <= SHADOW_SIMPLE) {
- // TODO: Display simple shadow here
- return;
- }
+bool BaseRenderOpenGL3DShader::setup3D(Camera3D *camera, bool force) {
+ if (_state != RSTATE_3D || force) {
+ _state = RSTATE_3D;
- DXVector3 position = *lightPos;
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
- if (lightPosRelative) {
- position = object->_posVector + *lightPos;
- }
+ setAmbientLightRenderState();
- DXMatrix lightView = DXMatrix(Math::makeLookAtMatrix(Math::Vector3d(position),
- Math::Vector3d(object->_posVector),
- Math::Vector3d(0.0f, 1.0f, 0.0f)).getData());
- DXMatrix translation;
- DXMatrixTranslation(&translation, -position._x, -position._y, -position._z);
- DXMatrixTranspose(&translation, &translation);
- DXMatrixMultiply(&lightView, &translation, &lightView);
+ if (camera)
+ _camera = camera;
+ if (_camera) {
+ DXMatrix viewMatrix;
+ _camera->getViewMatrix(&viewMatrix);
+ setViewTransform(viewMatrix);
- Math::Matrix4 lightViewMatrix;
- lightViewMatrix.setData(lightView);
- _flatShadowXModelShader->use();
- _flatShadowXModelShader->setUniform("viewMatrix", lightViewMatrix);
+ _fov = _camera->_fov;
- Math::Matrix4 worldMatrix;
- worldMatrix.setData(object->_worldMatrix);
- worldMatrix.transpose();
- _flatShadowXModelShader->setUniform("modelMatrix", worldMatrix);
+ if (_camera->_nearClipPlane >= 0.0f) {
+ _nearClipPlane = _camera->_nearClipPlane;
+ } else {
+ _nearClipPlane = DEFAULT_NEAR_PLANE;
+ }
- byte a = RGBCOLGetA(object->_shadowColor);
- byte r = RGBCOLGetR(object->_shadowColor);
- byte g = RGBCOLGetG(object->_shadowColor);
- byte b = RGBCOLGetB(object->_shadowColor);
+ if (_camera->_farClipPlane >= 0.0f) {
+ _farClipPlane = _camera->_farClipPlane;
+ } else {
+ _farClipPlane = DEFAULT_FAR_PLANE;
+ }
+ } else {
+ _nearClipPlane = DEFAULT_NEAR_PLANE;
+ _farClipPlane = DEFAULT_FAR_PLANE;
+ }
- _flatShadowColor.x() = r / 255.0f;
- _flatShadowColor.y() = g / 255.0f;
- _flatShadowColor.z() = b / 255.0f;
- _flatShadowColor.w() = a / 255.0f;
- _flatShadowXModelShader->setUniform("shadowColor", _flatShadowColor);
+ bool fogEnabled;
+ uint32 fogColor;
+ float fogStart, fogEnd;
- glBindFramebuffer(GL_FRAMEBUFFER, _flatShadowFrameBuffer);
+ _gameRef->getFogParams(&fogEnabled, &fogColor, &fogStart, &fogEnd);
+ if (fogEnabled) {
+ // TODO: Implement fog
+ GLfloat color[4];
+ color[0] = RGBCOLGetR(fogColor) / 255.0f;
+ color[1] = RGBCOLGetG(fogColor) / 255.0f;
+ color[2] = RGBCOLGetB(fogColor) / 255.0f;
+ color[3] = RGBCOLGetA(fogColor) / 255.0f;
+ debug(5, "BaseRenderOpenGL3DShader::setup3D fog not yet implemented! [%f %f %f %f]", color[0], color[1], color[2], color[3]);
+ } else {
+ // TODO: Disable fog in shader
+ }
- GLint currentViewport[4];
- glGetIntegerv(GL_VIEWPORT, currentViewport);
- glViewport(1, 1, _shadowTextureWidth - 2, _shadowTextureHeight - 2);
+ glViewport(_viewportRect.left, _height - _viewportRect.bottom, _viewportRect.width(), _viewportRect.height());
- glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ setProjection();
+ }
- object->_xmodel->renderFlatShadowModel();
+ Math::Matrix4 viewMatrix, projectionMatrix;
+ viewMatrix.setData(_viewMatrix);
+ projectionMatrix.setData(_projectionMatrix);
+ _xmodelShader->use();
+ _xmodelShader->setUniform("viewMatrix", viewMatrix);
+ _xmodelShader->setUniform("projMatrix", projectionMatrix);
+ // this is 8 / 255, since 8 is the value used by wme (as a DWORD)
+ _xmodelShader->setUniform1f("alphaRef", 0.031f);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ _geometryShader->use();
+ _geometryShader->setUniform("viewMatrix", viewMatrix);
+ _geometryShader->setUniform("projMatrix", projectionMatrix);
- glViewport(currentViewport[0], currentViewport[1], currentViewport[2], currentViewport[3]);
+ _shadowVolumeShader->use();
+ _shadowVolumeShader->setUniform("viewMatrix", viewMatrix);
+ _shadowVolumeShader->setUniform("projMatrix", projectionMatrix);
- glDisable(GL_DEPTH_WRITEMASK);
+ return true;
+}
- DXMatrix shadowPos;
- DXMatrixTranslation(&shadowPos, object->_posVector._x, object->_posVector._y, object->_posVector._z);
- DXMatrixTranspose(&shadowPos, &shadowPos);
+void BaseRenderOpenGL3DShader::setAmbientLightRenderState() {
+ byte a = RGBCOLGetA(_ambientLightColor);
+ byte r = RGBCOLGetR(_ambientLightColor);
+ byte g = RGBCOLGetG(_ambientLightColor);
+ byte b = RGBCOLGetB(_ambientLightColor);
- Math::Matrix4 viewMatrix, projectionMatrix, shadowPosition;
- viewMatrix.setData(_viewMatrix);
- projectionMatrix.setData(_projectionMatrix);
- shadowPosition.setData(shadowPos);
- _flatShadowMaskShader->use();
- _flatShadowMaskShader->setUniform("lightViewMatrix", lightViewMatrix);
- _flatShadowMaskShader->setUniform("worldMatrix", shadowPosition);
- _flatShadowMaskShader->setUniform("viewMatrix", viewMatrix);
- _flatShadowMaskShader->setUniform("projMatrix", projectionMatrix);
- _flatShadowMaskShader->setUniform("shadowColor", _flatShadowColor);
+ if (!_ambientLightOverride) {
+ uint32 color = _gameRef->getAmbientLightColor();
- glBindBuffer(GL_ARRAY_BUFFER, _flatShadowMaskVBO);
- glBindTexture(GL_TEXTURE_2D, _flatShadowRenderTexture);
+ a = RGBCOLGetA(color);
+ r = RGBCOLGetR(color);
+ g = RGBCOLGetG(color);
+ b = RGBCOLGetB(color);
+ }
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ Math::Vector4d value;
+ value.x() = r / 255.0f;
+ value.y() = g / 255.0f;
+ value.z() = b / 255.0f;
+ value.w() = a / 255.0f;
- glBindTexture(GL_TEXTURE_2D, 0);
+ _xmodelShader->use();
+ _xmodelShader->setUniform("ambientLight", value);
+}
- glEnable(GL_DEPTH_WRITEMASK);
+bool BaseRenderOpenGL3DShader::setupLines() {
+ if (_state != RSTATE_LINES) {
+ _state = RSTATE_LINES;
+
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ glBindTexture(GL_TEXTURE_2D, 0);
}
-}
-bool BaseRenderOpenGL3DShader::stencilSupported() {
- // assume that we have a stencil buffer
return true;
}
-BaseImage *BaseRenderOpenGL3DShader::takeScreenshot() {
- BaseImage *screenshot = new BaseImage();
- Graphics::Surface *surface = new Graphics::Surface();
-#ifdef SCUMM_BIG_ENDIAN
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
-#else
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 0, 8, 16, 24);
-#endif
- surface->create(_viewportRect.width(), _viewportRect.height(), format);
+bool BaseRenderOpenGL3DShader::drawSpriteEx(BaseSurfaceOpenGL3D &tex, const Wintermute::Rect32 &rect,
+ const Wintermute::Vector2 &pos, const Wintermute::Vector2 &rot,
+ const Wintermute::Vector2 &scale, float angle, uint32 color,
+ bool alphaDisable, Graphics::TSpriteBlendMode blendMode,
+ bool mirrorX, bool mirrorY) {
+ // original wme has a batch mode for sprites, we ignore this for the moment
- glReadPixels(_viewportRect.left, _viewportRect.height() - _viewportRect.bottom, _viewportRect.width(), _viewportRect.height(),
- GL_RGBA, GL_UNSIGNED_BYTE, surface->getPixels());
- flipVertical(surface);
- Graphics::Surface *converted = surface->convertTo(getPixelFormat());
- screenshot->copyFrom(converted);
- delete surface;
- delete converted;
- return screenshot;
-}
+ if (_forceAlphaColor != 0) {
+ color = _forceAlphaColor;
+ }
-void BaseRenderOpenGL3DShader::setWindowed(bool windowed) {
- ConfMan.setBool("fullscreen", !windowed);
- g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !windowed);
- g_system->endGFXTransaction();
-}
+ float width = (rect.right - rect.left) * scale.x;
+ float height = (rect.bottom - rect.top) * scale.y;
-void BaseRenderOpenGL3DShader::fadeToColor(byte r, byte g, byte b, byte a) {
- setProjection2D();
+ glBindTexture(GL_TEXTURE_2D, tex.getTextureName());
- Math::Vector4d color;
- color.x() = r / 255.0f;
- color.y() = g / 255.0f;
- color.z() = b / 255.0f;
- color.w() = a / 255.0f;
+ // for sprites we clamp to the edge, to avoid line fragments at the edges
+ // this is not done by wme, though
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, 0);
- glBindBuffer(GL_ARRAY_BUFFER, _fadeVBO);
+ int texWidth = tex.getGLTextureWidth();
+ int texHeight = tex.getGLTextureHeight();
- Math::Matrix4 projectionMatrix2d;
- projectionMatrix2d.setData(_projectionMatrix2d);
- _fadeShader->use();
- _fadeShader->setUniform("color", color);
- _fadeShader->setUniform("projMatrix", projectionMatrix2d);
+ float texLeft = (float)rect.left / (float)texWidth;
+ float texTop = (float)rect.top / (float)texHeight;
+ float texRight = (float)rect.right / (float)texWidth;
+ float texBottom = (float)rect.bottom / (float)texHeight;
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ float offset = _height / 2.0f;
+ float correctedYPos = (pos.y - offset) * -1.0f + offset;
- setup2D(true);
-}
+ if (mirrorX) {
+ SWAP(texLeft, texRight);
+ }
-bool BaseRenderOpenGL3DShader::fill(byte r, byte g, byte b, Common::Rect *rect) {
- glClearColor(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- return true;
-}
+ if (mirrorY) {
+ SWAP(texTop, texBottom);
+ }
-bool BaseRenderOpenGL3DShader::setViewport(int left, int top, int right, int bottom) {
- _viewportRect.setRect(left, top, right, bottom);
- _viewport._x = left;
- _viewport._y = top;
- _viewport._width = right - left;
- _viewport._height = bottom - top;
- _viewport._minZ = 0.0f;
- _viewport._maxZ = 1.0f;
- glViewport(left, _height - bottom, right - left, bottom - top);
- glDepthRange(_viewport._minZ, _viewport._maxZ);
- return true;
-}
+ SpriteVertexShader vertices[4] = {};
-bool BaseRenderOpenGL3DShader::setViewport3D(DXViewport *viewport) {
- _viewport = *viewport;
- glViewport(_viewport._x, _height - _viewport._height, _viewport._width, _viewport._height);
- glDepthRange(_viewport._minZ, _viewport._maxZ);
- return true;
-}
+ // texture coords
+ vertices[0].u = texLeft;
+ vertices[0].v = texTop;
-bool BaseRenderOpenGL3DShader::drawLine(int x1, int y1, int x2, int y2, uint32 color) {
- glBindBuffer(GL_ARRAY_BUFFER, _lineVBO);
+ vertices[1].u = texLeft;
+ vertices[1].v = texBottom;
- float lineCoords[4];
+ vertices[2].u = texRight;
+ vertices[2].v = texTop;
- lineCoords[0] = x1;
- lineCoords[1] = _height - y1;
- lineCoords[2] = x2;
- lineCoords[3] = _height - y2;
+ vertices[3].u = texRight;
+ vertices[3].v = texBottom;
- glBufferSubData(GL_ARRAY_BUFFER, 0, 2 * 8, lineCoords);
+ // position coords
+ vertices[0].x = pos.x;
+ vertices[0].y = correctedYPos;
+
+ vertices[1].x = pos.x;
+ vertices[1].y = correctedYPos - height;
+
+ vertices[2].x = pos.x + width;
+ vertices[2].y = correctedYPos;
+
+ vertices[3].x = pos.x + width;
+ vertices[3].y = correctedYPos - height;
+ // not exactly sure about the color format, but this seems to work
byte a = RGBCOLGetA(color);
byte r = RGBCOLGetR(color);
byte g = RGBCOLGetG(color);
byte b = RGBCOLGetB(color);
- Math::Vector4d colorValue;
- colorValue.x() = r / 255.0f;
- colorValue.y() = g / 255.0f;
- colorValue.z() = b / 255.0f;
- colorValue.w() = a / 255.0f;
+ for (int i = 0; i < 4; ++i) {
+ vertices[i].r = r / 255.0f;
+ vertices[i].g = g / 255.0f;
+ vertices[i].b = b / 255.0f;
+ vertices[i].a = a / 255.0f;
+ }
+
+ Math::Matrix3 transform;
+ transform.setToIdentity();
+
+ if (angle != 0) {
+ Vector2 correctedRot(rot.x, (rot.y - offset) * -1.0f + offset);
+ transform = build2dTransformation(correctedRot, angle);
+ transform.transpose();
+ }
Math::Matrix4 projectionMatrix2d;
projectionMatrix2d.setData(_projectionMatrix2d);
- _lineShader->use();
- _lineShader->setUniform("color", colorValue);
- _lineShader->setUniform("projMatrix", projectionMatrix2d);
+ _spriteShader->use();
+ _spriteShader->setUniform("alphaTest", !alphaDisable);
+ _spriteShader->setUniform("transform", transform);
+ _spriteShader->setUniform("projMatrix", projectionMatrix2d);
- glDrawArrays(GL_LINES, 0, 2);
+ glBindBuffer(GL_ARRAY_BUFFER, _spriteVBO);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, 4 * sizeof(SpriteVertexShader), vertices);
+
+ setSpriteBlendMode(blendMode);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
return true;
}
@@ -504,55 +452,38 @@ bool BaseRenderOpenGL3DShader::setProjection() {
return setProjectionTransform(matProj);
}
-bool BaseRenderOpenGL3DShader::setProjection2D() {
- float nearPlane = -1.0f;
- float farPlane = 100.0f;
-
- DXMatrixIdentity(&_projectionMatrix2d);
-
- _projectionMatrix2d.matrix._11 = 2.0f / _width;
- _projectionMatrix2d.matrix._22 = 2.0f / _height;
- _projectionMatrix2d.matrix._33 = 2.0f / (farPlane - nearPlane);
-
- _projectionMatrix2d.matrix._41 = -1.0f;
- _projectionMatrix2d.matrix._42 = -1.0f;
- _projectionMatrix2d.matrix._43 = -(farPlane + nearPlane) / (farPlane - nearPlane);
+bool BaseRenderOpenGL3DShader::drawLine(int x1, int y1, int x2, int y2, uint32 color) {
+ glBindBuffer(GL_ARRAY_BUFFER, _lineVBO);
- Math::Matrix4 projectionMatrix2d;
- projectionMatrix2d.setData(_projectionMatrix2d);
- _shadowMaskShader->use();
- _shadowMaskShader->setUniform("projMatrix", projectionMatrix2d);
- return true;
-}
+ float lineCoords[4];
-bool BaseRenderOpenGL3DShader::setWorldTransform(const DXMatrix &transform) {
- _worldMatrix = transform;
- DXMatrix newInvertedTranspose, world = transform;
- DXMatrixMultiply(&newInvertedTranspose, &world, &_viewMatrix);
- DXMatrixInverse(&newInvertedTranspose, nullptr, &newInvertedTranspose);
- DXMatrixTranspose(&newInvertedTranspose, &newInvertedTranspose);
+ lineCoords[0] = x1;
+ lineCoords[1] = _height - y1;
+ lineCoords[2] = x2;
+ lineCoords[3] = _height - y2;
- Math::Matrix4 modelMatrix, normalMatrix;
- modelMatrix.setData(world);
- normalMatrix.setData(newInvertedTranspose);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, 2 * 8, lineCoords);
- _xmodelShader->use();
- _xmodelShader->setUniform("modelMatrix", modelMatrix);
- _xmodelShader->setUniform("normalMatrix", normalMatrix);
+ byte a = RGBCOLGetA(color);
+ byte r = RGBCOLGetR(color);
+ byte g = RGBCOLGetG(color);
+ byte b = RGBCOLGetB(color);
- _shadowVolumeShader->use();
- _shadowVolumeShader->setUniform("modelMatrix", modelMatrix);
+ Math::Vector4d colorValue;
+ colorValue.x() = r / 255.0f;
+ colorValue.y() = g / 255.0f;
+ colorValue.z() = b / 255.0f;
+ colorValue.w() = a / 255.0f;
- return true;
-}
+ Math::Matrix4 projectionMatrix2d;
+ projectionMatrix2d.setData(_projectionMatrix2d);
+ _lineShader->use();
+ _lineShader->setUniform("color", colorValue);
+ _lineShader->setUniform("projMatrix", projectionMatrix2d);
-bool BaseRenderOpenGL3DShader::setViewTransform(const DXMatrix &transform) {
- _viewMatrix = transform;
- return true;
-}
+ glDrawArrays(GL_LINES, 0, 2);
-bool BaseRenderOpenGL3DShader::setProjectionTransform(const DXMatrix &transform) {
- _projectionMatrix = transform;
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
return true;
}
@@ -561,337 +492,154 @@ bool BaseRenderOpenGL3DShader::windowedBlt() {
return true;
}
-void Wintermute::BaseRenderOpenGL3DShader::onWindowChange() {
- _windowed = !g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
-}
+void BaseRenderOpenGL3DShader::fadeToColor(byte r, byte g, byte b, byte a) {
+ setProjection2D();
-bool BaseRenderOpenGL3DShader::initRenderer(int width, int height, bool windowed) {
- glGenBuffers(1, &_spriteVBO);
- glBindBuffer(GL_ARRAY_BUFFER, _spriteVBO);
- glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(SpriteVertexShader), nullptr, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- static const char *spriteAttributes[] = {"position", "texcoord", "color", nullptr};
- _spriteShader = OpenGL::Shader::fromFiles("wme_sprite", spriteAttributes);
-
- _spriteShader->enableVertexAttribute("position", _spriteVBO, 2, GL_FLOAT, false, sizeof(SpriteVertexShader), 0);
- _spriteShader->enableVertexAttribute("texcoord", _spriteVBO, 2, GL_FLOAT, false, sizeof(SpriteVertexShader), 8);
- _spriteShader->enableVertexAttribute("color", _spriteVBO, 4, GL_FLOAT, false, sizeof(SpriteVertexShader), 16);
-
- static const char *geometryAttributes[] = { "position", "color", nullptr };
- _geometryShader = OpenGL::Shader::fromFiles("wme_geometry", geometryAttributes);
-
- static const char *shadowVolumeAttributes[] = { "position", nullptr };
- _shadowVolumeShader = OpenGL::Shader::fromFiles("wme_shadow_volume", shadowVolumeAttributes);
-
- static const char *shadowMaskAttributes[] = { "position", nullptr };
- _shadowMaskShader = OpenGL::Shader::fromFiles("wme_shadow_mask", shadowMaskAttributes);
-
- DXMatrix m;
- DXMatrixIdentity(&m);
- _transformStack.push_back(m);
-
- static const char *XModelAttributes[] = {"position", "texcoord", "normal", nullptr};
- _xmodelShader = OpenGL::Shader::fromFiles("wme_modelx", XModelAttributes);
-
- setDefaultAmbientLightColor();
-
- for (int i = 0; i < getMaxActiveLights(); ++i) {
- setLightParameters(i, DXVector3(0, 0, 0), DXVector3(0, 0, 0), DXVector4(0, 0, 0, 0), false);
- lightEnable(i, false);
- }
-
- _windowed = !ConfMan.getBool("fullscreen");
- _width = width;
- _height = height;
-
- _nearClipPlane = 90.0f;
- _farClipPlane = 10000.0f;
-
- setViewport(0, 0, width, height);
-
- float fadeVertexCoords[8];
-
- fadeVertexCoords[0 * 2 + 0] = _viewportRect.left;
- fadeVertexCoords[0 * 2 + 1] = _viewportRect.bottom;
- fadeVertexCoords[1 * 2 + 0] = _viewportRect.left;
- fadeVertexCoords[1 * 2 + 1] = _viewportRect.top;
- fadeVertexCoords[2 * 2 + 0] = _viewportRect.right;
- fadeVertexCoords[2 * 2 + 1] = _viewportRect.bottom;
- fadeVertexCoords[3 * 2 + 0] = _viewportRect.right;
- fadeVertexCoords[3 * 2 + 1] = _viewportRect.top;
+ Math::Vector4d color;
+ color.x() = r / 255.0f;
+ color.y() = g / 255.0f;
+ color.z() = b / 255.0f;
+ color.w() = a / 255.0f;
- glGenBuffers(1, &_fadeVBO);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, 0);
glBindBuffer(GL_ARRAY_BUFFER, _fadeVBO);
- glBufferData(GL_ARRAY_BUFFER, 4 * 8, fadeVertexCoords, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- static const char *fadeAttributes[] = { "position", nullptr };
- _fadeShader = OpenGL::Shader::fromFiles("wme_fade", fadeAttributes);
- _fadeShader->enableVertexAttribute("position", _fadeVBO, 2, GL_FLOAT, false, 8, 0);
-
- glGenBuffers(1, &_lineVBO);
- glBindBuffer(GL_ARRAY_BUFFER, _lineVBO);
- glBufferData(GL_ARRAY_BUFFER, 2 * 8, nullptr, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- static const char *lineAttributes[] = { "position", nullptr };
- _lineShader = OpenGL::Shader::fromFiles("wme_line", lineAttributes);
- _lineShader->enableVertexAttribute("position", _lineVBO, 2, GL_FLOAT, false, 8, 0);
+ Math::Matrix4 projectionMatrix2d;
+ projectionMatrix2d.setData(_projectionMatrix2d);
+ _fadeShader->use();
+ _fadeShader->setUniform("color", color);
+ _fadeShader->setUniform("projMatrix", projectionMatrix2d);
- static const char *flatShadowXModelAttributes[] = { "position", nullptr };
- _flatShadowXModelShader = OpenGL::Shader::fromFiles("wme_flat_shadow_modelx", flatShadowXModelAttributes);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- _active = true;
+ setup2D(true);
+}
- setProjection();
+BaseImage *BaseRenderOpenGL3DShader::takeScreenshot() {
+ BaseImage *screenshot = new BaseImage();
+ Graphics::Surface *surface = new Graphics::Surface();
+#ifdef SCUMM_BIG_ENDIAN
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+ surface->create(_viewportRect.width(), _viewportRect.height(), format);
- return true;
+ glReadPixels(_viewportRect.left, _viewportRect.height() - _viewportRect.bottom, _viewportRect.width(), _viewportRect.height(),
+ GL_RGBA, GL_UNSIGNED_BYTE, surface->getPixels());
+ flipVertical(surface);
+ Graphics::Surface *converted = surface->convertTo(getPixelFormat());
+ screenshot->copyFrom(converted);
+ delete surface;
+ delete converted;
+ return screenshot;
}
-bool Wintermute::BaseRenderOpenGL3DShader::flip() {
- g_system->updateScreen();
+bool BaseRenderOpenGL3DShader::enableShadows() {
+ warning("BaseRenderOpenGL3DShader::disableShadows not implemented yet");
return true;
}
-bool BaseRenderOpenGL3DShader::indicatorFlip() {
- flip();
+bool BaseRenderOpenGL3DShader::disableShadows() {
+ warning("BaseRenderOpenGL3DShader::disableShadows not implemented yet");
return true;
}
-bool BaseRenderOpenGL3DShader::forcedFlip() {
- flip();
- return true;
+void BaseRenderOpenGL3DShader::displayShadow(BaseObject *object, const DXVector3 *lightPos, bool lightPosRelative) {
+ // TODO: to be implemented
+ return;
}
-bool BaseRenderOpenGL3DShader::setup2D(bool force) {
- if (_state != RSTATE_2D || force) {
- _state = RSTATE_2D;
-
- // some states are still missing here
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_STENCIL_TEST);
-
- glEnable(GL_CULL_FACE);
- glFrontFace(GL_CCW);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glViewport(0, 0, _width, _height);
-
- setProjection2D();
- }
-
+bool BaseRenderOpenGL3DShader::stencilSupported() {
+ // assume that we have a stencil buffer
return true;
}
-bool BaseRenderOpenGL3DShader::setup3D(Camera3D *camera, bool force) {
- if (_state != RSTATE_3D || force) {
- _state = RSTATE_3D;
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
-
- setAmbientLightRenderState();
-
- if (camera)
- _camera = camera;
- if (_camera) {
- DXMatrix viewMatrix;
- _camera->getViewMatrix(&viewMatrix);
- setViewTransform(viewMatrix);
-
- _fov = _camera->_fov;
-
- if (_camera->_nearClipPlane >= 0.0f) {
- _nearClipPlane = _camera->_nearClipPlane;
- } else {
- _nearClipPlane = DEFAULT_NEAR_PLANE;
- }
-
- if (_camera->_farClipPlane >= 0.0f) {
- _farClipPlane = _camera->_farClipPlane;
- } else {
- _farClipPlane = DEFAULT_FAR_PLANE;
- }
- } else {
- _nearClipPlane = DEFAULT_NEAR_PLANE;
- _farClipPlane = DEFAULT_FAR_PLANE;
- }
-
- bool fogEnabled;
- uint32 fogColor;
- float fogStart, fogEnd;
+void BaseRenderOpenGL3DShader::setSpriteBlendMode(Graphics::TSpriteBlendMode blendMode) {
+ switch (blendMode) {
+ case Graphics::BLEND_NORMAL:
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ break;
- _gameRef->getFogParams(&fogEnabled, &fogColor, &fogStart, &fogEnd);
- if (fogEnabled) {
- // TODO: Implement fog
- GLfloat color[4];
- color[0] = RGBCOLGetR(fogColor) / 255.0f;
- color[1] = RGBCOLGetG(fogColor) / 255.0f;
- color[2] = RGBCOLGetB(fogColor) / 255.0f;
- color[3] = RGBCOLGetA(fogColor) / 255.0f;
- debug(5, "BaseRenderOpenGL3DShader::setup3D fog not yet implemented! [%f %f %f %f]", color[0], color[1], color[2], color[3]);
- } else {
- // TODO: Disable fog in shader
- }
+ case Graphics::BLEND_ADDITIVE:
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ break;
- glViewport(_viewportRect.left, _height - _viewportRect.bottom, _viewportRect.width(), _viewportRect.height());
+ case Graphics::BLEND_SUBTRACTIVE:
+ // wme3d takes the color value here
+ glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
+ break;
- setProjection();
+ default:
+ warning("BaseRenderOpenGL3DShader::setSpriteBlendMode unsupported blend mode %i", blendMode);
}
-
- Math::Matrix4 viewMatrix, projectionMatrix;
- viewMatrix.setData(_viewMatrix);
- projectionMatrix.setData(_projectionMatrix);
- _xmodelShader->use();
- _xmodelShader->setUniform("viewMatrix", viewMatrix);
- _xmodelShader->setUniform("projMatrix", projectionMatrix);
- // this is 8 / 255, since 8 is the value used by wme (as a DWORD)
- _xmodelShader->setUniform1f("alphaRef", 0.031f);
-
- _geometryShader->use();
- _geometryShader->setUniform("viewMatrix", viewMatrix);
- _geometryShader->setUniform("projMatrix", projectionMatrix);
-
- _shadowVolumeShader->use();
- _shadowVolumeShader->setUniform("viewMatrix", viewMatrix);
- _shadowVolumeShader->setUniform("projMatrix", projectionMatrix);
-
- return true;
}
-bool BaseRenderOpenGL3DShader::setupLines() {
- if (_state != RSTATE_LINES) {
- _state = RSTATE_LINES;
-
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
-
- return true;
+int BaseRenderOpenGL3DShader::getMaxActiveLights() {
+ return 8;
}
-BaseSurface *Wintermute::BaseRenderOpenGL3DShader::createSurface() {
- return new BaseSurfaceOpenGL3D(_gameRef, this);
+// implements D3D LightEnable()
+void BaseRenderOpenGL3DShader::lightEnable(int index, bool enable) {
+ _xmodelShader->use();
+ Common::String uniform = Common::String::format("lights[%i].enabled", index);
+ if (enable)
+ _xmodelShader->setUniform1f(uniform.c_str(), 1.0f);
+ else
+ _xmodelShader->setUniform1f(uniform.c_str(), -1.0f);
}
-bool BaseRenderOpenGL3DShader::drawSpriteEx(BaseSurfaceOpenGL3D &tex, const Wintermute::Rect32 &rect,
- const Wintermute::Vector2 &pos, const Wintermute::Vector2 &rot,
- const Wintermute::Vector2 &scale, float angle, uint32 color,
- bool alphaDisable, Graphics::TSpriteBlendMode blendMode,
- bool mirrorX, bool mirrorY) {
- // original wme has a batch mode for sprites, we ignore this for the moment
-
- if (_forceAlphaColor != 0) {
- color = _forceAlphaColor;
- }
-
- float width = (rect.right - rect.left) * scale.x;
- float height = (rect.bottom - rect.top) * scale.y;
-
- glBindTexture(GL_TEXTURE_2D, tex.getTextureName());
-
- // for sprites we clamp to the edge, to avoid line fragments at the edges
- // this is not done by wme, though
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- int texWidth = tex.getGLTextureWidth();
- int texHeight = tex.getGLTextureHeight();
-
- float texLeft = (float)rect.left / (float)texWidth;
- float texTop = (float)rect.top / (float)texHeight;
- float texRight = (float)rect.right / (float)texWidth;
- float texBottom = (float)rect.bottom / (float)texHeight;
-
- float offset = _height / 2.0f;
- float correctedYPos = (pos.y - offset) * -1.0f + offset;
-
- if (mirrorX) {
- SWAP(texLeft, texRight);
- }
-
- if (mirrorY) {
- SWAP(texTop, texBottom);
- }
-
- SpriteVertexShader vertices[4] = {};
-
- // texture coords
- vertices[0].u = texLeft;
- vertices[0].v = texTop;
-
- vertices[1].u = texLeft;
- vertices[1].v = texBottom;
-
- vertices[2].u = texRight;
- vertices[2].v = texTop;
-
- vertices[3].u = texRight;
- vertices[3].v = texBottom;
-
- // position coords
- vertices[0].x = pos.x;
- vertices[0].y = correctedYPos;
-
- vertices[1].x = pos.x;
- vertices[1].y = correctedYPos - height;
-
- vertices[2].x = pos.x + width;
- vertices[2].y = correctedYPos;
-
- vertices[3].x = pos.x + width;
- vertices[3].y = correctedYPos - height;
+// backend layer 3DLight::SetLight
+void BaseRenderOpenGL3DShader::setLightParameters(int index, const DXVector3 &position,
+ const DXVector3 &direction,
+ const DXVector4 &diffuse, bool spotlight) {
+ Math::Vector4d position4d;
+ position4d.x() = position._x;
+ position4d.y() = position._y;
+ position4d.z() = position._z;
+ position4d.w() = 1.0f;
- // not exactly sure about the color format, but this seems to work
- byte a = RGBCOLGetA(color);
- byte r = RGBCOLGetR(color);
- byte g = RGBCOLGetG(color);
- byte b = RGBCOLGetB(color);
+ Math::Vector4d direction4d;
+ direction4d.x() = direction._x;
+ direction4d.y() = direction._y;
+ direction4d.z() = direction._z;
+ direction4d.w() = 0.0f;
- for (int i = 0; i < 4; ++i) {
- vertices[i].r = r / 255.0f;
- vertices[i].g = g / 255.0f;
- vertices[i].b = b / 255.0f;
- vertices[i].a = a / 255.0f;
+ if (spotlight) {
+ direction4d.w() = -1.0f;
}
- Math::Matrix3 transform;
- transform.setToIdentity();
+ Math::Vector4d diffuse4d;
+ diffuse4d.x() = diffuse._x;
+ diffuse4d.y() = diffuse._y;
+ diffuse4d.z() = diffuse._z;
+ diffuse4d.w() = 0.0f;
- if (angle != 0) {
- Vector2 correctedRot(rot.x, (rot.y - offset) * -1.0f + offset);
- transform = build2dTransformation(correctedRot, angle);
- transform.transpose();
- }
- Math::Matrix4 projectionMatrix2d;
- projectionMatrix2d.setData(_projectionMatrix2d);
- _spriteShader->use();
- _spriteShader->setUniform("alphaTest", !alphaDisable);
- _spriteShader->setUniform("transform", transform);
- _spriteShader->setUniform("projMatrix", projectionMatrix2d);
-
- glBindBuffer(GL_ARRAY_BUFFER, _spriteVBO);
- glBufferSubData(GL_ARRAY_BUFFER, 0, 4 * sizeof(SpriteVertexShader), vertices);
+ _xmodelShader->use();
- setSpriteBlendMode(blendMode);
+ Common::String uniform = Common::String::format("lights[%i]._position", index);
+ _xmodelShader->setUniform(uniform.c_str(), position4d);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ uniform = Common::String::format("lights[%i]._direction", index);
+ _xmodelShader->setUniform(uniform.c_str(), direction4d);
- return true;
+ uniform = Common::String::format("lights[%i]._color", index);
+ _xmodelShader->setUniform(uniform.c_str(), diffuse4d);
}
+// backend layer AdSceneGeometry::Render
void BaseRenderOpenGL3DShader::renderSceneGeometry(const BaseArray<AdWalkplane *> &planes, const BaseArray<AdBlock *> &blocks,
- const BaseArray<AdGeneric *> &generics, const BaseArray<Light3D *> &lights, Camera3D *camera) {
+ const BaseArray<AdGeneric *> &generics, const BaseArray<Light3D *> &lights, Camera3D *camera) {
// don't render scene geometry, as OpenGL ES 2 has no wireframe rendering and we don't have a shader alternative yet
}
+// backend layer 3DShadowVolume::Render()
void BaseRenderOpenGL3DShader::renderShadowGeometry(const BaseArray<AdWalkplane *> &planes, const BaseArray<AdBlock *> &blocks,
- const BaseArray<AdGeneric *> &generics, Camera3D *camera) {
+ const BaseArray<AdGeneric *> &generics, Camera3D *camera) {
DXMatrix matIdentity;
DXMatrixIdentity(&matIdentity);
@@ -930,6 +678,115 @@ void BaseRenderOpenGL3DShader::renderShadowGeometry(const BaseArray<AdWalkplane
setSpriteBlendMode(Graphics::BLEND_NORMAL);
}
+// implements D3D SetRenderState() D3DRS_CULLMODE - CCW
+void BaseRenderOpenGL3DShader::enableCulling() {
+ glFrontFace(GL_CW);
+ glEnable(GL_CULL_FACE);
+}
+
+// implements D3D SetRenderState() D3DRS_CULLMODE - NONE
+void BaseRenderOpenGL3DShader::disableCulling() {
+ glDisable(GL_CULL_FACE);
+}
+
+void BaseRenderOpenGL3DShader::setWindowed(bool windowed) {
+ ConfMan.setBool("fullscreen", !windowed);
+ g_system->beginGFXTransaction();
+ g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !windowed);
+ g_system->endGFXTransaction();
+}
+
+// implements D3D SetViewport() for 2D viewport
+bool BaseRenderOpenGL3DShader::setViewport(int left, int top, int right, int bottom) {
+ _viewportRect.setRect(left, top, right, bottom);
+ _viewport._x = left;
+ _viewport._y = top;
+ _viewport._width = right - left;
+ _viewport._height = bottom - top;
+ _viewport._minZ = 0.0f;
+ _viewport._maxZ = 1.0f;
+ glViewport(left, _height - bottom, right - left, bottom - top);
+ glDepthRange(_viewport._minZ, _viewport._maxZ);
+ return true;
+}
+
+// implements D3D SetViewport() for 3D viewport
+bool BaseRenderOpenGL3DShader::setViewport3D(DXViewport *viewport) {
+ _viewport = *viewport;
+ glViewport(_viewport._x, _height - _viewport._height, _viewport._width, _viewport._height);
+ glDepthRange(_viewport._minZ, _viewport._maxZ);
+ return true;
+}
+
+bool BaseRenderOpenGL3DShader::setProjection2D() {
+ float nearPlane = -1.0f;
+ float farPlane = 100.0f;
+
+ DXMatrixIdentity(&_projectionMatrix2d);
+
+ _projectionMatrix2d.matrix._11 = 2.0f / _width;
+ _projectionMatrix2d.matrix._22 = 2.0f / _height;
+ _projectionMatrix2d.matrix._33 = 2.0f / (farPlane - nearPlane);
+
+ _projectionMatrix2d.matrix._41 = -1.0f;
+ _projectionMatrix2d.matrix._42 = -1.0f;
+ _projectionMatrix2d.matrix._43 = -(farPlane + nearPlane) / (farPlane - nearPlane);
+
+ Math::Matrix4 projectionMatrix2d;
+ projectionMatrix2d.setData(_projectionMatrix2d);
+ _shadowMaskShader->use();
+ _shadowMaskShader->setUniform("projMatrix", projectionMatrix2d);
+ return true;
+}
+
+// implements SetTransform() D3DTS_WORLD
+bool BaseRenderOpenGL3DShader::setWorldTransform(const DXMatrix &transform) {
+ _worldMatrix = transform;
+ DXMatrix newInvertedTranspose, world = transform;
+ DXMatrixMultiply(&newInvertedTranspose, &world, &_viewMatrix);
+ DXMatrixInverse(&newInvertedTranspose, nullptr, &newInvertedTranspose);
+ DXMatrixTranspose(&newInvertedTranspose, &newInvertedTranspose);
+
+ Math::Matrix4 modelMatrix, normalMatrix;
+ modelMatrix.setData(world);
+ normalMatrix.setData(newInvertedTranspose);
+
+ _xmodelShader->use();
+ _xmodelShader->setUniform("modelMatrix", modelMatrix);
+ _xmodelShader->setUniform("normalMatrix", normalMatrix);
+
+ _shadowVolumeShader->use();
+ _shadowVolumeShader->setUniform("modelMatrix", modelMatrix);
+
+ return true;
+}
+
+// implements SetTransform() D3DTS_WIEW
+bool BaseRenderOpenGL3DShader::setViewTransform(const DXMatrix &transform) {
+ _viewMatrix = transform;
+ return true;
+}
+
+// implements SetTransform() D3DTS_PROJECTION
+bool BaseRenderOpenGL3DShader::setProjectionTransform(const DXMatrix &transform) {
+ _projectionMatrix = transform;
+ return true;
+}
+
+bool BaseRenderOpenGL3DShader::indicatorFlip() {
+ flip();
+ return true;
+}
+
+bool BaseRenderOpenGL3DShader::forcedFlip() {
+ flip();
+ return true;
+}
+
+BaseSurface *Wintermute::BaseRenderOpenGL3DShader::createSurface() {
+ return new BaseSurfaceOpenGL3D(_gameRef, this);
+}
+
Mesh3DS *BaseRenderOpenGL3DShader::createMesh3DS() {
return new Mesh3DSOpenGLShader(_gameRef, _geometryShader);
}
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
index 443abfb84e2..c9d0c432a3b 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
@@ -133,13 +133,10 @@ private:
Common::Array<DXMatrix> _transformStack;
Math::Vector4d _flatShadowColor;
- int _shadowTextureWidth;
- int _shadowTextureHeight;
GLuint _spriteVBO;
GLuint _fadeVBO;
GLuint _lineVBO;
- GLuint _flatShadowMaskVBO;
GLuint _flatShadowFrameBuffer;
GLuint _flatShadowRenderTexture;
GLuint _flatShadowDepthBuffer;
More information about the Scummvm-git-logs
mailing list