[Scummvm-git-logs] scummvm master -> 6a88a4c06827659d49364b645a1929e785370619
neuromancer
noreply at scummvm.org
Sat Nov 23 08:01:25 UTC 2024
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
0edaf859d3 FREESCAPE: more tinygl fixes to avoid rounding issues
66df0b3f54 FREESCAPE: tweak glPolygonOffset values
867960e60d FREESCAPE: added 3D textures to TinyGL and implemented background for castle
4ceba8c1f8 FREESCAPE: refactored and unified getRGBAPixelFormat across all the codebase
6a88a4c068 FREESCAPE: first attempt to implement stipple patterns in TinyGL using textures
Commit: 0edaf859d34e656a78629df15dc8bc5e2d2f518e
https://github.com/scummvm/scummvm/commit/0edaf859d34e656a78629df15dc8bc5e2d2f518e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-11-23T09:01:43+01:00
Commit Message:
FREESCAPE: more tinygl fixes to avoid rounding issues
Changed paths:
engines/freescape/area.cpp
engines/freescape/gfx.cpp
engines/freescape/gfx_tinygl.cpp
diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 30e204af6b0..039bac55de9 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -241,7 +241,7 @@ void Area::draw(Freescape::Renderer *gfx, uint32 animationTicks, Math::Vector3d
ObjectArray nonPlanarObjects;
Object *floor = nullptr;
Common::HashMap<Object *, float> sizes;
- float offset = (gfx->_isAccelerated ? 1.0 : 2.0) / _scale;
+ float offset = 1.0 / _scale;
for (auto &obj : _drawableObjects) {
if (!obj->isDestroyed() && !obj->isInvisible()) {
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 4f4cfe17d02..e4a0c6614a9 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -955,6 +955,9 @@ void Renderer::renderRectangle(const Math::Vector3d &originalOrigin, const Math:
Math::Vector3d size = originalSize;
Math::Vector3d origin = originalOrigin;
+ if (!_isAccelerated)
+ polygonOffset(true);
+
if (size.x() > 0 && size.y() > 0 && size.z() > 0) {
/* According to https://www.shdon.com/freescape/
If the bounding box is has all non-zero dimensions
@@ -1091,6 +1094,10 @@ void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d
}
polygonOffset(false);
} else {
+
+ if (!_isAccelerated)
+ polygonOffset(true);
+
if (size.x() == 0) {
for (int i = 0; i < int(ordinates->size()); i++) {
if (i % 3 == 0)
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 434da92facf..e1230a8395f 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -273,7 +273,7 @@ void TinyGLRenderer::useStipple(bool enabled) {
TGLfloat factor = 0;
tglGetFloatv(TGL_POLYGON_OFFSET_FACTOR, &factor);
tglEnable(TGL_POLYGON_OFFSET_FILL);
- tglPolygonOffset(factor - 5.0f, -1.0f);
+ tglPolygonOffset(factor - 1.0f, -1.0f);
tglEnable(TGL_POLYGON_STIPPLE);
if (_renderMode == Common::kRenderZX ||
_renderMode == Common::kRenderCPC ||
@@ -405,7 +405,7 @@ void TinyGLRenderer::depthTesting(bool enabled) {
void TinyGLRenderer::polygonOffset(bool enabled) {
if (enabled) {
tglEnable(TGL_POLYGON_OFFSET_FILL);
- tglPolygonOffset(-10.0f, 1.0f);
+ tglPolygonOffset(-1.0f, 1.0f);
} else {
tglPolygonOffset(0, 0);
tglDisable(TGL_POLYGON_OFFSET_FILL);
Commit: 66df0b3f5417f70e4762a827193c92e523fff103
https://github.com/scummvm/scummvm/commit/66df0b3f5417f70e4762a827193c92e523fff103
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-11-23T09:01:43+01:00
Commit Message:
FREESCAPE: tweak glPolygonOffset values
Changed paths:
engines/freescape/gfx_opengl.cpp
engines/freescape/gfx_tinygl.cpp
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 15ed174e24c..148728925ec 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -492,7 +492,7 @@ void OpenGLRenderer::depthTesting(bool enabled) {
void OpenGLRenderer::polygonOffset(bool enabled) {
if (enabled) {
glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-10.0f, 1.0f);
+ glPolygonOffset(-1.0f, 1.0f);
} else {
glPolygonOffset(0, 0);
glDisable(GL_POLYGON_OFFSET_FILL);
@@ -513,7 +513,7 @@ void OpenGLRenderer::useStipple(bool enabled) {
GLfloat factor = 0;
glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor);
glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(factor - 1.0f, -1.0f);
+ glPolygonOffset(factor - 0.5f, -1.0f);
glEnable(GL_POLYGON_STIPPLE);
if (_renderMode == Common::kRenderZX ||
_renderMode == Common::kRenderCPC ||
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index e1230a8395f..c1317a905fb 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -273,7 +273,7 @@ void TinyGLRenderer::useStipple(bool enabled) {
TGLfloat factor = 0;
tglGetFloatv(TGL_POLYGON_OFFSET_FACTOR, &factor);
tglEnable(TGL_POLYGON_OFFSET_FILL);
- tglPolygonOffset(factor - 1.0f, -1.0f);
+ tglPolygonOffset(factor - 0.5f, -1.0f);
tglEnable(TGL_POLYGON_STIPPLE);
if (_renderMode == Common::kRenderZX ||
_renderMode == Common::kRenderCPC ||
Commit: 867960e60d5b843a8a7b895e6eaa952d40eec5ee
https://github.com/scummvm/scummvm/commit/867960e60d5b843a8a7b895e6eaa952d40eec5ee
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-11-23T09:01:43+01:00
Commit Message:
FREESCAPE: added 3D textures to TinyGL and implemented background for castle
Changed paths:
engines/freescape/freescape.cpp
engines/freescape/gfx.h
engines/freescape/gfx_opengl.cpp
engines/freescape/gfx_opengl.h
engines/freescape/gfx_opengl_shaders.cpp
engines/freescape/gfx_opengl_shaders.h
engines/freescape/gfx_opengl_texture.cpp
engines/freescape/gfx_tinygl.cpp
engines/freescape/gfx_tinygl.h
engines/freescape/gfx_tinygl_texture.cpp
engines/freescape/gfx_tinygl_texture.h
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 35cb66a4009..c702ff6f82c 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -406,7 +406,7 @@ void FreescapeEngine::drawBackground() {
if (isCastle() && _background) {
if (!_skyTexture)
- _skyTexture = _gfx->createTexture(_background->surfacePtr());
+ _skyTexture = _gfx->createTexture(_background->surfacePtr(), true);
_gfx->drawSkybox(_skyTexture, _position);
}
}
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 25a14a3527e..19586fd3269 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -79,7 +79,7 @@ public:
virtual void depthTesting(bool enabled) {};
virtual void polygonOffset(bool enabled) = 0;
- virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
+ virtual Texture *createTexture(const Graphics::Surface *surface, bool is3D = false) = 0;
Graphics::Surface *convertImageFormatIfNecessary(Graphics::ManagedSurface *surface);
virtual void freeTexture(Texture *texture) = 0;
@@ -172,6 +172,91 @@ public:
byte *_variableStippleArray;
+ float _skyNormals[16][3] = {
+ { 0.0, 0.0, 1.0 }, //front //0
+ { 0.0, 0.0, 1.0 }, //1
+ { 0.0, 0.0, 1.0 }, //2
+ { 0.0, 0.0, 1.0 }, //3
+ { 0.0, 0.0, -1.0 }, //back //0
+ { 0.0, 0.0, -1.0 }, //1
+ { 0.0, 0.0, -1.0 }, //2
+ { 0.0, 0.0, -1.0 }, //3
+ { -1.0, 0.0, 0.0 }, //left
+ { -1.0, 0.0, 0.0 },
+ { -1.0, 0.0, 0.0 },
+ { -1.0, 0.0, 0.0 },
+ { 1.0, 0.0, 0.0 }, //right
+ { 1.0, 0.0, 0.0 },
+ { 1.0, 0.0, 0.0 },
+ { 1.0, 0.0, 0.0 }
+ };
+
+ float _skyUvs1008[16][2] = {
+ { 0.0f, 0.0f }, //1
+ { 0.0f, 2.0f }, //2
+ { 0.4f, 2.0f }, //3
+ { 0.4f, 0.0f }, //front //4
+
+ { 0.0f, 2.0f }, //back //1
+ { 0.4f, 2.0f }, //2
+ { 0.4f, 0.0f }, //3
+ { 0.0f, 0.0f }, //4
+
+ { 0.0f, 0.0f }, //left //1
+ { 0.4f, 0.0f }, //2
+ { 0.4f, 2.0f }, //3
+ { 0.0f, 2.0f }, //4
+
+ { 0.4f, 0.0f }, //right //1
+ { 0.0f, 0.0f }, //2
+ { 0.0f, 2.0f }, //3
+ { 0.4f, 2.0f }, //4
+ };
+
+ float _skyUvs128[16][2] = {
+ { 0.0f, 0.0f }, //1
+ { 0.0f, 2.0f }, //2
+ { 2.5f, 2.0f }, //3
+ { 2.5f, 0.0f }, //front //4
+
+ { 0.0f, 2.0f }, //back //1
+ { 2.5f, 2.0f }, //2
+ { 2.5f, 0.0f }, //3
+ { 0.0f, 0.0f }, //4
+
+ { 0.0f, 0.0f }, //left //1
+ { 2.5f, 0.0f }, //2
+ { 2.5f, 2.0f }, //3
+ { 0.0f, 2.0f }, //4
+
+ { 2.5f, 0.0f }, //right //1
+ { 0.0f, 0.0f }, //2
+ { 0.0f, 2.0f }, //3
+ { 2.5f, 2.0f }, //4
+ };
+
+ float _skyVertices[16][3] = {
+ { -81280.0, 8128.0, 81280.0 }, //1 // Vertex #0 front
+ { -81280.0, -8128.0, 81280.0 }, //2 // Vertex #1
+ { 81280.0, -8128.0, 81280.0 }, //3 // Vertex #2
+ { 81280.0, 8128.0, 81280.0 }, //4 // Vertex #3
+
+ { 81280.0f, -8128.0f, -81280.0f }, // 1
+ { -81280.0f, -8128.0f, -81280.0f }, // 2
+ { -81280.0f, 8128.0f, -81280.0f }, // 3
+ { 81280.0f, 8128.0f, -81280.0f }, // 4
+
+ { -81280.0f, 8128.0f, 81280.0f }, //left //1
+ { -81280.0f, 8128.0f, -81280.0f }, //2
+ { -81280.0f, -8128.0f, -81280.0f }, //3
+ { -81280.0f, -8128.0f, 81280.0f }, //4
+
+ { 81280.0f, 8128.0f, -81280.0f }, //right //1
+ { 81280.0f, 8128.0f, 81280.0f }, //2
+ { 81280.0f, -8128.0f, 81280.0f },//3
+ { 81280.0f, -8128.0f, -81280.0f },//4
+ };
+
byte *_palette;
void setColorMap(ColorMap *colorMap_);
ColorMap *_colorMap;
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 148728925ec..c518c89c3bd 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -51,7 +51,7 @@ OpenGLRenderer::~OpenGLRenderer() {
free(_coords);
}
-Texture *OpenGLRenderer::createTexture(const Graphics::Surface *surface) {
+Texture *OpenGLRenderer::createTexture(const Graphics::Surface *surface, bool is3D) {
return new OpenGLTexture(surface);
}
diff --git a/engines/freescape/gfx_opengl.h b/engines/freescape/gfx_opengl.h
index 43d8c1c30b8..5ed5a02326f 100644
--- a/engines/freescape/gfx_opengl.h
+++ b/engines/freescape/gfx_opengl.h
@@ -76,7 +76,7 @@ public:
virtual void depthTesting(bool enabled) override;
- Texture *createTexture(const Graphics::Surface *surface) override;
+ Texture *createTexture(const Graphics::Surface *surface, bool is3D = false) override;
void freeTexture(Texture *texture) override;
virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
@@ -93,90 +93,6 @@ public:
void drawSkybox(Texture *texture, Math::Vector3d camera) override;
virtual Graphics::Surface *getScreenshot() override;
- GLfloat _skyNormals[16][3] = {
- { 0.0, 0.0, 1.0 }, //front //0
- { 0.0, 0.0, 1.0 }, //1
- { 0.0, 0.0, 1.0 }, //2
- { 0.0, 0.0, 1.0 }, //3
- { 0.0, 0.0, -1.0 }, //back //0
- { 0.0, 0.0, -1.0 }, //1
- { 0.0, 0.0, -1.0 }, //2
- { 0.0, 0.0, -1.0 }, //3
- { -1.0, 0.0, 0.0 }, //left
- { -1.0, 0.0, 0.0 },
- { -1.0, 0.0, 0.0 },
- { -1.0, 0.0, 0.0 },
- { 1.0, 0.0, 0.0 }, //right
- { 1.0, 0.0, 0.0 },
- { 1.0, 0.0, 0.0 },
- { 1.0, 0.0, 0.0 }
- };
-
- GLfloat _skyUvs1008[16][2] = {
- { 0.0f, 0.0f }, //1
- { 0.0f, 2.0f }, //2
- { 0.4f, 2.0f }, //3
- { 0.4f, 0.0f }, //front //4
-
- { 0.0f, 2.0f }, //back //1
- { 0.4f, 2.0f }, //2
- { 0.4f, 0.0f }, //3
- { 0.0f, 0.0f }, //4
-
- { 0.0f, 0.0f }, //left //1
- { 0.4f, 0.0f }, //2
- { 0.4f, 2.0f }, //3
- { 0.0f, 2.0f }, //4
-
- { 0.4f, 0.0f }, //right //1
- { 0.0f, 0.0f }, //2
- { 0.0f, 2.0f }, //3
- { 0.4f, 2.0f }, //4
- };
-
- GLfloat _skyUvs128[16][2] = {
- { 0.0f, 0.0f }, //1
- { 0.0f, 2.0f }, //2
- { 2.5f, 2.0f }, //3
- { 2.5f, 0.0f }, //front //4
-
- { 0.0f, 2.0f }, //back //1
- { 2.5f, 2.0f }, //2
- { 2.5f, 0.0f }, //3
- { 0.0f, 0.0f }, //4
-
- { 0.0f, 0.0f }, //left //1
- { 2.5f, 0.0f }, //2
- { 2.5f, 2.0f }, //3
- { 0.0f, 2.0f }, //4
-
- { 2.5f, 0.0f }, //right //1
- { 0.0f, 0.0f }, //2
- { 0.0f, 2.0f }, //3
- { 2.5f, 2.0f }, //4
- };
-
- GLfloat _skyVertices[16][3] = {
- { -81280.0, 8128.0, 81280.0 }, //1 // Vertex #0 front
- { -81280.0, -8128.0, 81280.0 }, //2 // Vertex #1
- { 81280.0, -8128.0, 81280.0 }, //3 // Vertex #2
- { 81280.0, 8128.0, 81280.0 }, //4 // Vertex #3
-
- { 81280.0f, -8128.0f, -81280.0f }, // 1
- { -81280.0f, -8128.0f, -81280.0f }, // 2
- { -81280.0f, 8128.0f, -81280.0f }, // 3
- { 81280.0f, 8128.0f, -81280.0f }, // 4
-
- { -81280.0f, 8128.0f, 81280.0f }, //left //1
- { -81280.0f, 8128.0f, -81280.0f }, //2
- { -81280.0f, -8128.0f, -81280.0f }, //3
- { -81280.0f, -8128.0f, 81280.0f }, //4
-
- { 81280.0f, 8128.0f, -81280.0f }, //right //1
- { 81280.0f, 8128.0f, 81280.0f }, //2
- { 81280.0f, -8128.0f, 81280.0f },//3
- { 81280.0f, -8128.0f, -81280.0f },//4
- };
};
} // End of namespace Freescape
diff --git a/engines/freescape/gfx_opengl_shaders.cpp b/engines/freescape/gfx_opengl_shaders.cpp
index 7ff7e38df9d..f1898754188 100644
--- a/engines/freescape/gfx_opengl_shaders.cpp
+++ b/engines/freescape/gfx_opengl_shaders.cpp
@@ -64,7 +64,7 @@ OpenGLShaderRenderer::~OpenGLShaderRenderer() {
free(_verts);
}
-Texture *OpenGLShaderRenderer::createTexture(const Graphics::Surface *surface) {
+Texture *OpenGLShaderRenderer::createTexture(const Graphics::Surface *surface, bool is3D) {
return new OpenGLTexture(surface);
}
diff --git a/engines/freescape/gfx_opengl_shaders.h b/engines/freescape/gfx_opengl_shaders.h
index 33211f60392..d5d258cae7b 100644
--- a/engines/freescape/gfx_opengl_shaders.h
+++ b/engines/freescape/gfx_opengl_shaders.h
@@ -78,7 +78,7 @@ public:
virtual void setStippleData(byte *data) override;
virtual void useStipple(bool enabled) override;
- Texture *createTexture(const Graphics::Surface *surface) override;
+ Texture *createTexture(const Graphics::Surface *surface, bool is3D = false) override;
void freeTexture(Texture *texture) override;
virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
diff --git a/engines/freescape/gfx_opengl_texture.cpp b/engines/freescape/gfx_opengl_texture.cpp
index e9db5c3cd4a..bc68440908e 100644
--- a/engines/freescape/gfx_opengl_texture.cpp
+++ b/engines/freescape/gfx_opengl_texture.cpp
@@ -110,18 +110,7 @@ void OpenGLTexture::updateTexture(const Graphics::Surface *surface, const Common
assert(surface->format == _format);
glBindTexture(GL_TEXTURE_2D, _id);
-
- if (OpenGLContext.unpackSubImageSupported) {
- const Graphics::Surface subArea = surface->getSubArea(rect);
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format.bytesPerPixel);
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, subArea.w, subArea.h, _internalFormat, _sourceFormat, const_cast<void *>(subArea.getPixels()));
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- } else {
- // GL_UNPACK_ROW_LENGTH is not supported, don't bother and do a full texture update
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surface->w, surface->h, _internalFormat, _sourceFormat, const_cast<void *>(surface->getPixels()));
- }
+ glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat, surface->w, surface->h, 0, _internalFormat, _sourceFormat, const_cast<void *>(surface->getPixels()));
}
void OpenGLTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index c1317a905fb..c7a71f642be 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -39,7 +39,7 @@ Renderer *CreateGfxTinyGL(int screenW, int screenH, Common::RenderMode renderMod
TinyGLRenderer::TinyGLRenderer(int screenW, int screenH, Common::RenderMode renderMode) : Renderer(screenW, screenH, renderMode, true) {
_verts = (Vertex *)malloc(sizeof(Vertex) * kVertexArraySize);
- _texturePixelFormat = TinyGLTexture::getRGBAPixelFormat();
+ _texturePixelFormat = TinyGL2DTexture::getRGBAPixelFormat();
_variableStippleArray = nullptr;
}
@@ -48,13 +48,16 @@ TinyGLRenderer::~TinyGLRenderer() {
free(_verts);
}
-Texture *TinyGLRenderer::createTexture(const Graphics::Surface *surface) {
- return new TinyGLTexture(surface);
+Texture *TinyGLRenderer::createTexture(const Graphics::Surface *surface, bool is3D) {
+ if (is3D)
+ return new TinyGL3DTexture(surface);
+ else
+ return new TinyGL2DTexture(surface);
}
void TinyGLRenderer::freeTexture(Texture *texture) {
- TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
- delete glTexture;
+ //TinyGLTexture *glTexture = static_cast<TinyGLTexture *>(texture);
+ delete texture;
}
void TinyGLRenderer::init() {
@@ -92,7 +95,47 @@ void TinyGLRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Co
TinyGL::BlitTransform transform(sLeft + viewPort[0], sTop + viewPort[1]);
transform.sourceRectangle(textureRect.left, textureRect.top, sWidth, sHeight);
- tglBlit(((TinyGLTexture *)texture)->getBlitTexture(), transform);
+ tglBlit(((TinyGL2DTexture *)texture)->getBlitTexture(), transform);
+}
+
+void TinyGLRenderer::drawSkybox(Texture *texture, Math::Vector3d camera) {
+ TinyGL3DTexture *glTexture = static_cast<TinyGL3DTexture *>(texture);
+ tglDisable(TGL_DEPTH_TEST);
+ tglEnable(TGL_TEXTURE_2D);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_REPEAT);
+
+ tglBindTexture(TGL_TEXTURE_2D, glTexture->_id);
+ tglColor4f(1.f, 1.f, 1.f, 1.f);
+ tglVertexPointer(3, TGL_FLOAT, 0, _skyVertices);
+ tglNormalPointer(TGL_FLOAT, 0, _skyNormals);
+ if (texture->_width == 1008)
+ tglTexCoordPointer(2, TGL_FLOAT, 0, _skyUvs1008);
+ else if (texture->_width == 128)
+ tglTexCoordPointer(2, TGL_FLOAT, 0, _skyUvs128);
+ else
+ error("Unsupported skybox texture width %d", glTexture->_width);
+
+ tglEnableClientState(TGL_VERTEX_ARRAY);
+ tglEnableClientState(TGL_TEXTURE_COORD_ARRAY);
+ tglEnableClientState(TGL_NORMAL_ARRAY);
+
+ tglPolygonMode(TGL_BACK, TGL_FILL);
+
+ tglPushMatrix();
+ {
+ tglTranslatef(camera.x(), camera.y(), camera.z());
+ tglDrawArrays(TGL_QUADS, 0, 16);
+ }
+ tglPopMatrix();
+
+ tglDisableClientState(TGL_NORMAL_ARRAY);
+ tglDisableClientState(TGL_TEXTURE_COORD_ARRAY);
+ tglDisableClientState(TGL_VERTEX_ARRAY);
+
+ tglBindTexture(TGL_TEXTURE_2D, 0);
+ tglDisable(TGL_TEXTURE_2D);
+ tglEnable(TGL_DEPTH_TEST);
+ tglFlush();
}
void TinyGLRenderer::updateProjectionMatrix(float fov, float aspectRatio, float nearClipPlane, float farClipPlane) {
@@ -499,7 +542,7 @@ Graphics::Surface *TinyGLRenderer::getScreenshot() {
TinyGL::getSurfaceRef(glBuffer);
Graphics::Surface *s = new Graphics::Surface();
- s->create(_screenW, _screenH, TinyGLTexture::getRGBAPixelFormat());
+ s->create(_screenW, _screenH, TinyGL2DTexture::getRGBAPixelFormat());
s->copyFrom(glBuffer);
return s;
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 7a97f6776c2..5174c1e9749 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -60,9 +60,10 @@ public:
TGLubyte *_variableStippleArray;
- Texture *createTexture(const Graphics::Surface *surface) override;
+ Texture *createTexture(const Graphics::Surface *surface, bool is3D = false) override;
void freeTexture(Texture *texture) override;
virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
+ void drawSkybox(Texture *texture, Math::Vector3d camera) override;
virtual void renderSensorShoot(byte color, const Math::Vector3d sensor, const Math::Vector3d player, const Common::Rect viewPort) override;
virtual void renderPlayerShootBall(byte color, const Common::Point position, int frame, const Common::Rect viewPort) override;
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index 887a386afb7..01c150728cb 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -25,11 +25,11 @@
namespace Freescape {
-const Graphics::PixelFormat TinyGLTexture::getRGBAPixelFormat() {
+const Graphics::PixelFormat TinyGL2DTexture::getRGBAPixelFormat() {
return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
}
-TinyGLTexture::TinyGLTexture(const Graphics::Surface *surface) {
+TinyGL2DTexture::TinyGL2DTexture(const Graphics::Surface *surface) {
_width = surface->w;
_height = surface->h;
_format = surface->format;
@@ -41,22 +41,72 @@ TinyGLTexture::TinyGLTexture(const Graphics::Surface *surface) {
update(surface);
}
-TinyGLTexture::~TinyGLTexture() {
+TinyGL2DTexture::~TinyGL2DTexture() {
tglDeleteBlitImage(_blitImage);
}
-void TinyGLTexture::update(const Graphics::Surface *surface) {
+void TinyGL2DTexture::update(const Graphics::Surface *surface) {
uint32 keyColor = getRGBAPixelFormat().RGBToColor(0xA0, 0xA0, 0xA0);
tglUploadBlitImage(_blitImage, *surface, keyColor, true);
}
-void TinyGLTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
+void TinyGL2DTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
// FIXME: TinyGL does not support partial texture update
update(surface);
}
-TinyGL::BlitImage *TinyGLTexture::getBlitTexture() const {
+TinyGL::BlitImage *TinyGL2DTexture::getBlitTexture() const {
return _blitImage;
}
+const Graphics::PixelFormat TinyGL3DTexture::getRGBAPixelFormat() {
+ return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+}
+
+TinyGL3DTexture::TinyGL3DTexture(const Graphics::Surface *surface) {
+ _width = surface->w;
+ _height = surface->h;
+ _format = surface->format;
+ _upsideDown = false;
+
+ if (_format.bytesPerPixel == 4) {
+ assert(surface->format == getRGBAPixelFormat());
+ _format = surface->format;
+ _internalFormat = TGL_RGBA;
+ _sourceFormat = TGL_UNSIGNED_BYTE;
+ } else if (_format.bytesPerPixel == 2) {
+ _internalFormat = TGL_RGB;
+ _sourceFormat = TGL_UNSIGNED_SHORT_5_6_5;
+ } else
+ error("Unknown pixel format");
+
+
+ tglGenTextures(1, &_id);
+ tglBindTexture(TGL_TEXTURE_2D, _id);
+ tglTexImage2D(TGL_TEXTURE_2D, 0, _internalFormat, _width, _height, 0, _internalFormat, _sourceFormat, nullptr);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_NEAREST);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_NEAREST);
+
+ // NOTE: TinyGL doesn't have issues with white lines so doesn't need use TGL_CLAMP_TO_EDGE
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_CLAMP_TO_EDGE);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_CLAMP_TO_EDGE);
+ update(surface);
+}
+
+TinyGL3DTexture::~TinyGL3DTexture() {
+ tglDeleteTextures(1, &_id);
+}
+
+void TinyGL3DTexture::update(const Graphics::Surface *surface) {
+ assert(surface->format == _format);
+
+ tglBindTexture(TGL_TEXTURE_2D, _id);
+ tglTexImage2D(TGL_TEXTURE_2D, 0, _internalFormat, surface->w, surface->h, 0, _internalFormat, _sourceFormat, const_cast<void *>(surface->getPixels()));
+}
+
+void TinyGL3DTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
+ // FIXME: TinyGL does not support partial texture update
+ update(surface);
+}
+
} // End of namespace Freescape
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index 5dbedf40f8d..c2ce33845ec 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -28,10 +28,10 @@
namespace Freescape {
-class TinyGLTexture : public Texture {
+class TinyGL2DTexture : public Texture {
public:
- TinyGLTexture(const Graphics::Surface *surface);
- virtual ~TinyGLTexture();
+ TinyGL2DTexture(const Graphics::Surface *surface);
+ virtual ~TinyGL2DTexture();
const static Graphics::PixelFormat getRGBAPixelFormat();
@@ -47,6 +47,25 @@ private:
TinyGL::BlitImage *_blitImage;
};
+
+class TinyGL3DTexture : public Texture {
+public:
+ TinyGL3DTexture(const Graphics::Surface *surface);
+ virtual ~TinyGL3DTexture();
+
+ const static Graphics::PixelFormat getRGBAPixelFormat();
+
+ void update(const Graphics::Surface *surface) override;
+ void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) override;
+
+ TGLuint _id;
+ TGLuint _internalFormat;
+ TGLuint _sourceFormat;
+ uint32 _internalWidth;
+ uint32 _internalHeight;
+ bool _upsideDown;
+};
+
} // End of namespace Freescape
#endif // FREESCAPE_GFX_TINYGL_TEXTURE_H
Commit: 4ceba8c1f8c808ac1efcb5c3efb9d2488ec648d3
https://github.com/scummvm/scummvm/commit/4ceba8c1f8c808ac1efcb5c3efb9d2488ec648d3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-11-23T09:01:43+01:00
Commit Message:
FREESCAPE: refactored and unified getRGBAPixelFormat across all the codebase
Changed paths:
engines/freescape/gfx.cpp
engines/freescape/gfx.h
engines/freescape/gfx_opengl.cpp
engines/freescape/gfx_opengl_shaders.cpp
engines/freescape/gfx_opengl_texture.cpp
engines/freescape/gfx_opengl_texture.h
engines/freescape/gfx_tinygl.cpp
engines/freescape/gfx_tinygl_texture.cpp
engines/freescape/gfx_tinygl_texture.h
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index e4a0c6614a9..3ddf77aeaa6 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -34,6 +34,14 @@
namespace Freescape {
+const Graphics::PixelFormat getRGBAPixelFormat() {
+#ifdef SCUMM_BIG_ENDIAN
+ return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+ return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+}
+
Renderer::Renderer(int screenW, int screenH, Common::RenderMode renderMode, bool authenticGraphics) {
_screenW = screenW;
_screenH = screenH;
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 19586fd3269..24506afd9d9 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -42,6 +42,8 @@ typedef Common::HashMap<int, int> ColorReMap;
class Renderer;
+const Graphics::PixelFormat getRGBAPixelFormat();
+
class Texture {
public:
Texture(){ _width = 0; _height = 0; };
@@ -53,8 +55,6 @@ public:
virtual void update(const Graphics::Surface *surface) = 0;
virtual void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) = 0;
-
- static const Graphics::PixelFormat getRGBAPixelFormat();
};
class Renderer {
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index c518c89c3bd..eb51a158d07 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -41,7 +41,7 @@ Renderer *CreateGfxOpenGL(int screenW, int screenH, Common::RenderMode renderMod
OpenGLRenderer::OpenGLRenderer(int screenW, int screenH, Common::RenderMode renderMode, bool authenticGraphics) : Renderer(screenW, screenH, renderMode, authenticGraphics) {
_verts = (Vertex *)malloc(sizeof(Vertex) * kVertexArraySize);
_coords = (Coord *)malloc(sizeof(Coord) * kCoordsArraySize);
- _texturePixelFormat = OpenGLTexture::getRGBAPixelFormat();
+ _texturePixelFormat = getRGBAPixelFormat();
_isAccelerated = true;
_variableStippleArray = nullptr;
}
@@ -563,7 +563,7 @@ void OpenGLRenderer::flipBuffer() {}
Graphics::Surface *OpenGLRenderer::getScreenshot() {
Common::Rect screen = viewport();
Graphics::Surface *s = new Graphics::Surface();
- s->create(screen.width(), screen.height(), OpenGLTexture::getRGBAPixelFormat());
+ s->create(screen.width(), screen.height(), getRGBAPixelFormat());
glReadPixels(screen.left, screen.top, screen.width(), screen.height(), GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());
flipVertical(s);
return s;
diff --git a/engines/freescape/gfx_opengl_shaders.cpp b/engines/freescape/gfx_opengl_shaders.cpp
index f1898754188..9569c6ff1d3 100644
--- a/engines/freescape/gfx_opengl_shaders.cpp
+++ b/engines/freescape/gfx_opengl_shaders.cpp
@@ -52,7 +52,7 @@ OpenGLShaderRenderer::OpenGLShaderRenderer(int screenW, int screenH, Common::Ren
_bitmapShader = nullptr;
_bitmapVBO = 0;
- _texturePixelFormat = OpenGLTexture::getRGBAPixelFormat();
+ _texturePixelFormat = getRGBAPixelFormat();
_isAccelerated = true;
}
@@ -519,7 +519,7 @@ void OpenGLShaderRenderer::flipBuffer() {}
Graphics::Surface *OpenGLShaderRenderer::getScreenshot() {
Common::Rect screen = viewport();
Graphics::Surface *s = new Graphics::Surface();
- s->create(screen.width(), screen.height(), OpenGLTexture::getRGBAPixelFormat());
+ s->create(screen.width(), screen.height(), getRGBAPixelFormat());
glReadPixels(screen.left, screen.top, screen.width(), screen.height(), GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());
flipVertical(s);
return s;
diff --git a/engines/freescape/gfx_opengl_texture.cpp b/engines/freescape/gfx_opengl_texture.cpp
index bc68440908e..bcbd1a6c054 100644
--- a/engines/freescape/gfx_opengl_texture.cpp
+++ b/engines/freescape/gfx_opengl_texture.cpp
@@ -41,14 +41,6 @@ static uint32 upperPowerOfTwo(uint32 v) {
return v;
}
-const Graphics::PixelFormat OpenGLTexture::getRGBAPixelFormat() {
-#ifdef SCUMM_BIG_ENDIAN
- return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-#else
- return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
-#endif
-}
-
OpenGLTexture::OpenGLTexture() :
_internalFormat(0),
_sourceFormat(0),
diff --git a/engines/freescape/gfx_opengl_texture.h b/engines/freescape/gfx_opengl_texture.h
index cd3f3b073ee..31d8c3592f2 100644
--- a/engines/freescape/gfx_opengl_texture.h
+++ b/engines/freescape/gfx_opengl_texture.h
@@ -35,8 +35,6 @@ public:
OpenGLTexture();
virtual ~OpenGLTexture();
- const static Graphics::PixelFormat getRGBAPixelFormat();
-
void update(const Graphics::Surface *surface) override;
void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) override;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index c7a71f642be..cd5a72db205 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -39,7 +39,7 @@ Renderer *CreateGfxTinyGL(int screenW, int screenH, Common::RenderMode renderMod
TinyGLRenderer::TinyGLRenderer(int screenW, int screenH, Common::RenderMode renderMode) : Renderer(screenW, screenH, renderMode, true) {
_verts = (Vertex *)malloc(sizeof(Vertex) * kVertexArraySize);
- _texturePixelFormat = TinyGL2DTexture::getRGBAPixelFormat();
+ _texturePixelFormat = getRGBAPixelFormat();
_variableStippleArray = nullptr;
}
@@ -542,7 +542,7 @@ Graphics::Surface *TinyGLRenderer::getScreenshot() {
TinyGL::getSurfaceRef(glBuffer);
Graphics::Surface *s = new Graphics::Surface();
- s->create(_screenW, _screenH, TinyGL2DTexture::getRGBAPixelFormat());
+ s->create(_screenW, _screenH, getRGBAPixelFormat());
s->copyFrom(glBuffer);
return s;
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index 01c150728cb..ca71310113c 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -25,10 +25,6 @@
namespace Freescape {
-const Graphics::PixelFormat TinyGL2DTexture::getRGBAPixelFormat() {
- return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-}
-
TinyGL2DTexture::TinyGL2DTexture(const Graphics::Surface *surface) {
_width = surface->w;
_height = surface->h;
@@ -59,10 +55,6 @@ TinyGL::BlitImage *TinyGL2DTexture::getBlitTexture() const {
return _blitImage;
}
-const Graphics::PixelFormat TinyGL3DTexture::getRGBAPixelFormat() {
- return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
-}
-
TinyGL3DTexture::TinyGL3DTexture(const Graphics::Surface *surface) {
_width = surface->w;
_height = surface->h;
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index c2ce33845ec..5832e8d7199 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -33,8 +33,6 @@ public:
TinyGL2DTexture(const Graphics::Surface *surface);
virtual ~TinyGL2DTexture();
- const static Graphics::PixelFormat getRGBAPixelFormat();
-
TinyGL::BlitImage *getBlitTexture() const;
void update(const Graphics::Surface *surface) override;
@@ -53,8 +51,6 @@ public:
TinyGL3DTexture(const Graphics::Surface *surface);
virtual ~TinyGL3DTexture();
- const static Graphics::PixelFormat getRGBAPixelFormat();
-
void update(const Graphics::Surface *surface) override;
void updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) override;
Commit: 6a88a4c06827659d49364b645a1929e785370619
https://github.com/scummvm/scummvm/commit/6a88a4c06827659d49364b645a1929e785370619
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-11-23T09:01:43+01:00
Commit Message:
FREESCAPE: first attempt to implement stipple patterns in TinyGL using textures
Changed paths:
engines/freescape/gfx.cpp
engines/freescape/gfx_tinygl.cpp
engines/freescape/gfx_tinygl.h
engines/freescape/gfx_tinygl_texture.cpp
engines/freescape/gfx_tinygl_texture.h
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 3ddf77aeaa6..3001eb80550 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -282,6 +282,7 @@ bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
assert (_renderMode == Common::kRenderCGA);
if (index <= 4) { // Solid colors
+ stipple = nullptr;
readFromPalette(index - 1, r1, g1, b1);
r2 = r1;
g2 = g1;
@@ -295,6 +296,9 @@ bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
byte c2 = (pair >> 4) & 0xf;
readFromPalette(c1, r1, g1, b1);
readFromPalette(c2, r2, g2, b2);
+ if (r1 == r2 && g1 == g2 && b1 == b2) {
+ stipple = nullptr;
+ }
return true;
}
@@ -372,12 +376,14 @@ bool Renderer::getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r
if (entry[0] == 0 && entry[1] == 0 && entry[2] == 0 && entry[3] == 0) {
readFromPalette(_paperColor, r1, g1, b1);
readFromPalette(_paperColor, r2, g2, b2);
+ stipple = nullptr;
return true;
}
if (entry[0] == 0xff && entry[1] == 0xff && entry[2] == 0xff && entry[3] == 0xff) {
readFromPalette(_inkColor, r1, g1, b1);
readFromPalette(_inkColor, r2, g2, b2);
+ stipple = nullptr;
return true;
}
@@ -385,6 +391,9 @@ bool Renderer::getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r
readFromPalette(_paperColor, r1, g1, b1);
readFromPalette(_inkColor, r2, g2, b2);
+ if (r1 == r2 && g1 == g2 && b1 == g2) {
+ stipple = nullptr;
+ }
return true;
}
@@ -438,12 +447,14 @@ bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
r2 = r1;
g2 = g1;
b2 = b1;
+ stipple = nullptr;
return true;
}
readFromPalette(index, r1, g1, b1);
r2 = r1;
g2 = g1;
b2 = b1;
+ stipple = nullptr;
return true;
}
@@ -453,6 +464,7 @@ bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
r2 = r1;
g2 = g1;
b2 = b1;
+ stipple = nullptr;
return true;
}
@@ -462,6 +474,9 @@ bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
uint8 i2 = getCPCPixel(entry[0], 1, true);
selectColorFromFourColorPalette(i1, r1, g1, b1);
selectColorFromFourColorPalette(i2, r2, g2, b2);
+ if (r1 == r2 && g1 == g2 && b1 == b2) {
+ stipple = nullptr;
+ }
return true;
}
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index cd5a72db205..8f1c7ada75e 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -39,13 +39,18 @@ Renderer *CreateGfxTinyGL(int screenW, int screenH, Common::RenderMode renderMod
TinyGLRenderer::TinyGLRenderer(int screenW, int screenH, Common::RenderMode renderMode) : Renderer(screenW, screenH, renderMode, true) {
_verts = (Vertex *)malloc(sizeof(Vertex) * kVertexArraySize);
+ _texCoord = (Coord *)malloc(sizeof(Coord) * kVertexArraySize);
_texturePixelFormat = getRGBAPixelFormat();
_variableStippleArray = nullptr;
}
TinyGLRenderer::~TinyGLRenderer() {
+ for (auto &it : _stippleTextureCache) {
+ delete (TinyGL3DTexture *)it._value;
+ }
TinyGL::destroyContext();
free(_verts);
+ free(_texCoord);
}
Texture *TinyGLRenderer::createTexture(const Graphics::Surface *surface, bool is3D) {
@@ -76,6 +81,10 @@ void TinyGLRenderer::init() {
tglDisable(TGL_LIGHTING);
tglDisable(TGL_TEXTURE_2D);
tglEnable(TGL_DEPTH_TEST);
+ _stippleEnabled = false;
+ _lastColorSet0 = 0;
+ _lastColorSet1 = 0;
+ _stippleTexture = nullptr;
}
void TinyGLRenderer::setViewport(const Common::Rect &rect) {
@@ -303,31 +312,27 @@ void TinyGLRenderer::renderCrossair(const Common::Point crossairPosition) {
}
void TinyGLRenderer::setStippleData(byte *data) {
- if (!data)
+ if (!data) {
+ _stippleTexture = nullptr;
+ assert(_stippleEnabled == false);
+ _variableStippleArray = nullptr;
return;
+ }
+ if (_stippleTextureCache.contains(uint64(data))) {
+
+ }
+ assert(_stippleTextureCache.size() <= 16);
_variableStippleArray = data;
- //for (int i = 0; i < 128; i++)
- // _variableStippleArray[i] = data[(i / 16) % 4];
}
void TinyGLRenderer::useStipple(bool enabled) {
+ _stippleEnabled = enabled;
+
if (enabled) {
- TGLfloat factor = 0;
- tglGetFloatv(TGL_POLYGON_OFFSET_FACTOR, &factor);
- tglEnable(TGL_POLYGON_OFFSET_FILL);
- tglPolygonOffset(factor - 0.5f, -1.0f);
- tglEnable(TGL_POLYGON_STIPPLE);
- if (_renderMode == Common::kRenderZX ||
- _renderMode == Common::kRenderCPC ||
- _renderMode == Common::kRenderCGA)
- tglPolygonStipple(_variableStippleArray);
- else
- tglPolygonStipple(_defaultStippleArraySmall);
+ assert(_variableStippleArray);
} else {
- tglPolygonOffset(0, 0);
- tglDisable(TGL_POLYGON_OFFSET_FILL);
- tglDisable(TGL_POLYGON_STIPPLE);
+ _stippleTexture = nullptr;
}
}
@@ -349,6 +354,16 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
return;
}
+ if (_stippleEnabled) {
+ if (_stippleTextureCache.contains(uint64(_variableStippleArray))) {
+ _stippleTexture = _stippleTextureCache[uint64(_variableStippleArray)];
+ } else {
+ _stippleTexture = new TinyGL3DTexture(_variableStippleArray, _lastColorSet0, _lastColorSet1);
+ _stippleTextureCache[uint64(_variableStippleArray)] = _stippleTexture;
+ }
+ } else if (_variableStippleArray)
+ return; // We are in the middle of a stipple rendering operation, so we should skip this face
+
tglEnableClientState(TGL_VERTEX_ARRAY);
uint vi = 0;
for (uint i = 1; i < vertices.size() - 1; i++) { // no underflow since vertices.size() > 2
@@ -360,8 +375,61 @@ void TinyGLRenderer::renderFace(const Common::Array<Math::Vector3d> &vertices) {
copyToVertexArray(vi + 2, v2);
}
tglVertexPointer(3, TGL_FLOAT, 0, _verts);
+
+ if (_stippleEnabled) {
+ tglClear(TGL_STENCIL_BUFFER_BIT);
+ tglEnable(TGL_STENCIL_TEST);
+ tglStencilFunc(TGL_ALWAYS, 1, 0xFF); // Always pass stencil test
+ tglStencilOp(TGL_KEEP, TGL_KEEP, TGL_REPLACE); // Replace stencil buffer where drawn
+ tglEnable(TGL_DEPTH_TEST);
+ tglDepthMask(TGL_TRUE);
+ tglColorMask(TGL_FALSE, TGL_FALSE, TGL_FALSE, TGL_FALSE);
+ }
+
tglDrawArrays(TGL_TRIANGLES, 0, vi + 3);
tglDisableClientState(TGL_VERTEX_ARRAY);
+
+ if (_stippleEnabled) {
+ tglColorMask(TGL_TRUE, TGL_TRUE, TGL_TRUE, TGL_TRUE);
+ tglStencilFunc(TGL_EQUAL, 1, 0xFF); // Only render where stencil value is 1
+ tglStencilOp(TGL_KEEP, TGL_KEEP, TGL_KEEP); // Don't change stencil buffer
+
+ tglMatrixMode(TGL_PROJECTION);
+ tglPushMatrix();
+
+ tglLoadIdentity();
+ tglOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); // Orthographic projection
+
+ tglScalef(1, 1, 1);
+ tglMatrixMode(TGL_MODELVIEW);
+ tglPushMatrix();
+ tglLoadIdentity();
+
+ tglEnable(TGL_TEXTURE_2D);
+ tglBindTexture(TGL_TEXTURE_2D, _stippleTexture->_id);
+ tglColor4f(1.f, 1.f, 1.f, 1.f);
+ tglDepthMask(TGL_FALSE);
+
+ tglBegin(TGL_QUADS);
+ tglTexCoord2f(0.0f, 0.0f); tglVertex2f(0.0f, 0.0f);
+ tglTexCoord2f(1.0, 0.0f); tglVertex2f(1.0, 0.0f);
+ tglTexCoord2f(1.0, 1.0); tglVertex2f(1.0, 1.0);
+ tglTexCoord2f(0.0f, 1.0); tglVertex2f(0.0f, 1.0);
+ tglEnd();
+
+ tglDepthMask(TGL_TRUE);
+ tglDisable(TGL_STENCIL_TEST);
+ tglDisable(TGL_TEXTURE_2D);
+ tglDisable(TGL_TEXTURE);
+ tglFlush();
+ tglBindTexture(TGL_TEXTURE_2D, 0);
+
+ tglMatrixMode(TGL_PROJECTION);
+ tglPopMatrix();
+
+ tglMatrixMode(TGL_MODELVIEW);
+ tglPopMatrix();
+ }
}
void TinyGLRenderer::drawCelestialBody(Math::Vector3d position, float radius, byte color) {
@@ -456,11 +524,13 @@ void TinyGLRenderer::polygonOffset(bool enabled) {
}
void TinyGLRenderer::useColor(uint8 r, uint8 g, uint8 b) {
+ _lastColorSet1 = _lastColorSet0;
+ _lastColorSet0 = _texturePixelFormat.RGBToColor(r, g, b);
tglColor3ub(r, g, b);
}
void TinyGLRenderer::clear(uint8 r, uint8 g, uint8 b, bool ignoreViewport) {
- tglClear(TGL_DEPTH_BUFFER_BIT);
+ tglClear(TGL_DEPTH_BUFFER_BIT | TGL_STENCIL_BITS);
if (ignoreViewport) {
tglClearColor(r / 255., g / 255., b / 255., 1.0);
tglClear(TGL_COLOR_BUFFER_BIT);
diff --git a/engines/freescape/gfx_tinygl.h b/engines/freescape/gfx_tinygl.h
index 5174c1e9749..973b1b63282 100644
--- a/engines/freescape/gfx_tinygl.h
+++ b/engines/freescape/gfx_tinygl.h
@@ -23,8 +23,10 @@
#define FREESCAPE_GFX_TINYGL_H
#include "math/vector3d.h"
+#include "common/hashmap.h"
#include "freescape/gfx.h"
+#include "freescape/gfx_tinygl_texture.h"
namespace Freescape {
@@ -39,12 +41,29 @@ public:
TGLfloat z;
};
+ Vertex *_verts;
void copyToVertexArray(uint idx, const Math::Vector3d &src) {
assert(idx < kVertexArraySize);
_verts[idx].x = src.x(); _verts[idx].y = src.y(); _verts[idx].z = src.z();
}
- Vertex *_verts;
+ struct Coord {
+ TGLfloat x;
+ TGLfloat y;
+ };
+
+ Coord *_texCoord;
+
+ void copyToTexCoordArray(uint idx, float x, float y) {
+ assert(idx < kVertexArraySize);
+ _texCoord[idx].x = x; _texCoord[idx].y = y;
+ }
+
+ bool _stippleEnabled;
+ TinyGL3DTexture *_stippleTexture;
+ Common::HashMap<uint64, TinyGL3DTexture *> _stippleTextureCache;
+ uint32 _lastColorSet0;
+ uint32 _lastColorSet1;
virtual void init() override;
virtual void clear(uint8 r, uint8 g, uint8 b, bool ignoreViewport = false) override;
@@ -58,8 +77,6 @@ public:
virtual void setStippleData(byte *data) override;
virtual void useStipple(bool enabled) override;
- TGLubyte *_variableStippleArray;
-
Texture *createTexture(const Graphics::Surface *surface, bool is3D = false) override;
void freeTexture(Texture *texture) override;
virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) override;
diff --git a/engines/freescape/gfx_tinygl_texture.cpp b/engines/freescape/gfx_tinygl_texture.cpp
index ca71310113c..c3ad12c027b 100644
--- a/engines/freescape/gfx_tinygl_texture.cpp
+++ b/engines/freescape/gfx_tinygl_texture.cpp
@@ -55,6 +55,82 @@ TinyGL::BlitImage *TinyGL2DTexture::getBlitTexture() const {
return _blitImage;
}
+TinyGL3DTexture::TinyGL3DTexture(byte *stipple, uint32 c1, uint32 c2) {
+ Graphics::Surface *surface = new Graphics::Surface();
+ int width = 32;
+ int height = 32;
+
+ surface->create(width, height, getRGBAPixelFormat());
+ surface->fillRect(Common::Rect(0, 0, width, height), surface->format.RGBToColor(0, 0, 0xFF));
+
+ const int stippleWidth = 32;
+ const int stippleHeight = 32;
+
+
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+
+ // Match OpenGL's stipple bit layout
+ int stippleX = x % stippleWidth; // Bit position in the row
+ int stippleY = y % stippleHeight; // Row index
+
+ int byteIndex = stippleY * 4 + (stippleX / 8); // 4 bytes per row
+ int bitIndex = stippleX % 8;
+
+ byte bitmask = 1 << (7 - bitIndex);
+ bool isForeground = stipple[byteIndex] & bitmask;
+ //debug("stippleX=%d stippleY=%d byteIndex=%d bitIndex=%d stipple[byteIndex]: %x color: %s", stippleX, stippleY, byteIndex, bitIndex, stipple[byteIndex], isForeground ? "X" : " ");
+ surface->setPixel(stippleX, stippleY, isForeground ? c1 : c2);
+ }
+ }
+ //assert(0);
+ Graphics::Surface *texture = new Graphics::Surface();
+ texture->create(320, 200, getRGBAPixelFormat());
+ texture->fillRect(Common::Rect(0, 0, 320, 200), texture->format.RGBToColor(0, 0, 0xFF));
+ //texture->copyRectToSurface(*surface, 0, 0, Common::Rect(0, 0, 32, 32));
+
+ // Replicate the stipple pattern to fill the entire texture
+ for (int x = 0; x < 320; x += width) {
+ for (int y = 0; y < 200; y += height) {
+ if (x + width >= 320 || y + height >= 200) {
+ texture->copyRectToSurface(*surface, x, y, Common::Rect(0, 0, MIN(width, 320 - x), MIN(height, 200 - y)));
+ } else
+ texture->copyRectToSurface(*surface, x, y, Common::Rect(0, 0, width, height));
+ }
+ }
+
+ // This surface is no longer needed
+ surface->free();
+ delete surface;
+
+ _width = texture->w;
+ _height = texture->h;
+ _format = texture->format;
+ _upsideDown = false;
+
+ if (_format.bytesPerPixel == 4) {
+ assert(texture->format == getRGBAPixelFormat());
+ _format = texture->format;
+ _internalFormat = TGL_RGBA;
+ _sourceFormat = TGL_UNSIGNED_BYTE;
+ } else if (_format.bytesPerPixel == 2) {
+ _internalFormat = TGL_RGB;
+ _sourceFormat = TGL_UNSIGNED_SHORT_5_6_5;
+ } else
+ error("Unknown pixel format");
+
+ tglGenTextures(1, &_id);
+ tglBindTexture(TGL_TEXTURE_2D, _id);
+ tglTexImage2D(TGL_TEXTURE_2D, 0, _internalFormat, _width, _height, 0, _internalFormat, _sourceFormat, nullptr);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_NEAREST);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_NEAREST);
+
+ update(texture);
+
+ texture->free();
+ delete texture;
+}
+
TinyGL3DTexture::TinyGL3DTexture(const Graphics::Surface *surface) {
_width = surface->w;
_height = surface->h;
@@ -80,8 +156,8 @@ TinyGL3DTexture::TinyGL3DTexture(const Graphics::Surface *surface) {
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_NEAREST);
// NOTE: TinyGL doesn't have issues with white lines so doesn't need use TGL_CLAMP_TO_EDGE
- tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_CLAMP_TO_EDGE);
- tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_CLAMP_TO_EDGE);
+ //tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_CLAMP_TO_EDGE);
+ //tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_CLAMP_TO_EDGE);
update(surface);
}
diff --git a/engines/freescape/gfx_tinygl_texture.h b/engines/freescape/gfx_tinygl_texture.h
index 5832e8d7199..7b0d09c6a45 100644
--- a/engines/freescape/gfx_tinygl_texture.h
+++ b/engines/freescape/gfx_tinygl_texture.h
@@ -49,6 +49,7 @@ private:
class TinyGL3DTexture : public Texture {
public:
TinyGL3DTexture(const Graphics::Surface *surface);
+ TinyGL3DTexture(byte *stipple, uint32 color1, uint32 color2);
virtual ~TinyGL3DTexture();
void update(const Graphics::Surface *surface) override;
More information about the Scummvm-git-logs
mailing list