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()





Wow Thank you It works right now. Yeah I am pretty new at glsl xD.
– SomeGuy
Aug 27 at 12:59





@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.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)