I've been trying to put together a game with opengl using SFML to manage the window & texture loading, and I've been running into some difficulties.
Firstly, as a bit of a warning, I do not have much experience with opengl, and to me, this seems like it should work (or at the very least, still draw the SFML shape). Secondly, I've been following the opengl tutorials at open.gl, and this program is essentially a mix between the SFML test code, and the code from one of the tutorials, as I want to test to make sure my drawing actually works
Forgive me if this is not the correct place to ask for help (as the problem is likely rooted in my opengl code), but it seems to be affecting the SFML stuff too.
The stages of error, through commenting out parts of the code:
* With all of the opengl stuff commented out, everything works fine, the green circle is drawn.
* After uncommenting the shader and VAO stuff, the circle does not display. (starting when the vbo binding and filling is uncommented)
* Uncommenting line 96, in which I attempt to bind a texture loaded via SFML into a shader ( "glUniform1i(glGetUniformLocation(shaders, "tex"), 0);") produces an error upon closing the application window: "An internal OpenGL call failed in Texture.cpp (110) : GL_INVALID_OPERATION, the specified operation is not allowed in the current state"
So, my question is: Is there something wrong with my code (most likely) (and if so, what), or is it just a bad idea in general to draw something via SFML when also using OpenGL?
Apologies in advance that the sample code I have is about 120 lines long. Due to the opengl stuff, I couldn't get it much shorter.
#include <iostream>
#include "RenderMaster.hpp" // The class which I'm later going to be using for my rendering
#include <SFML\Graphics.hpp>
#include <GL\glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works! Opengl, however, doesn't.");
glewExperimental = GL_TRUE;
glewInit();
const GLchar* vertex1 = // Vertex form: posx, posy, posz, texx, texy
"#version 150 core\n"
"in vec3 position;"
"in vec2 texcoord;"
"out vec2 Texcoord;"
"uniform mat4 model;"
"uniform mat4 view;"
"uniform mat4 proj;"
"void main() {"
" Texcoord = texcoord;"
" gl_Position = proj * view * model * vec4(position, 1.0);"
"}";
const GLchar* fragment1 =
"#version 150 core\n"
"in vec2 Texcoord;"
"out vec4 outColor;"
"uniform sampler2D tex;"
"void main() {"
" outColor = texture(tex, Texcoord);"
"}";
GLuint vao;
glGenVertexArrays(1, &vao);
GLuint vbo;
glGenBuffers(1, &vbo);
float vertices[] = {
// Position Texcoords
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f // Bottom-left
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint vertexShader1 = glCreateShader(GL_VERTEX_SHADER); // Create the two shaders
glShaderSource(vertexShader1, 1, &vertex1, NULL);
glCompileShader(vertexShader1);
GLuint fragmentShader1 = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader1, 1, &fragment1, NULL);
glCompileShader(fragmentShader1);
GLint shaders = glCreateProgram(); //Actually create the program
glAttachShader(shaders, vertexShader1);
glAttachShader(shaders, fragmentShader1);
glBindFragDataLocation(shaders, 0, "outColor");
glLinkProgram(shaders);
glBindVertexArray(vao);
GLint position1 = glGetAttribLocation(shaders, "position"); //Attribute setup
glEnableVertexAttribArray(position1);
glVertexAttribPointer(position1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
GLint texture1 = glGetAttribLocation(shaders, "texcoord");
glEnableVertexAttribArray(texture1);
glVertexAttribPointer(texture1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
glDeleteShader(fragmentShader1); //Delete shaders... They're already linked!
glDeleteShader(vertexShader1);
glm::mat4 view = glm::lookAt(
glm::vec3(1.2f, 1.2f, 1.2f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f)
);
GLint uniView = glGetUniformLocation(shaders, "view");
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));
glm::mat4 proj = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.0f, 10.0f);
GLint uniProj = glGetUniformLocation(shaders, "proj");
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
glm::mat4 model = glm::mat4();
GLint uniModel = glGetUniformLocation(shaders, "model");
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(proj));
sf::Texture t;
t.loadFromFile("MapTile.png");
sf::Texture::bind(&t);
glUniform1i(glGetUniformLocation(shaders, "tex"), 0);
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawBuffer(GL_BACK);
window.draw(shape);
// Swap buffers
window.display();
}
sf::Texture::bind(0);
return 0;
}