我有一个使用DerelictGL3和DerelictSDL2的简单D应用程序。我试图使用顶点缓冲区对象渲染红色三角形,但每当我运行glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, float.sizeof * 2, null);
时,glGetError()
返回1282(无效操作)。代码如下......
app.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.vert
#version 120
attribute vec2 position;
void main(void) {
gl_Position = vec4(position, 0, 1);
}
着色器/ minimal.frag
#version 120
void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
忽略错误时,屏幕右上角会显示一个红色矩形。
答案 0 :(得分:3)
您错过了OpenGL 3.2中所需的VAO。您可以在其他缓冲区之前创建它:
GLuint vao;
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);
答案 1 :(得分:1)
启用OpenGL调试日志记录可能会有所帮助,您可以这样做:https://github.com/d-gamedev-team/gfm/blob/master/opengl/gfm/opengl/opengl.d#L419
像NVIDIA这样的驱动程序会在出现问题时提供广泛警告,问题可能不是您认为的问题。