Well I'm just trying to extend the OpenGL example with having it render the OpenGL specific stuff to a render texture to then be copied to the output window.
I can verify that the render texture have correct OpenGL states and that stuff are "rendered" to it. I randomize a clear color every frame and the render texture get that color. It is also copied to the window as I can see the effect. Removing the copy gives me a black screen with the example text. What doesn't work is the actual geometry. No cube is rendered to the render texture. I don't understand why? Am I missing something?
I know I have succeeded with this before but just this case where I am trying to only extend the OpenGL example I can't get it to work. What am I missing?
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
// Create the main window
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Deferred OpenGL", sf::Style::Default, sf::ContextSettings(32));
window.setVerticalSyncEnabled(true);
sf::RenderTexture geometryBuffer;
geometryBuffer.create(800, 600, true);
sf::Sprite geometrySprite(geometryBuffer.getTexture());
window.setActive();
// Create a sprite for the background
sf::Texture backgroundTexture;
if (!backgroundTexture.loadFromFile("resources/background.jpg"))
return EXIT_FAILURE;
sf::Sprite background(backgroundTexture);
// Load an OpenGL texture.
// We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function),
// but here we want more control on it (generate mipmaps, ...) so we create a new one from an image
GLuint texture = 0;
{
sf::Image image;
if (!image.loadFromFile("resources/texture.jpg"))
return EXIT_FAILURE;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getWidth(), image.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
// window.setActive();
geometryBuffer.setActive();
// Enable Z-buffer read and write
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glClearDepth(1.f);
glClearColor(0.f, 0.f, 0.f, 0.f);
// Setup a perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 800.f/600.f, 1.f, 100.f);
// Bind our texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glColor4f(1.f, 1.f, 1.f, 1.f);
// Create a clock for measuring the time elapsed
sf::Clock clock;
// Start game loop
while (window.isOpen())
{
// Process events
sf::Event event;
while (window.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
window.close();
// Escape key : exit
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
window.close();
// Adjust the viewport when the window is resized
if (event.type == sf::Event::Resized)
{
// window.setActive();
geometryBuffer.setActive();
glViewport(0, 0, event.size.width, event.size.height);
}
}
// Draw the background
window.pushGLStates();
window.draw(background);
window.popGLStates();
// Activate the window before using OpenGL commands.
// This is useless here because we have only one window which is
// always the active one, but don't forget it if you use multiple windows
// window.setActive();
geometryBuffer.setActive();
// Clear the depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Apply some transformations
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -5.f);
glRotatef(clock.getElapsedTime().asSeconds() * 50.f, 1.f, 0.f, 0.f);
glRotatef(clock.getElapsedTime().asSeconds() * 30.f, 0.f, 1.f, 0.f);
glRotatef(clock.getElapsedTime().asSeconds() * 90.f, 0.f, 0.f, 1.f);
// Draw a cube
float size = 1.f;
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(-size, -size, -size);
glTexCoord2f(0, 1); glVertex3f(-size, size, -size);
glTexCoord2f(1, 1); glVertex3f( size, size, -size);
glTexCoord2f(1, 0); glVertex3f( size, -size, -size);
glTexCoord2f(0, 0); glVertex3f(-size, -size, size);
glTexCoord2f(0, 1); glVertex3f(-size, size, size);
glTexCoord2f(1, 1); glVertex3f( size, size, size);
glTexCoord2f(1, 0); glVertex3f( size, -size, size);
glTexCoord2f(0, 0); glVertex3f(-size, -size, -size);
glTexCoord2f(0, 1); glVertex3f(-size, size, -size);
glTexCoord2f(1, 1); glVertex3f(-size, size, size);
glTexCoord2f(1, 0); glVertex3f(-size, -size, size);
glTexCoord2f(0, 0); glVertex3f(size, -size, -size);
glTexCoord2f(0, 1); glVertex3f(size, size, -size);
glTexCoord2f(1, 1); glVertex3f(size, size, size);
glTexCoord2f(1, 0); glVertex3f(size, -size, size);
glTexCoord2f(0, 1); glVertex3f(-size, -size, size);
glTexCoord2f(0, 0); glVertex3f(-size, -size, -size);
glTexCoord2f(1, 0); glVertex3f( size, -size, -size);
glTexCoord2f(1, 1); glVertex3f( size, -size, size);
glTexCoord2f(0, 1); glVertex3f(-size, size, size);
glTexCoord2f(0, 0); glVertex3f(-size, size, -size);
glTexCoord2f(1, 0); glVertex3f( size, size, -size);
glTexCoord2f(1, 1); glVertex3f( size, size, size);
glEnd();
geometryBuffer.display();
// Draw some text on top of our OpenGL object
window.pushGLStates();
window.draw(geometrySprite);
sf::Text text("SFML / OpenGL demo");
text.setColor(sf::Color(255, 255, 255, 170));
text.setPosition(250.f, 450.f);
window.draw(text);
window.popGLStates();
// Finally, display the rendered frame on screen
window.display();
std::cout << sf::err();
}
// Don't forget to destroy our texture
glDeleteTextures(1, &texture);
return EXIT_SUCCESS;
}
Also you are aware of that the projection matrix aspect ratio is wrong?
Update: Remade the example and if I uncomment the activation of the window and comment the geometry buffer activation it works like I would expect it to do. (Though the clear hides the background but it is expected so not weird)
Second Update: Tried with rendering a test sprite to the render texture and it works just like it should so rendering to the texture works. Just not opengl geometry? But SFML uses that behind the scene so what is missing?