Ich habe tex2.setSmooth(false); ausprobiert und den Alphawert für
geändert
Code: Select all
sprite.setColor(sf::Color(shadeValue, shadeValue, shadeValue, 255));Was versuche ich zu tun:
Alle Komponenten in dieser Reihenfolge für meine Renderfunktion rendern:
Code: Select all
void TwoHalfD::Engine::render()
{
m_window.clear(sf::Color::Black);
m_renderTexture.clear(sf::Color::Transparent);
renderFloor();
renderWalls();
renderObjects();
m_renderTexture.display();
sf::Sprite sprite(m_renderTexture.getTexture());
sprite.setScale(static_cast(m_engineSettings.windowDim.x) / m_engineSettings.resolution.x,
static_cast(m_engineSettings.windowDim.y) / m_engineSettings.resolution.y);
m_window.draw(sprite);
m_window.display();
}
Code: Select all
sf::Sprite sprite;
sprite.setTexture(tex);
sf::IntRect subRect(static_cast(texX), 0, sliceWidth, texSize.y);
sprite.setTextureRect(subRect);
sprite.setScale(1.0f, spriteHeightScreen / texSize.y);
sprite.setPosition(x * sliceWidth, topSpriteScreen);
float shade = std::min(1.0f, 256.0f / distToSprite);
sf::Uint8 shadeValue = static_cast(255 * shade);
sprite.setColor(sf::Color(shadeValue, shadeValue, shadeValue, 255));
m_renderTexture.draw(sprite);
Wände und der Boden bewältigen die Sprites, die vorne gerendert werden, einwandfrei, wobei die transparenten Teile des Sprites, die ich zum Testen verwende, die Pixel dahinter nicht überschreiben. Aber die Sprites, die sich überlagern, haben das Problem, dass Sprites vorne Sprites dahinter „abschneiden“, obwohl dieser Teil des Sprites transparent ist.
Überlappung verursacht Rendering-Probleme:

Keine Überlappung – nein Probleme:

Vollständige Funktion zum Rendern von Objekten
Code: Select all
void TwoHalfD::Engine::renderObjects()
{
float cameraDirRad = m_cameraObject.cameraPos.direction;
sf::Vector2f direction{std::cos(cameraDirRad), std::sin(cameraDirRad)};
sf::Vector2f plane{-direction.y * m_engineSettings.fovScale, direction.x * m_engineSettings.fovScale};
const float planeLen = std::sqrt(plane.x * plane.x + plane.y * plane.y);
const sf::Vector2f normalizedPlane = {plane.x / planeLen, plane.y / planeLen};
float focalLength = (m_engineSettings.resolution.x / 2.0f) / m_engineSettings.fovScale;
for (int x = 0; x < m_engineSettings.numRays; ++x)
{
float cameraX =
2.0f * x * (1.0f * m_engineSettings.resolution.x / m_engineSettings.numRays) / static_cast(m_engineSettings.resolution.x) - 1.0f;
sf::Vector2f rayDir = direction + plane * cameraX;
float rayLength = std::sqrt(rayDir.x * rayDir.x + rayDir.y * rayDir.y);
rayDir.x /= rayLength;
rayDir.y /= rayLength;
float rayDirX = rayDir.x;
float rayDirY = rayDir.y;
auto cmp = [](const auto &a, const auto &b) { return a.first < b.first; };
std::priority_queue
spriteOrderedDistance(cmp);
for (const auto &object : m_level.sprites)
{
if (object.textureId == -1)
continue;
// https://en.wikipedia.org/wiki/Line–line_intersection
const float x1 = m_cameraObject.cameraPos.pos.x, y1 = m_cameraObject.cameraPos.pos.y;
const float x2 = x1 + 1000.0f * rayDirX, y2 = y1 + 1000.0f * rayDirY;
const float x3 = object.pos.posf.x + object.radius * normalizedPlane.x, y3 = object.pos.posf.y + object.radius * normalizedPlane.y;
const float x4 = object.pos.posf.x - object.radius * normalizedPlane.x, y4 = object.pos.posf.y - object.radius * normalizedPlane.y;
float denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
if (std::abs(denom) < 0.00001f)
continue;
float numeratorT = (x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4);
float numeratorU = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3));
float t = numeratorT / denom;
float u = numeratorU / denom;
if (u < 0 || u > 1 || t < 0)
continue;
spriteOrderedDistance.push({t * 1000.0f, object});
}
while (!spriteOrderedDistance.empty())
{
const auto &distSpritePair = spriteOrderedDistance.top();
spriteOrderedDistance.pop();
const float distToSprite = distSpritePair.first;
const TwoHalfD::SpriteEntity currSprite = distSpritePair.second;
const auto &textureIt = m_textures.find(currSprite.textureId);
if (textureIt == m_textures.end())
{
exit(1);
}
const sf::Texture &tex = textureIt->second;
const sf::Vector2u texSize = tex.getSize();
float perpWorldDistance = distToSprite * (rayDirX * direction.x + rayDirY * direction.y);
const float bottomOfSpriteScreen = focalLength * m_cameraObject.cameraHeight / perpWorldDistance + m_engineSettings.resolution.y / 2.0f;
const float topSpriteScreen =
focalLength * (m_cameraObject.cameraHeight - currSprite.height) / perpWorldDistance + m_engineSettings.resolution.y / 2.0f;
const float spriteHeightScreen = bottomOfSpriteScreen - topSpriteScreen;
const sf::Vector2f spriteStartPos = {currSprite.pos.posf.x - currSprite.radius * normalizedPlane.x,
currSprite.pos.posf.y - currSprite.radius * normalizedPlane.y};
const sf::Vector2f spriteEndPos = {currSprite.pos.posf.x + currSprite.radius * normalizedPlane.x,
currSprite.pos.posf.y + currSprite.radius * normalizedPlane.y};
const float intersectX = m_cameraObject.cameraPos.pos.x + distToSprite * rayDirX;
const float intersectY = m_cameraObject.cameraPos.pos.y + distToSprite * rayDirY;
float spriteDirX = spriteEndPos.x - spriteStartPos.x;
float spriteDirY = spriteEndPos.y - spriteStartPos.y;
const float wallLen = std::sqrtf(spriteDirX * spriteDirX + spriteDirY * spriteDirY);
spriteDirX /= wallLen;
spriteDirY /= wallLen;
const float toIntersectX = intersectX - spriteStartPos.x;
const float toIntersectY = intersectY - spriteStartPos.y;
float lenToIntercept = toIntersectX * spriteDirX + toIntersectY * spriteDirY;
float texX = (lenToIntercept / (2.0f * currSprite.radius)) * texSize.x;
texX = std::max(0.0f, std::min(texX, static_cast(texSize.x - 1)));
int sliceWidth = m_engineSettings.resolution.x / m_engineSettings.numRays;
sf::Sprite sprite;
sprite.setTexture(tex);
sf::IntRect subRect(static_cast(texX), 0, sliceWidth, texSize.y);
sprite.setTextureRect(subRect);
sprite.setScale(1.0f, spriteHeightScreen / texSize.y);
sprite.setPosition(x * sliceWidth, topSpriteScreen);
float shade = std::min(1.0f, 256.0f / distToSprite);
sf::Uint8 shadeValue = static_cast(255 * shade);
sprite.setColor(sf::Color(shadeValue, shadeValue, shadeValue, 255));
m_renderTexture.draw(sprite);
}
}
}
Mobile version