GLVertexAttributePointer导致D中的无效操作OpenGL错误
我有一个使用DerelictGL3和DerelictSDL2的简单D应用程序。我尝试使用顶点缓冲区对象渲染红色三角形,但是每当我运行GLVertexAttributePointer导致D中的无效操作OpenGL错误,opengl,d,derelict3,Opengl,D,Derelict3,我有一个使用DerelictGL3和DerelictSDL2的简单D应用程序。我尝试使用顶点缓冲区对象渲染红色三角形,但是每当我运行glvertexattributepointer(位置,2,GL_FLOAT,GL_FALSE,FLOAT.sizeof*2,null),glGetError()返回1282(无效操作)。代码如下 应用程序d import std.string; import std.conv; import std.stdio; import std.file; import s
glvertexattributepointer(位置,2,GL_FLOAT,GL_FALSE,FLOAT.sizeof*2,null)代码>,glGetError()
返回1282(无效操作)。代码如下
应用程序d
import std.string;
import std.conv;
import std.stdio;
import std.file;
import std.c.stdlib;
import derelict.opengl3.gl3;
import derelict.sdl2.sdl;
void main() {
DerelictSDL2.load();
DerelictGL3.load();
assert(SDL_Init(SDL_INIT_VIDEO) >= 0);
auto vertex_shader = (cast(string) read("shaders/minimal.vert")).toStringz;
auto fragment_shader = (cast(string) read("shaders/minimal.frag")).toStringz;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
auto final_param = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
auto window = SDL_CreateWindow("Triangle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, final_param);
assert(window);
SDL_GL_CreateContext(window);
DerelictGL3.reload();
GLfloat[] vertices = [1, 1, 1, -1, -1, 1, -0.8, -1, 1];
uint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.length * float.sizeof, vertices.ptr, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
auto program = glCreateProgram();
auto vshader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vshader, 1, &vertex_shader, null);
glCompileShader(vshader);
glAttachShader(program, vshader);
auto fshader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fshader, 1, &fragment_shader, null);
glCompileShader(fshader);
glAttachShader(program, fshader);
glLinkProgram(program);
glUseProgram(program);
auto position = glGetAttribLocation(program, "position");
auto close = false;
check();
while(!close) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) close = true;
}
glClearColor(1, 0.4, 0.4, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(position);
check("before"); // Does not return error.
glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, float.sizeof * 2, null); // <- Causing Invalid Operation GL error.
check("after"); // Returns error.
glDrawArrays(GL_TRIANGLES, 0, 3);
SDL_GL_SwapWindow(window);
}
}
void check(string msg="") {
auto error = glGetError();
assert(error == 0, msg ~ ":" ~ to!string(error));
}
着色器/minimal.frag
#version 120
void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
忽略错误时,屏幕右上角会呈现一个红色矩形。启用OpenGL调试日志可能会有所帮助,您可以这样做:
有些司机喜欢英伟达一号提供了广泛的警告,如果出了问题,问题可能不在你想的地方。 < P>你错过了OpenGL 3.2所要求的瓦奥。您可以在其他缓冲区之前创建它,如下所示:
GLuint vao;
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);
我不确定D特定的库和其他东西。您不需要明确要求SDL具有核心或兼容性配置文件,我也不知道SDL在这种情况下会做什么。但如果最终得到的是GL3.x core配置文件,则顶点数组对象是必需的,并且错误是可以理解的,因为在设置指针时没有VAO边界。将跨步设置为2*float.sizeof,这意味着每个属性之间有两个未使用的浮点。@derhass那么,如果不需要核心或兼容性配置文件,我就不能使用VBOs吗?我看到的其他示例包括SDL,其方式与上面相同,但使用VBOs。@Asraelite:我没有这么说。我根本没有谈论VBOs(你可以在任何配置文件中使用它们),但是VAOs,不同的东西。我所说的是,您必须在core profile中使用VAOs,我不知道SDL是否会使用您设置的vae属性创建core profile。如果您使用的是OpenGL 3.2(如在窗口创建中指定的),为什么要在着色器中使用#version 120
?(OpenGL 3.2使用#版本150
)。
GLuint vao;
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);