digitalmars.D.learn - Derelict, SDL, and OpenGL3: Triangle Tribulations
- DarthCthulhu (71/71) Aug 11 2015 So I decided to try some OGL3 stuff in D utilizing the Derelict
- JN (6/12) Aug 11 2015 You need a vertex and a fragment shader. You can't render
- DarthCthulhu (11/34) Aug 11 2015 I thought that was the case, but the tutorial I was looking at
- BBasile (75/81) Aug 11 2015 For me the following code works:
- Mike Parker (10/84) Aug 11 2015 It seems to me that your driver is doing things it isn't actually
- BBasile (4/15) Aug 11 2015 Right, the triangle is well drawn but glGetError returns 1282.
- JN (7/26) Aug 12 2015 Depends on what context gets created in this case. A core profile
- Mike Parker (7/14) Aug 11 2015 I should point out that *either* DerelictGL3 *or* DerelictGL
- Mike Parker (11/12) Aug 11 2015 Too much to list. I suggest you get going with a good tutorial.
- Mike Parker (2/3) Aug 11 2015 [1] http://antongerdelan.net/opengl/index.html
So I decided to try some OGL3 stuff in D utilizing the Derelict bindings and SDL. Creating an SDL-OGL window worked fine, but I'm having trouble with doing the most basic thing of rendering a triangle. I get the window just fine and the screen is being properly cleared and buffered, but no triangle. Code: GLuint initVAO () { // An array of 3 vectors which represents 3 vertices static const GLfloat g_vertex_buffer_data[] = [ -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, ]; // This will identify our vertex buffer GLuint vertexbuffer; // Generate 1 buffer, put the resulting identifier in vertexbuffer glGenBuffers(1, &vertexbuffer); // The following commands will talk about our 'vertexbuffer' buffer glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); // Give our vertices to OpenGL. glBufferData(GL_ARRAY_BUFFER, g_vertex_buffer_data.length * GL_FLOAT.sizeof, g_vertex_buffer_data.ptr, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, null); glBindBuffer(GL_ARRAY_BUFFER, 0); return vertexbuffer; } void main() { string title = "Hello, world! With SDL2 OpenGL3.3!"; writefln(title); // Create a new OGL Window Window win = new SDL_OGL_Window(title); GLuint vertexbuffer = initVAO(); // Main loop flag bool quit = false; //Event handler SDL_Event e; glClearColor(0,0,0.4,0); do { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindVertexArray(vertexbuffer); // Draw the triangle glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(vertexbuffer); glBindVertexArray(0); SDL_GL_SwapWindow(win.window); // Handle events on queue while( SDL_PollEvent( &e ) != 0 ) { //User requests quit if( e.type == SDL_QUIT ) { quit = true; } } const Uint8* currentKeyStates = SDL_GetKeyboardState( null ); // Escape to quit as well. if( currentKeyStates[ SDL_SCANCODE_ESCAPE ] ) { quit = true;; } } while ( !quit ); glDeleteBuffers(1, &vertexbuffer); } The SDL_OGL_Window is an object that creates an SDL window and binds a OpenGL context to it; I don't think it's relevant for what's going on, but if anyone thinks it might be the culprit, I'll post it. So, any ideas what I'm doing wrong?
Aug 11 2015
On Wednesday, 12 August 2015 at 03:32:47 UTC, DarthCthulhu wrote:So I decided to try some OGL3 stuff in D utilizing the Derelict bindings and SDL. Creating an SDL-OGL window worked fine, but I'm having trouble with doing the most basic thing of rendering a triangle. I get the window just fine and the screen is being properly cleared and buffered, but no triangle. [...]You need a vertex and a fragment shader. You can't render anything in OGL3 without shaders. Also, you seem to be confusing Vertex Array Objects and Vertex Buffer Objects. You are creating a VBO and try to bind it as a VAO. You should put a glGenVertexArrays somewhere there.
Aug 11 2015
On Wednesday, 12 August 2015 at 05:26:33 UTC, JN wrote:You need a vertex and a fragment shader. You can't render anything in OGL3 without shaders.I thought that was the case, but the tutorial I was looking at didn't have any shaders at that point. I added a shader program.Also, you seem to be confusing Vertex Array Objects and Vertex Buffer Objects. You are creating a VBO and try to bind it as a VAO. You should put a glGenVertexArrays somewhere there.Aha! Yes, that's it, thanks! Once I understood the difference between VAO and VBOs, it was easy to fix. Thanks! On Wednesday, 12 August 2015 at 05:35:30 UTC, Mike Parker wrote:On Wednesday, 12 August 2015 at 03:32:47 UTC, DarthCthulhu wrote:On Wednesday, 12 August 2015 at 05:54:13 UTC, Mike Parker wrote:So, any ideas what I'm doing wrong?Too much to list. I suggest you get going with a good tutorial. One of the best I've seen is by Anton Gerdelan [1]. The four basic tutorials he has on his site will be enough to get you up and running. He used to have a lot more there, but he's published them all in a book. Even though there are numerous free resources online, I think Anton's ebook is well worth the ~$9.00 you pay for it. His tutorials are quite detailed and do a lot more than showing you a bunch of code to copy and paste. Work your way through that book and you'll know your way around well enough to do what you need to do for any basic OpenGL renderer.On Wednesday, 12 August 2015 at 05:35:30 UTC, Mike Parker wrote:Thanks very much for the resource! I had already looked at about a dozen different OGL3.x tutorials online, but this was the one which clicked for me. I'll definitely look into getting his book. Thanks again!One of the best I've seen is by Anton Gerdelan [1]. The four[1] http://antongerdelan.net/opengl/index.html
Aug 11 2015
On Wednesday, 12 August 2015 at 03:32:47 UTC, DarthCthulhu wrote:So I decided to try some OGL3 stuff in D utilizing the Derelict bindings and SDL. Creating an SDL-OGL window worked fine, but I'm having trouble with doing the most basic thing of rendering a triangle. I get the window just fine and the screen is being properly cleared and buffered, but no triangle. So, any ideas what I'm doing wrong?For me the following code works: --- import derelict.sdl2.sdl; import derelict.opengl3.gl3; import derelict.opengl3.gl; import std.stdio; static this() { DerelictGL3.load; DerelictGL.load; DerelictSDL2.load; SDL_Init(SDL_INIT_VIDEO); } static ~this() { SDL_Quit(); DerelictGL3.unload; DerelictSDL2.unload; } GLuint initVAO () { // An array of 3 vectors which represents 3 vertices static const GLfloat[] g_vertex_buffer_data = [ -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, ]; // This will identify our vertex buffer GLuint vertexbuffer; // Generate 1 buffer, put the resulting identifier in vertexbuffer glGenBuffers(1, &vertexbuffer); // The following commands will talk about our 'vertexbuffer' buffer glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); // Give our vertices to OpenGL. glBufferData(GL_ARRAY_BUFFER, g_vertex_buffer_data.length * GL_FLOAT.sizeof, g_vertex_buffer_data.ptr, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, null); glBindBuffer(GL_ARRAY_BUFFER, 0); return vertexbuffer; } void main(string[] args) { auto flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; auto win = SDL_CreateWindow( null, 50, 50, 800, 600, flags); auto ctxt = SDL_GL_CreateContext(win); DerelictGL3.reload; GLuint vertexbuffer = initVAO(); SDL_Event ev; while (true) { if (SDL_WaitEvent(&ev)) { glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindVertexArray(vertexbuffer); // Draw the triangle glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(vertexbuffer); glBindVertexArray(0); SDL_GL_SwapWindow(SDL_GL_GetCurrentWindow()); } if (ev.type == SDL_QUIT) break; } SDL_DestroyWindow(win); SDL_GL_DeleteContext(ctxt); } --- It looks like it's the window/context creation that fail for you because the OpenGL code is 100% the same.
Aug 11 2015
On Wednesday, 12 August 2015 at 05:34:22 UTC, BBasile wrote:For me the following code works: --- import derelict.sdl2.sdl; import derelict.opengl3.gl3; import derelict.opengl3.gl; import std.stdio; static this() { DerelictGL3.load; DerelictGL.load; DerelictSDL2.load; SDL_Init(SDL_INIT_VIDEO); } static ~this() { SDL_Quit(); DerelictGL3.unload; DerelictSDL2.unload; } GLuint initVAO () { // An array of 3 vectors which represents 3 vertices static const GLfloat[] g_vertex_buffer_data = [ -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, ]; // This will identify our vertex buffer GLuint vertexbuffer; // Generate 1 buffer, put the resulting identifier in vertexbuffer glGenBuffers(1, &vertexbuffer); // The following commands will talk about our 'vertexbuffer' buffer glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); // Give our vertices to OpenGL. glBufferData(GL_ARRAY_BUFFER, g_vertex_buffer_data.length * GL_FLOAT.sizeof, g_vertex_buffer_data.ptr, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, null); glBindBuffer(GL_ARRAY_BUFFER, 0); return vertexbuffer; } void main(string[] args) { auto flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; auto win = SDL_CreateWindow( null, 50, 50, 800, 600, flags); auto ctxt = SDL_GL_CreateContext(win); DerelictGL3.reload; GLuint vertexbuffer = initVAO(); SDL_Event ev; while (true) { if (SDL_WaitEvent(&ev)) { glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindVertexArray(vertexbuffer); // Draw the triangle glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(vertexbuffer); glBindVertexArray(0); SDL_GL_SwapWindow(SDL_GL_GetCurrentWindow()); } if (ev.type == SDL_QUIT) break; } SDL_DestroyWindow(win); SDL_GL_DeleteContext(ctxt); } --- It looks like it's the window/context creation that fail for you because the OpenGL code is 100% the same.It seems to me that your driver is doing things it isn't actually supposed to do. This code is binding a vertex buffer object with a function which is supposed to bind a vertex array object. The only reason the vbo is bound at all is because of the call to glBindBuffer in the misnamed initVAO -- a function which never even initializes a vao. The spec actually requires a vao to be created and a shader program to be bound, so I would expect a conforming driver to show nothing. I expect a couple of calls to glError will not come up empty.
Aug 11 2015
On Wednesday, 12 August 2015 at 05:46:27 UTC, Mike Parker wrote:On Wednesday, 12 August 2015 at 05:34:22 UTC, BBasile wrote:Right, the triangle is well drawn but glGetError returns 1282. Maybe the OP has a different OGL implementation. At least NVidia driver renders a triangle for this code.[...]It seems to me that your driver is doing things it isn't actually supposed to do. This code is binding a vertex buffer object with a function which is supposed to bind a vertex array object. The only reason the vbo is bound at all is because of the call to glBindBuffer in the misnamed initVAO -- a function which never even initializes a vao. The spec actually requires a vao to be created and a shader program to be bound, so I would expect a conforming driver to show nothing. I expect a couple of calls to glError will not come up empty.
Aug 11 2015
On Wednesday, 12 August 2015 at 05:58:23 UTC, BBasile wrote:On Wednesday, 12 August 2015 at 05:46:27 UTC, Mike Parker wrote:Depends on what context gets created in this case. A core profile context shouldn't render anything without a bound shader. NVidia likes backwards compatibility, so it's possible this code works, it's just using fixed function pipeline rendering, which isn't typically what people want when they mention "GL3". Might as well use glBegin/glEnd, and it would work too.On Wednesday, 12 August 2015 at 05:34:22 UTC, BBasile wrote:Right, the triangle is well drawn but glGetError returns 1282. Maybe the OP has a different OGL implementation. At least NVidia driver renders a triangle for this code.[...]It seems to me that your driver is doing things it isn't actually supposed to do. This code is binding a vertex buffer object with a function which is supposed to bind a vertex array object. The only reason the vbo is bound at all is because of the call to glBindBuffer in the misnamed initVAO -- a function which never even initializes a vao. The spec actually requires a vao to be created and a shader program to be bound, so I would expect a conforming driver to show nothing. I expect a couple of calls to glError will not come up empty.
Aug 12 2015
On Wednesday, 12 August 2015 at 05:34:22 UTC, BBasile wrote:static this() { DerelictGL3.load; DerelictGL.load; DerelictSDL2.load; SDL_Init(SDL_INIT_VIDEO); }I should point out that *either* DerelictGL3 *or* DerelictGL should be loaded, but never both. DerelictGL actually extends DerelictGL3. When you call load on it, it calls super.load (ditto for reload), with the net effect that you're loading all of the DerelictGL3 stuff twice. If you need the deprecated stuff, just use DerelictGL; if you don't, just use DerelictGL3.
Aug 11 2015
On Wednesday, 12 August 2015 at 03:32:47 UTC, DarthCthulhu wrote:So, any ideas what I'm doing wrong?Too much to list. I suggest you get going with a good tutorial. One of the best I've seen is by Anton Gerdelan [1]. The four basic tutorials he has on his site will be enough to get you up and running. He used to have a lot more there, but he's published them all in a book. Even though there are numerous free resources online, I think Anton's ebook is well worth the ~$9.00 you pay for it. His tutorials are quite detailed and do a lot more than showing you a bunch of code to copy and paste. Work your way through that book and you'll know your way around well enough to do what you need to do for any basic OpenGL renderer.
Aug 11 2015
On Wednesday, 12 August 2015 at 05:35:30 UTC, Mike Parker wrote:One of the best I've seen is by Anton Gerdelan [1]. The four[1] http://antongerdelan.net/opengl/index.html
Aug 11 2015