diff --git a/assets/opensb/rendering/effects/interface.config b/assets/opensb/rendering/effects/interface.config index 4616e72..f153068 100644 --- a/assets/opensb/rendering/effects/interface.config +++ b/assets/opensb/rendering/effects/interface.config @@ -1,7 +1,13 @@ { "blitFrameBuffer" : "main", - "effectParameters" : {}, + "effectParameters" : { + "vertexRounding" : { + "type" : "bool", + "default" : false, + "uniform" : "vertexRounding" + } + }, "effectTextures" : {}, "effectShaders" : { diff --git a/assets/opensb/rendering/effects/interface.vert b/assets/opensb/rendering/effects/interface.vert index 14a7cea..dfd94d4 100644 --- a/assets/opensb/rendering/effects/interface.vert +++ b/assets/opensb/rendering/effects/interface.vert @@ -6,6 +6,7 @@ uniform vec2 textureSize2; uniform vec2 textureSize3; uniform vec2 screenSize; uniform mat3 vertexTransform; +uniform bool vertexRounding; in vec2 vertexPosition; in vec4 vertexColor; @@ -19,10 +20,14 @@ out vec4 fragmentColor; void main() { vec2 screenPosition = (vertexTransform * vec3(vertexPosition, 1.0)).xy; gl_Position = vec4(screenPosition / screenSize * 2.0 - 1.0, 0.0, 1.0); - if (((vertexData >> 3) & 0x1) == 1) - screenPosition.x = round(screenPosition.x); - if (((vertexData >> 4) & 0x1) == 1) - screenPosition.y = round(screenPosition.y); + + if (vertexRounding) { + if (((vertexData >> 3) & 0x1) == 1) + screenPosition.x = round(screenPosition.x); + if (((vertexData >> 4) & 0x1) == 1) + screenPosition.y = round(screenPosition.y); + } + int vertexTextureIndex = vertexData & 0x3; if (vertexTextureIndex == 3) fragmentTextureCoordinate = vertexTextureCoordinate / textureSize3; diff --git a/assets/opensb/rendering/effects/world.config b/assets/opensb/rendering/effects/world.config index d8ec1a9..3a55cfe 100644 --- a/assets/opensb/rendering/effects/world.config +++ b/assets/opensb/rendering/effects/world.config @@ -21,6 +21,11 @@ "type" : "float", "default" : 1.0, "uniform" : "lightMapMultiplier" + }, + "vertexRounding" : { + "type" : "bool", + "default" : false, + "uniform" : "vertexRounding" } }, diff --git a/assets/opensb/rendering/effects/world.vert b/assets/opensb/rendering/effects/world.vert index ce8a9fc..f41c0a8 100644 --- a/assets/opensb/rendering/effects/world.vert +++ b/assets/opensb/rendering/effects/world.vert @@ -6,6 +6,7 @@ uniform vec2 textureSize2; uniform vec2 textureSize3; uniform vec2 screenSize; uniform mat3 vertexTransform; +uniform bool vertexRounding; uniform vec2 lightMapSize; uniform vec2 lightMapScale; uniform vec2 lightMapOffset; @@ -24,11 +25,13 @@ out vec2 fragmentLightMapCoordinate; void main() { vec2 screenPosition = (vertexTransform * vec3(vertexPosition, 1.0)).xy; - if (((vertexData >> 3) & 0x1) == 1) - screenPosition.x = round(screenPosition.x); - if (((vertexData >> 4) & 0x1) == 1) - screenPosition.y = round(screenPosition.y); - + if (vertexRounding) { + if (((vertexData >> 3) & 0x1) == 1) + screenPosition.x = round(screenPosition.x); + if (((vertexData >> 4) & 0x1) == 1) + screenPosition.y = round(screenPosition.y); + } + fragmentLightMapMultiplier = float((vertexData >> 2) & 0x1); int vertexTextureIndex = vertexData & 0x3; fragmentLightMapCoordinate = (screenPosition / lightMapScale) - lightMapOffset * lightMapSize / screenSize; diff --git a/source/application/StarRenderer_opengl.cpp b/source/application/StarRenderer_opengl.cpp index 401acc7..f0e4dfd 100644 --- a/source/application/StarRenderer_opengl.cpp +++ b/source/application/StarRenderer_opengl.cpp @@ -394,6 +394,8 @@ bool OpenGlRenderer::switchEffectConfig(String const& name) { setupGlUniforms(effect); m_currentEffect = &effect; + setEffectParameter("vertexRounding", m_multiSampling > 0); + return true; } @@ -432,7 +434,7 @@ void OpenGlRenderer::setMultiSampling(unsigned multiSampling) { if (m_multiSampling) { glEnable(GL_MULTISAMPLE); glEnable(GL_SAMPLE_SHADING); - glMinSampleShading(1.0f); + glMinSampleShading(1.f); } else { glMinSampleShading(0.f); glDisable(GL_SAMPLE_SHADING); diff --git a/source/base/StarCellularLighting.cpp b/source/base/StarCellularLighting.cpp index ebca0ad..48ba265 100644 --- a/source/base/StarCellularLighting.cpp +++ b/source/base/StarCellularLighting.cpp @@ -223,7 +223,7 @@ void CellularLightIntensityCalculator::addSpreadLight(Vec2F const& position, flo void CellularLightIntensityCalculator::addPointLight(Vec2F const& position, float light, float beam, float beamAngle, float beamAmbience) { Vec2F arrayPosition = position - Vec2F(m_calculationRegion.min()); - m_lightArray.addPointLight({arrayPosition, light, beam, beamAngle, beamAmbience}); + m_lightArray.addPointLight({arrayPosition, light, beam, beamAngle, beamAmbience, false}); } diff --git a/source/base/StarMemoryAssetSource.cpp b/source/base/StarMemoryAssetSource.cpp index a0c220d..a7554b6 100644 --- a/source/base/StarMemoryAssetSource.cpp +++ b/source/base/StarMemoryAssetSource.cpp @@ -45,7 +45,7 @@ IODevicePtr MemoryAssetSource::open(String const& path) { String deviceName() const override { return name; } bool atEnd() override { - return assetPos >= assetSize; + return assetPos >= (StreamOffset)assetSize; } void seek(StreamOffset p, IOSeek mode) override { diff --git a/source/core/StarMatrix3.hpp b/source/core/StarMatrix3.hpp index 04d8005..8cdd2d5 100644 --- a/source/core/StarMatrix3.hpp +++ b/source/core/StarMatrix3.hpp @@ -110,6 +110,8 @@ public: template Vec3 operator*(Vector const& v) const; + template + Vec2 operator*(Vector const& v) const; private: Rows m_rows; }; @@ -304,8 +306,7 @@ void Matrix3::scale(T scale, Vec2 const& point) { template template Vector Matrix3::transformVec2(Vector const& point) const { - Vector res = (*this) * Vector(point, 1); - return res.vec2(); + return (*this) * point; } template @@ -412,6 +413,13 @@ auto Matrix3::operator*(const Vector& u) const -> Vec3 { m_rows[2][0] * u[0] + m_rows[2][1] * u[1] + m_rows[2][2] * u[2]); } +template +template +auto Matrix3::operator*(const Vector& u) const -> Vec2 { + return Vec2(m_rows[0][0] * u[0] + m_rows[0][1] * u[1] + m_rows[0][2], + m_rows[1][0] * u[0] + m_rows[1][1] * u[1] + m_rows[1][2]); +} + template Matrix3 Matrix3::operator/(const T& s) const { return Matrix3(m_rows[0] / s, m_rows[1] / s, m_rows[2] / s); diff --git a/source/rendering/StarDrawablePainter.cpp b/source/rendering/StarDrawablePainter.cpp index 5f9fd79..88ca651 100644 --- a/source/rendering/StarDrawablePainter.cpp +++ b/source/rendering/StarDrawablePainter.cpp @@ -36,15 +36,13 @@ void DrawablePainter::drawDrawable(Drawable const& drawable) { } else if (auto imagePart = drawable.part.ptr()) { TexturePtr texture = m_textureGroup->loadTexture(imagePart->image); + Vec2F position = drawable.position; Vec2F textureSize(texture->size()); - RectF imageRect(Vec2F(), textureSize); - - Mat3F transformation = Mat3F::translation(drawable.position) * imagePart->transformation; - - Vec2F lowerLeft = transformation.transformVec2(Vec2F(imageRect.xMin(), imageRect.yMin())); - Vec2F lowerRight = transformation.transformVec2(Vec2F(imageRect.xMax(), imageRect.yMin())); - Vec2F upperRight = transformation.transformVec2(Vec2F(imageRect.xMax(), imageRect.yMax())); - Vec2F upperLeft = transformation.transformVec2(Vec2F(imageRect.xMin(), imageRect.yMax())); + Mat3F transformation = imagePart->transformation; + Vec2F lowerLeft = { transformation[0][2] += position.x(), transformation[1][2] += position.y() }; + Vec2F lowerRight = transformation * Vec2F(textureSize.x(), 0.f); + Vec2F upperRight = transformation * textureSize; + Vec2F upperLeft = transformation * Vec2F(0.f, textureSize.y()); float param1 = drawable.fullbright ? 0.0f : 1.0f; diff --git a/source/rendering/StarWorldCamera.cpp b/source/rendering/StarWorldCamera.cpp index c0bc645..de23f3e 100644 --- a/source/rendering/StarWorldCamera.cpp +++ b/source/rendering/StarWorldCamera.cpp @@ -26,15 +26,17 @@ void WorldCamera::setCenterWorldPosition(Vec2F const& position, bool force) { // elements drawn in world space that are aligned with TilePixels will // eventually also be aligned to real screen pixels. + float ratio = TilePixels * m_pixelRatio; + if (m_screenSize[0] % 2 == 0) - m_worldCenter[0] = round(m_worldCenter[0] * (TilePixels * m_pixelRatio)) / (TilePixels * m_pixelRatio); + m_worldCenter[0] = round(m_worldCenter[0] * ratio) / ratio; else - m_worldCenter[0] = (round(m_worldCenter[0] * (TilePixels * m_pixelRatio) + 0.5f) - 0.5f) / (TilePixels * m_pixelRatio); + m_worldCenter[0] = (round(m_worldCenter[0] * ratio + 0.5f) - 0.5f) / ratio; if (m_screenSize[1] % 2 == 0) - m_worldCenter[1] = round(m_worldCenter[1] * (TilePixels * m_pixelRatio)) / (TilePixels * m_pixelRatio); + m_worldCenter[1] = round(m_worldCenter[1] * ratio) / ratio; else - m_worldCenter[1] = (round(m_worldCenter[1] * (TilePixels * m_pixelRatio) + 0.5f) - 0.5f) / (TilePixels * m_pixelRatio); + m_worldCenter[1] = (round(m_worldCenter[1] * ratio + 0.5f) - 0.5f) / ratio; } }