GLSL C++ glVertexAttribPointer & glDrawElements return GL_INVALID_OPERATION
GLSL C++ glVertexAttribPointer & glDrawElements return GL_INVALID_OPERATION
我得到错误GL_INVALID_OPERATION
行:164和183,我不知道如何解决它。
第 164 行:
GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0));
第 183 行:
GLCall(glDrawElements(GL_TRIANGLES, 6 ,GL_UNSIGNED_INT, nullptr));
我正在使用带有OpenGL版本字符串的Ubuntu 18.04:3.1 Mesa 18.3.0-devel - padoka PPA。 顺便说一下,我想画一个立方体。
主要:
#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 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);
};
在拥有当前有效的 OpenGL 上下文之前,您不能调用任何 OpenGL 指令。
此外,glfwWindowHint
和glfwMakeContextCurrent
不是OpenGL指令。
所以宏GLCall
检查glError
,比如
GLCall(glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4));
....
和
GLCall(glfwMakeContextCurrent(window));
无效且没有任何意义。
宏GLCall
的第一个有效使用将在glfwMakeContextCurrent(window)
之后。
由于您使用的是具有向前兼容性的核心配置文件上下文:
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);
您必须创建一个绑定名为顶点数组对象。
请注意,在核心配置文件上下文中,默认顶点数组对象 (0( 无效。
在创建缓冲区对象并定义通用顶点属性数据数组之前,创建并绑定一个命名顶点数组对象就足够了。此对象取代兼容性配置文件中的默认顶点数组对象:
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));
在初始化 GLEW 之前设置glewExperimental = GL_TRUE
。
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK) std::cout << "Error!" << std::endl;
请参阅GLEW文档,其中说:
GLEW 从图形驱动程序获取有关支持的扩展的信息。但是,实验性或预发布驱动程序可能不会通过标准机制报告每个可用的扩展,在这种情况下,GLEW 将报告它不受支持。为了规避这种情况,可以通过在调用
glewInit()
之前将其设置为GL_TRUE
来打开glewExperimental
全局开关,从而确保所有具有有效入口点的分机都将公开。
相关文章:
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 如何处理 c++ 中类实现中的"invalid use of non-static data member"?
- C++ "error: invalid use of void expression"
- 收到错误"invalid use of non-static data member 'stu::n' "
- Poloniex API "Invalid command" c++ libcurl
- Visual Studio 19-17 库兼容性根据 GL 标志
- C++模板错误:"invalid explicitly-specified argument for template parameter"
- SDL_CreateTextureFromSurface() "Invalid texture"错误?
- C++ "Invalid use of 'this' in non-member function" ,
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- glDrawElements GL 错误类型 = 0x824c,严重性 = 0x9146,消息 = GL_INVALID
- 继承类时"invalid use of incomplete type ‘class tree_node_t’"
- 为什么我会"Invalid read of size 8"?(瓦尔格林德)
- 将"Compass"与相机旋转隔离开GL
- "fast"或"normal"在"free(): invalid next size (fast)"中是什么意思?
- 如何在Arduino程序中解决"invalid operands of types"?
- 如何'Invalid conversion'和'no match for operator'更正这些 c++ 错误
- 是否有一个版本的glCopyImageSubData在Openg GL中使用混合?
- 访问函数变体时"Invalid conversion"错误
- glBindFramebuffer 在使用 GL_DRAW_FRAMEBUFFER 目标时会导致 "invalid operation" GL 错误