Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: GL_INVALID_OPERATION when pushGLStates()  (Read 4199 times)

0 Members and 2 Guests are viewing this topic.

sodah

  • Newbie
  • *
  • Posts: 11
    • View Profile
GL_INVALID_OPERATION when pushGLStates()
« on: June 03, 2013, 08:29:33 pm »
So, im just starting GL with sfml. When i try to pushGLStates to draw a simple circle i get GL_INVALID_OPERATION in current state in the console.

My textured quad i try to draw afterwards comes out fine.

the problems starts when i bind my first vertexarray at line 43
//OpenGL
#include <gl\glew.h>
#include <gl\freeglut.h>
#include <glm\glm.hpp>
#include <glm\ext.hpp>

//SFML
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML\OpenGL.hpp>

//Std
#include <string>
#include <iostream>

//Stuff
#include "ShaderManager.hpp"
#include "Convertion.hpp"

//test
#include "Cube.hpp"
int main()
{
    // create the window
    sf::RenderWindow window(sf::VideoMode(800, 600), "OpenGL");

        GLenum GlewInitResult;
        GlewInitResult = glewInit();

        if (GLEW_OK != GlewInitResult) {
                fprintf(
                        stderr,
                        "ERROR: %s\n",
                        glewGetErrorString(GlewInitResult)
                );
                exit(EXIT_FAILURE);
        }
        sf::Clock clock;

        GLuint program = ShaderManager::LoadShaders("Simple_vertex.glsl", "Simple_fragment.glsl");
       
        GLuint VertexArrayID;
        glGenVertexArrays(1, &VertexArrayID);
        glBindVertexArray(VertexArrayID);

        Cube* cube = new Cube();
       
        // This will identify our vertex buffer
        GLuint vertexbuffer;
        // Generate 1 buffer, put the resulting identifier in vertexbuffer
        glGenBuffers(1, &vertexbuffer);
        // The following commands will talk about our 'vertexbuffer' buffer
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        // Give our vertices to OpenGL.
        glBufferData(GL_ARRAY_BUFFER, cube->getVertices().size() * sizeof(float), &cube->getVertices()[0], GL_STATIC_DRAW);

        static const GLfloat g_uv_buffer_data[] = {
                1.0, 1.0,
                0.0, 1.0,
                0.0, 0.0,

                0.0, 0.0,
                1.0, 0.0,
                1.0, 1.0 };

        // This will identify our vertex buffer
        GLuint UVbuffer;
        // Generate 1 buffer, put the resulting identifier in vertexbuffer
        glGenBuffers(1, &UVbuffer);
        // The following commands will talk about our 'vertexbuffer' buffer
        glBindBuffer(GL_ARRAY_BUFFER, UVbuffer);
        // Give our vertices to OpenGL.
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW);
    // load resources, initialize the OpenGL states, ...

        glm::mat4 Projection = glm::perspective(75.0f, 4.0f/3.0f, 0.1f, 100.0f);
        glm::mat4 View = glm::lookAt(glm::vec3(0,0,-10), glm::vec3(0,0,0), glm::vec3(0,1,0)); // pos, looking at, upvector
        glm::mat4 Model = glm::mat4(1.0f);
        glm::mat4 MVP = Projection * View * Model;

        GLuint MatrixID = glGetUniformLocation(program, "MVP");

        glEnable(GL_DEPTH_TEST);
        glDepthMask(GL_TRUE);
        glClearDepth(1.f);

        glEnable(GL_TEXTURE_2D);

    GLuint texture = 0;
    {
        sf::Image image;
        if (!image.loadFromFile("lolcat.png"))
            return EXIT_FAILURE;

        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getSize().x, image.getSize().y, 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);
    }

        glBindTexture(GL_TEXTURE_2D, texture);

        GLuint TextureID  = glGetUniformLocation(program, "textureSampler");
        glUniform1i(TextureID, 0);

        sf::CircleShape shape(50);
        shape.setFillColor(sf::Color(100,250,20));

        // run the main loop
    bool running = true;
    while (running)
    {
        // handle events
        sf::Event Event;
        while (window.pollEvent(Event))
        {
            if (Event.type == sf::Event::Closed)
            {
                // end the program
                running = false;
            }
            else if (Event.type == sf::Event::Resized)
            {
                // adjust the viewport when the window is resized
                glViewport(0, 0, Event.size.width, Event.size.height);
            }
        }

        // clear the buffers
        glClear(GL_DEPTH_BUFFER_BIT);

                // 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
                );

                // UV
                glEnableVertexAttribArray(1);
                glBindBuffer(GL_ARRAY_BUFFER, UVbuffer);
                glVertexAttribPointer(
                        1,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
                        2,                  // size
                        GL_FLOAT,           // type
                        GL_FALSE,           // normalized?
                        0,                  // stride
                        (void*)0            // array buffer offset
                );

                glUseProgram(program);
                glUniformMatrix4fv(MatrixID,1,GL_FALSE, &MVP[0][0]);

                // Draw the triangle !
                glDrawArrays(GL_TRIANGLES, 0, 6); // Starting from vertex 0; 3 vertices total -> 1 triangle
 
                glUseProgram(0);

        // end the current frame (internally swaps the front and back buffers)

                window.pushGLStates();
                window.draw(shape);
                window.popGLStates();
               
                window.display();
    }

    // release resources...

    return 0;
}
 

Any help would be appriciated :-)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #1 on: June 03, 2013, 08:50:02 pm »
Can you please provide a minimal example that we can test: remove all the external libs and irrelevant code from your project.
Laurent Gomila - SFML developer

sodah

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #2 on: June 03, 2013, 10:42:54 pm »
I sort of found the problem:
 glUniform1i(TextureID, 0);
I've been following this tutorial: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/

but i guess this is not nessesary... if i remove this line i get no more INVALID_OPERATION.

Still, my green circle thats supposed to be rendered before and after my GL drawing aint showing still.

#include <gl\glew.h>
#include <gl\freeglut.h>
#include <SFML\OpenGL.hpp>
#include <SFML\Window.hpp>
#include <SFML\Graphics.hpp>

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>

#include <stdlib.h>
#include <string.h>

GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path);

int main()
{
    // create the window
        sf::RenderWindow window(sf::VideoMode(800, 600), "SFML OpenGL", sf::Style::Default, sf::ContextSettings(32));

        GLenum GlewInitResult;
        glewExperimental = true;
        GlewInitResult = glewInit();

        if (GLEW_OK != GlewInitResult) {
                fprintf(
                        stderr,
                        "ERROR: %s\n",
                        glewGetErrorString(GlewInitResult)
                );
                exit(EXIT_FAILURE);
        }

        // Enable depth test
        //glEnable(GL_DEPTH_TEST);

        GLuint program = LoadShaders("Simple_vertex.glsl", "Simple_fragment.glsl");

        float verts[3*6] = {
        1.0, 1.0, 0.0,
        -1.0, 1.0, 0.0,
        -1.0, -1.0, 0.0,

        -1.0, -1.0, 0.0,
        1.0, -1.0, 0.0,
        1.0, 1.0, 0.0
        };

        // This will identify our vertex buffer
        GLuint vertexbuffer;
        glGenBuffers(1, &vertexbuffer);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);

        static const GLfloat g_uv_buffer_data[] = {
        1.0, 1.0,
        0.0, 1.0,
        0.0, 0.0,

        0.0, 0.0,
        1.0, 0.0,
        1.0, 1.0 };

        //Binding Uv
        GLuint UVbuffer;
        glGenBuffers(1, &UVbuffer);
        glBindBuffer(GL_ARRAY_BUFFER, UVbuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW);

    GLuint texture = 0;
    {
        sf::Image image;
        if (!image.loadFromFile("lolcat.png"))
            return EXIT_FAILURE;

        glGenTextures(1, &texture);
                glBindTexture(GL_TEXTURE_2D, texture);
        gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getSize().x, image.getSize().y, 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);
    }

        // Enable Z-buffer read and write
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glClearDepth(1.f);

        //bind texture
        glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);

        GLuint TextureID  = glGetUniformLocation(program, "textureSampler");
        //glUniform1i(TextureID, 0);

        sf::CircleShape shape(200);
        shape.setFillColor(sf::Color(100,250,20));

        // run the main loop
    bool running = true;
    while (running)
    {
        // handle events
        sf::Event Event;
        while (window.pollEvent(Event))
        {
            if (Event.type == sf::Event::Closed)
            {
                // end the program
                running = false;
            }
            else if (Event.type == sf::Event::Resized)
            {
                // adjust the viewport when the window is resized
                glViewport(0, 0, Event.size.width, Event.size.height);
            }
        }

                window.pushGLStates();
                window.draw(shape);
                window.popGLStates();

        // Clear the depth buffer
        glClear(GL_DEPTH_BUFFER_BIT);

                // 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
                );

                // UV
                glEnableVertexAttribArray(1);
                glBindBuffer(GL_ARRAY_BUFFER, UVbuffer);
                glVertexAttribPointer(
                        1,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
                        2,                  // size
                        GL_FLOAT,           // type
                        GL_FALSE,           // normalized?
                        0,                  // stride
                        (void*)0            // array buffer offset
                );

                glUseProgram(program);
                glDrawArrays(GL_TRIANGLES, 0, 6);
                glUseProgram(0);

        // end the current frame (internally swaps the front and back buffers)
       
                window.pushGLStates();
                window.draw(shape);
                window.popGLStates();
               
                window.display();
    }

    // release resources...

    return 0;
}

GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){

        // Create the shaders
        GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
        GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

        // Read the Vertex Shader code from the file
        std::string VertexShaderCode;
        std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
        if(VertexShaderStream.is_open()){
                std::string Line = "";
                while(getline(VertexShaderStream, Line))
                        VertexShaderCode += "\n" + Line;
                VertexShaderStream.close();
        }else{
                printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
                return 0;
        }

        // Read the Fragment Shader code from the file
        std::string FragmentShaderCode;
        std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
        if(FragmentShaderStream.is_open()){
                std::string Line = "";
                while(getline(FragmentShaderStream, Line))
                        FragmentShaderCode += "\n" + Line;
                FragmentShaderStream.close();
        }

        GLint Result = GL_FALSE;
        int InfoLogLength;

        // Compile Vertex Shader
        printf("Compiling shader : %s\n", vertex_file_path);
        char const * VertexSourcePointer = VertexShaderCode.c_str();
        glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
        glCompileShader(VertexShaderID);

        // Check Vertex Shader
        glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        if ( InfoLogLength > 0 ){
                std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
                glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
                printf("%s\n", &VertexShaderErrorMessage[0]);
        }

        // Compile Fragment Shader
        printf("Compiling shader : %s\n", fragment_file_path);
        char const * FragmentSourcePointer = FragmentShaderCode.c_str();
        glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
        glCompileShader(FragmentShaderID);

        // Check Fragment Shader
        glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        if ( InfoLogLength > 0 ){
                std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
                glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
                printf("%s\n", &FragmentShaderErrorMessage[0]);
        }

        // Link the program
        printf("Linking program\n");
        GLuint ProgramID = glCreateProgram();
        glAttachShader(ProgramID, VertexShaderID);
        glAttachShader(ProgramID, FragmentShaderID);
        glLinkProgram(ProgramID);

        // Check the program
        glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
        glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        if ( InfoLogLength > 0 ){
                std::vector<char> ProgramErrorMessage(InfoLogLength+1);
                glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
                printf("%s\n", &ProgramErrorMessage[0]);
        }
        glDeleteShader(VertexShaderID);
        glDeleteShader(FragmentShaderID);

        return ProgramID;
}
 

Vertex shader...
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;

varying vec2 texCoords;

void main(){

    vec4 v = vec4(vertexPosition_modelspace,1);
    gl_Position = v;

        texCoords = vertexUV;
}
 

fragment...
#version 330 core
// Ouput data
out vec4 fragColor;

uniform sampler2D textureSampler;
varying vec2 texCoords;

void main()
{
        fragColor = texture2D(textureSampler, texCoords);
}
 

I really dont know how to get around not using freeglut/glew.
If i comment out ALL GL-stuff, the circle renders.

I've been trying to "follow" the example in the SDK as much as possible but i guess im doing something wrong... :'(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #3 on: June 03, 2013, 10:47:16 pm »
GLEW cannot be avoided, you're right. But I fail to see where you're using FreeGLUT in this code.
Laurent Gomila - SFML developer

sodah

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #4 on: June 03, 2013, 11:05:02 pm »
If i dont, i get linkererrors from gluBuild2DMipmaps.
I've got latest glew and followed their instructions on where to put the files.

my linkerinput for debugging:

sfml-window-d.lib
sfml-graphics-d.lib
sfml-system-d.lib
glew32.lib
opengl32.lib

sodah

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #5 on: June 03, 2013, 11:12:18 pm »
Ya, forgot glu32.lib =(

Still, no green circle...

sodah

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #6 on: June 03, 2013, 11:30:21 pm »
found this thread: http://en.sfml-dev.org/forums/index.php?topic=7508.0

Seems to be a similiar problem. It works with old-style GL but not with VBOs etc... ?
I have the latest version of 2.0

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #7 on: June 04, 2013, 08:06:16 am »
Would you be able to simplify the program? No texture, no shader, etc.
Laurent Gomila - SFML developer

sodah

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #8 on: June 04, 2013, 12:54:14 pm »
#include <gl\glew.h>
#include <SFML\Window.hpp>
#include <SFML\Graphics.hpp>
#include <SFML\OpenGL.hpp>

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>

#include <stdlib.h>
#include <string.h>

GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path);

int main()
{
    // create the window
        sf::RenderWindow window(sf::VideoMode(800, 600), "SFML OpenGL", sf::Style::Default, sf::ContextSettings(32));

        glewExperimental = true;
        if (glewInit() != GLEW_OK) {
                exit(EXIT_FAILURE);
        }

        float verts[3*3] = {
        1.0, 1.0, 0.0,
        -1.0, 1.0, 0.0,
        -1.0, -1.0, 0.0
        };

        // This will identify our vertex buffer
        GLuint vertexbuffer;
        glGenBuffers(1, &vertexbuffer);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
        sf::CircleShape shape(200);
        shape.setFillColor(sf::Color(100,250,20));

        // run the main loop
    bool running = true;
    while (running)
    {
        // handle events
        sf::Event Event;
        while (window.pollEvent(Event))
        {
            if (Event.type == sf::Event::Closed)
            {
                // end the program
                running = false;
            }
        }

        glClear(GL_DEPTH_BUFFER_BIT);

                // 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
                );

                glDrawArrays(GL_TRIANGLES, 0, 3);

                glBindBuffer(GL_ARRAY_BUFFER, 0); //Fixes the problem
                glDisableVertexAttribArray(0); //Fixes the problem

                window.pushGLStates();
                window.draw(shape);
                window.popGLStates();
               
                window.display();
    }

    // release resources...

    return 0;
}

Newbie mistake i guess, forgetting to unbind and disable the vertex array...
or is pushGLStates supposed to handle this?

Anyways... atleast i learnt a tiny bit of GL ^^ Thx!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #9 on: June 04, 2013, 12:56:18 pm »
Quote
Newbie mistake i guess, forgetting to unbind and disable the vertex array...
Do you need both to solve the problem, or only one is enough?

Quote
or is pushGLStates supposed to handle this?
Yes it is. You shouldn't have to care about this.
Laurent Gomila - SFML developer

sodah

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #10 on: June 04, 2013, 01:03:52 pm »
I need to disable both...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: GL_INVALID_OPERATION when pushGLStates()
« Reply #11 on: June 04, 2013, 01:09:10 pm »
Ok.

Currently, SFML doesn't take these states in account because they are specific to OpenGL 3. So until I find a solution, you have to call these two functions yourself.
Laurent Gomila - SFML developer