Hi to the SFML community. Thanks Laurent for giving us this invaluable library
Having recently decided to learn OpenGL I have been attempting to use SFML as a windowing system for 3D rendering. So far I have been using windowing libraries like glfw3, freeglut which work fine for simple projects but lack the extra functionality of SFML.
I have followed the tutorial:
http://www.sfml-dev.org/tutorials/2.2/window-opengl.php. After this I reviewed the example OpenGL + SFML project found in the SFML source. Now as mentioned I am new to OpenGL so was suprised when I found calls like:
// Enable position and texture coordinates vertex components
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), cube);
glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), cube + 3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(x, y, -100.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);
These don't seem to match the function calls used in the book I am reading: The OpenGL Programming Guide 8th ed. Which covers OpenGL 4.3. I assume these functions belong to older versions of OpenGL? Additionally the sample code doesn't, to my eyes, make use of shaders. From my understanding these are core to the workings of modern OpenGL?
Anyway here is my code so far:
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <iostream>
#include <cstdio>
#include <GL/glew.h>
#include <GL/glu.h>
#include <glm/glm.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include "LoadShaders.h"
////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
// Request a 32-bits depth buffer when creating the window
sf::ContextSettings contextSettings;
contextSettings.depthBits = 32;
contextSettings.minorVersion = 3;
contextSettings.majorVersion = 3;
// Create the main window
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML graphics with OpenGL", sf::Style::Default, contextSettings);
window.setVerticalSyncEnabled(true);
window.setActive();
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Configure the viewport (the same size as the window)
glViewport(0, 0, window.getSize().x, window.getSize().y);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
ShaderInfo shader_info[] =
{
{ GL_VERTEX_SHADER, "shaders/SimpleVertexShader.vertexshader" },
{ GL_FRAGMENT_SHADER, "shaders/SimpleFragmentShader.fragmentshader" },
{ GL_NONE, NULL }
};
// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders(shader_info);
static const GLfloat g_vertex_buffer_data[] =
{
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
// Start game loop
while (window.isOpen())
{
// Clear the depth buffer
glClear(GL_COLOR_BUFFER_BIT);
// Use our shader
glUseProgram(programID);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle
glDisableVertexAttribArray(0);
// Finally, display the rendered frame on screen
window.display();
// 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)
glViewport(0, 0, event.size.width, event.size.height);
}
}
glDeleteVertexArrays(1, &VertexArrayID);
glDeleteBuffers(1, &vertexbuffer);
glDeleteProgram(programID);
return EXIT_SUCCESS;
}
This code compiles and runs fine, but does not render the triangle as expected. Now when I swap the SFML window for a glfw3 window keeping essentially the same code apart from a few extra calls to glfw3 the triangle is rendered. Can anyone see where I am going wrong? If you require more information please let me know.
Thanks,
Haize