I'm using an sf::VertexArray and a multisample shader to draw the tile map in my game. This works fine, unless I try to draw something before it. When I do so, it messes with the texture coordinates in the multisampler. I found this
page, which mentions differing coordinates. Sure, enough, when I manually reset the GL_TEXTURE matrix before the shader, it works perfectly. However, I don't do any custom openGL rendering in my program, so why does SFML not handle the states properly itself? I'm happy to manually reset the texture matrix, but was just curious as to why I have to.
Aditionally I can call push/popGLState around each draw call and it works as well, however, calling resetGLStates does not work.
I also tried the fix listed
here, saying I should use sf::Shader::CurrentTexture, but that also did not work.
Also, should mention, I'm using one of the latest versions of SFML (Checking commits since my copy and they're all API updates, or irrelevant).
Anyway, here is a minimal app that demonstrates the issue (full app including shader attached):
#include <SFML/Graphics.hpp>
//Only included/linked to manually set GL_TEXTURE matrix to identity
#include <GL/glew.h>
#pragma comment(lib, "opengl32.lib")
int main() {
//Render window
sf::RenderWindow window( sf::VideoMode( 800, 600, 32 ), "GL States Issue" );
//Multisampler textures
sf::Texture prime1Tex;
sf::Texture prime2Tex;
sf::Texture prime3Tex;
prime1Tex.loadFromFile("prime1.png");
prime2Tex.loadFromFile("prime2.png");
prime3Tex.loadFromFile("prime3.png");
//Mutlisample shader - Samples from 3 repeating prime textures to significantly reduce tiling patterns
sf::Shader multisamplerShader;
multisamplerShader.loadFromFile("multisampler.sfx", sf::Shader::Fragment);
sf::Vector2f size;
multisamplerShader.setParameter("prime1Tex", prime1Tex);//sf::Shader::CurrentTexture);
size.x = 1.0f / prime1Tex.getSize().x;
size.y = 1.0f / prime1Tex.getSize().y;
multisamplerShader.setParameter("prime1Size", size);
multisamplerShader.setParameter("prime2Tex", prime2Tex);
size.x = 1.0f / prime2Tex.getSize().x;
size.y = 1.0f / prime2Tex.getSize().y;
multisamplerShader.setParameter("prime2Size", size);
multisamplerShader.setParameter("prime3Tex", prime3Tex);
size.x = 1.0f / prime3Tex.getSize().x;
size.y = 1.0f / prime3Tex.getSize().y;
multisamplerShader.setParameter("prime3Size", size);
//Random extra sprite to draw
sf::Sprite proj;
sf::Texture projTex;
projTex.loadFromFile("randomsprite.png");
proj.setTexture(projTex);
//Vertex array storing tile data.
sf::VertexArray tileDetails;
tileDetails.setPrimitiveType(sf::Triangles);
tileDetails.append(sf::Vertex(sf::Vector2f(20.0f, 20.0f), sf::Vector2f(20.0f,20.0f)));
tileDetails.append(sf::Vertex(sf::Vector2f(20.0f, 500.0f), sf::Vector2f(20.0f,500.0f)));
tileDetails.append(sf::Vertex(sf::Vector2f(500.0f, 500.0f), sf::Vector2f(500.0f,500.0f)));
bool run = true;
while(run)
{
window.clear(sf::Color::Cyan);
//Removing all these push/popGLState calls causes the multisample shader to mess up
//window.pushGLStates();
window.draw(proj);
//window.popGLStates();
//Just using this works
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
//Just using this does not work
//window.resetGLStates();
//window.pushGLStates();
//Even trying the fix of setting the first texture in the shader to sf::Shader::CurrentTexture, and
//then passing it in through sf::RenderStates does not work. It changes how the shader messes up however
sf::RenderStates states;
//states.texture = &prime1Tex;
states.shader = &multisamplerShader;
window.draw(tileDetails, states);
//window.popGLStates();
window.display();
sf::Event Event;
while (window.pollEvent(Event))
{
if ((Event.type == sf::Event::KeyPressed && (Event.key.code == sf::Keyboard::Escape))) {run = false; }
}
}
}
[attachment deleted by admin]