As the title says, I've been having some issues mixing OpenGL and SFML.
Ultimately, I want to be able to draw to a framebuffer, and then sample from that framebuffer in shaders that most of my sprites will use. The object drawn to the framebuffer will be 3D, but everything else is 2D, so ideally most of this can be done with SFML rather than raw OpenGL.
I already have a 100% OpenGL solution that works, however obviously it would be nice if I could clean things up with SFML instead. Specifically, I already use
sf::Sprite in a lot of places, so I want to get things working with that so I don't need to re-write all of my drawing code.
In order to get this working, I think I need one of two things to work:
1. Binding an OpenGL texture to an sf::SpriteI have not been able to get this to work; nothing is drawn to the screen. I have also tried this with an
sf::RectangleShape, which does get drawn to the screen, but is missing the texture.
The relevant bits of my code for this part look like this:
// --- initialization ---
{ // Shaders
const char* vs = R"(
#version 330 core
layout (location = 0) in vec2 pos;
layout (location = 1) in vec2 texCoords;
out vec2 TexCoords;
void main()
{
TexCoords = texCoords;
gl_Position = vec4(pos, 0.0, 1.0);
}
)";
const char* fs = R"(
#version 330 core
out vec4 color;
in vec2 TexCoords;
uniform sampler2D screenTexture;
void main()
{
color = vec4(texture(screenTexture, TexCoords).rrr, 1.0);
}
)";
makeShader(_spriteShader, vs, fs);
}
{ // FrameBuffer
glGenFramebuffers(1, &_frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
glGenTextures(1, &_sampleTexture);
glBindTexture(GL_TEXTURE_2D, _sampleTexture);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, CONST.WIN.WIDTH, CONST.WIN.HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, CONST.WIN.WIDTH, CONST.WIN.HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); // Only using the depth component for right now
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _sampleTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _sampleTexture, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
sprite.setScale(sf::Vector2f(1.0 / 3.0, 1.0 / 3.0));
sprite.setPosition(0, WINDOW_HEIGHT * 2.0 / 3.0);
// --- drawing ---
// ...
// draw to framebuffer...
// ...
// draw framebuffer to screen
_window.pushGLStates();
_window.setView(_window.getDefaultView());
glUseProgram(_spriteShader);
glBindTexture(GL_TEXTURE_2D, _texture);
_window.draw(sprite);
rect.setPosition(0,0);
_window.draw(rect);
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);
_window.popGLStates();
I'm not sure how the implementation of
sf::Sprite handles vertex and texture coordinates, so there definitely could be an issue there compared to what my shader is expecting.
Alternatively, is there a way to create an
sf::Texture from an OpenGL texture (preferably without making a copy?) I'm not sure if the shader or the texture is to blame here, but if it's the texture, that might be an easier solution.
2. Using an sf::RenderTexture instead of an OpenGL framebuffer + textureI was having some other issues with this one earlier, so you can see my code for this on
StackOverflow. I was able to solve some of the problems, but as of right now I can draw SFML objects to my
RenderTexture, but my OpenGL draw calls to the same
RenderTexture don't seem to do anything. I am at a loss for this one because I was able to draw directly to the window with minimal modifications, and it works fine.
Anyway, does anyone know if either of these solutions is possible, or if I am doing something wrong? I am new to OpenGL, so there is a high likelihood that both of these issues are just stupid mistakes on my part. Or maybe there is an even simpler solution that I don't know about yet.
Any insight is appreciated. Please let me know if I should provide more information or code.