0
\$\begingroup\$

I'm using SFML to make a pseudo 3d engine (Technically not software rendered since SFML uses OpenGL) and things are going rather swimmingly, but then I tried to make another wall, the picture says everything:

:(

The artifact gets worse the closer you get to the wall on the left.

And the Code...

#include "Quad3B.h"


Quad3B::Quad3B() {
    pos = sf::Vector3f(0, 0, 1);
    size = sf::Vector3f(1, 1, 0);
    shape = sf::VertexArray(sf::Quads, 4);
    c = sf::Color::Red;
    color = true;
}

Quad3B::Quad3B(sf::Vector3f p) {
    pos = p;
    size = sf::Vector3f(1, 1, 0);
    shape = sf::VertexArray(sf::Quads, 4);
    c = sf::Color::Red;
    color = true;
}

Quad3B::Quad3B(sf::Vector3f p, sf::Vector3f s) {
    pos = p;
    size = s;
    shape = sf::VertexArray(sf::Quads, 4);
    c = sf::Color::Red;
    color = true;
}

Quad3B::Quad3B(sf::Vector3f p, sf::Vector3f s, sf::Color c) {
    pos = p;
    size = s;
    shape = sf::VertexArray(sf::Quads, 4);
    Quad3B::c = c;
    color = true;
}

void Quad3B::loadTexture(string path, sf::Vector2f ts) {
    color = false;
    tex.setRepeated(true);
    tex.loadFromFile(path);
    texp = sf::Vector2f(ts.x * tex.getSize().x, ts.y * tex.getSize().y);
}

void Quad3B::dr(sf::Vector3f camPos, sf::RenderWindow &window, float hw, float hh, float rat) {
    bool draw = true;

    shape[0].position = sf::Vector2f((((pos.x + camPos.x) * rat) / (pos.z + camPos.z)) * hw + hw, (-(pos.y + camPos.y) / (pos.z + camPos.z)) * hh + hh);
    shape[1].position = sf::Vector2f((((pos.x + camPos.x) * rat) / (pos.z + camPos.z)) * hw + hw, (-(pos.y + size.y + camPos.y) / (pos.z + camPos.z)) * hh + hh);
    shape[2].position = sf::Vector2f((((pos.x + size.x + camPos.x) * rat) / (pos.z + size.z + camPos.z)) * hw + hw, (-(pos.y + size.y + camPos.y) / (pos.z + size.z + camPos.z)) * hh + hh);
    shape[3].position = sf::Vector2f((((pos.x + size.x + camPos.x) * rat) / (pos.z + size.z + camPos.z)) * hw + hw, (-(pos.y + camPos.y) / (pos.z + size.z + camPos.z)) * hh + hh);

    if (color) {
        shape[0].color = c;
        shape[1].color = c;
        shape[2].color = c;
        shape[3].color = c;
    }
    else {
        shape[0].texCoords = sf::Vector2f(0, texp.y);
        shape[1].texCoords = sf::Vector2f(0, 0);
        shape[2].texCoords = sf::Vector2f(texp.x, 0);
        shape[3].texCoords = sf::Vector2f(texp.x, texp.y);
    }

    if (pos.z + camPos.z < 0) { draw = false; }
    if (draw) { if (color) { window.draw(shape); } else { window.draw(shape, &tex); } }
}

Quad3B::~Quad3B() { }
\$\endgroup\$
  • \$\begingroup\$ There's nothing strange going on. You're drawing triangles. Those triangles have 3 texture coordinates it interpolates between nicely. Since I'm not familiar with SFML, I won't be able to solve this for you. \$\endgroup\$ – Peethor Dec 2 '15 at 8:50
  • \$\begingroup\$ I accidently said "The wall on the right" if you were confused by that \$\endgroup\$ – user68817 Dec 2 '15 at 8:55
  • \$\begingroup\$ The picture doesn't say anything. Is the perspective the way you want it to be and just the texture coordinates are wrong or is the perspective wrong? \$\endgroup\$ – Philipp Dec 2 '15 at 10:15
  • \$\begingroup\$ The perspective is fine, when i add size to the z axis the texture goes odd \$\endgroup\$ – user68817 Dec 2 '15 at 11:25
  • \$\begingroup\$ Truly classic artifact! \$\endgroup\$ – Willy Goat Dec 4 '15 at 1:22
3
\$\begingroup\$

It seems you are projecting your 3D-coordinates into 2D-Space by yourself. So the 3D information is lost for any HW-acceleration. You need to supply 3D- information to your Positional Coordinates I think you can use sf::Vector3f and just use your z-coordinate as 3rd entry.

PS: Funny detail: you just implemented affine texture mapping which was the best thing people could do 20 years ago :)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy