GLSL C++ glVertexAttribPointer & glDrawElements return GL_INVALID_OPERATION
GLSL C++ glVertexAttribPointer & glDrawElements return GL_INVALID_OPERATION
I get the error GL_INVALID_OPERATION
in lines: 164 & 183 and I don't know how to fix it.
GL_INVALID_OPERATION
line 164:
GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0));
line 183:
GLCall(glDrawElements(GL_TRIANGLES, 6 ,GL_UNSIGNED_INT, nullptr));
I am using Ubuntu 18.04 with OpenGL version string: 3.1 Mesa 18.3.0-devel - padoka PPA.
By the way I want to draw a Cube.
main:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <sys/stat.h>
#define ASSERT(x) if (!(x)) std::cin.get();
#define GLCall(x) GLClearError();
x;
ASSERT(GLLogCall(#x, __FILE__, __LINE__))
static void GLClearError()
while(glGetError() != GL_NO_ERROR);
static bool GLLogCall(const char* function, const char* file, int line)
while(GLenum error = glGetError())
std::cout << "[OPENGL ERROR](" << error << ")" << function <<
" " << file << " line: " << line << std::endl;
return false;
return true;
struct ShaderProgramSource
std::string VertexSource;
std::string FragmentSource;
;
static ShaderProgramSource ParseShader(const std::string& filepath)
std::fstream stream (filepath);
enum ShaderType
NONE = -1, VERTEX = 0, FRAGMENT = 1
;
std::string _line;
std::stringstream ss[2];
ShaderType type = ShaderType::NONE;
while(getline(stream, _line))
if(_line.find("#shader") != std::string::npos)
if(_line.find("vertex") != std::string::npos)
type = ShaderType::VERTEX;
else if (_line.find("fragment") != std::string::npos)
type = ShaderType::FRAGMENT;
else
ss[(int)type] << _line << 'n';
return ss[0].str(), ss[1].str() ;
static unsigned CompileShader(unsigned type, const std::string& source)
std::cout << "Compile Shader n";
unsigned id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
// TODO: ERROR handling
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if(!result)
int lenght;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &lenght);
char* message = (char*)&source[0];
glGetShaderInfoLog(id, lenght, &lenght, message);
std::cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " " << std::endl;
std::cout << message << std::endl;
return 0;
return id;
static unsigned CreateShader(const std::string& vertexShader, const std::string& fragmentShader)
unsigned program = glCreateProgram();
unsigned vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
unsigned fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
int main(void)
GLFWwindow* window;
/* Initialize the library*/
if(!glfwInit())
return -1;
GLCall(glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4));
GLCall(glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3));
GLCall(glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE));
GLCall(glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE));
/* Create a windowed mode window and its OpenGl context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if(!window)
glfwTerminate();
return -1;
/* Make the window's context current */
GLCall(glfwMakeContextCurrent(window));
if(glewInit() != GLEW_OK) std::cout << "Error!" << std::endl;
std::cout << glGetString(GL_VERSION) << std::endl;
float positions =
-0.5f, -0.5f, //0
0.5f, -0.5f, //1
0.5f, 0.5f, //2
-0.5f, 0.5f //3
;
unsigned indices
0, 1, 2,
2, 3, 0
;
unsigned buffer;
GLCall(glGenBuffers(1, &buffer));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, buffer));
GLCall(glBufferData(GL_ARRAY_BUFFER, 6*2*sizeof(float), positions, GL_STATIC_DRAW));
GLCall(glEnableVertexAttribArray(0));
GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0));
unsigned ibo; //index buffer Object
GLCall(glGenBuffers(1, &ibo));
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo));
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned), indices, GL_STATIC_DRAW));
//TODO: Relative path
ShaderProgramSource source = ParseShader("Path"); //This path leads to Shaders
unsigned shader = CreateShader(source.VertexSource, source.FragmentSource);
GLCall(glUseProgram(shader));
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
/* Render here */
GLCall(glClear(GL_COLOR_BUFFER_BIT));
GLCall(glDrawElements(GL_TRIANGLES, 6 ,GL_UNSIGNED_INT, nullptr));
/* Swap front and back buffers */
GLCall(glfwSwapBuffers(window));
/* Poll for and process events */
GLCall(glfwPollEvents());
glfwTerminate();
return 0;
Shader:
#shader vertex
#version 330 core
layout(location = 0) in vec4 position;
void main()
gl_Position = position;
;
#shader fragment
#version 330 core
layout(location = 0) out vec4 color;
void main()
color = vec4(0.0, 1.0, 0.0, 1.0);
;
1 Answer
1
You can't call any OpenGL instructions, before you have a current and valid OpenGL context.
Further, glfwWindowHint
and glfwMakeContextCurrent
are no OpenGL instructions.
glfwWindowHint
glfwMakeContextCurrent
So the glError
checks by the macro GLCall
, like
glError
GLCall
GLCall(glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4));
....
and
GLCall(glfwMakeContextCurrent(window));
are invalid and doesn't make any sense.
The first valid use of the macro GLCall
would be after glfwMakeContextCurrent(window)
.
GLCall
glfwMakeContextCurrent(window)
Since you are using a core profile context, with forward compatibility:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
you have to create an bind a named Vertex Array Object.
Note, in a core profile context the default vertex array object (0) is not valid.
It is sufficient to create and bind one named vertex array object, before you create the buffer objects and define the array of generic vertex attribute data. This object takes place of the default vertex array object in compatibility profile:
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
unsigned buffer;
GLCall(glGenBuffers(1, &buffer));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, buffer));
GLCall(glBufferData(GL_ARRAY_BUFFER, 6*2*sizeof(float), positions, GL_STATIC_DRAW));
GLCall(glEnableVertexAttribArray(0));
GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0));
unsigned ibo; //index buffer Object
GLCall(glGenBuffers(1, &ibo));
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo));
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned), indices, GL_STATIC_DRAW));
Set glewExperimental = GL_TRUE
, before initializing GLEW.
glewExperimental = GL_TRUE
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK) std::cout << "Error!" << std::endl;
See the GLEW documantation which says:
GLEW obtains information on the supported extensions from the graphics driver. Experimental or pre-release drivers, however, might not report every available extension through the standard mechanism, in which case GLEW will report it unsupported. To circumvent this situation, the glewExperimental
global switch can be turned on by setting it to GL_TRUE
before calling glewInit()
, which ensures that all extensions with valid entry points will be exposed.
glewExperimental
GL_TRUE
glewInit()
@SomeGuy You're welcome.
– Rabbid76
Aug 27 at 13:01
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Wow Thank you It works right now. Yeah I am pretty new at glsl xD.
– SomeGuy
Aug 27 at 12:59