Re: [fpc-pascal] OpenGL and SDL frustrations
> On May 26, 2017, at 11:56 AM, nore...@z505.com wrote: > > All these calls look kind of tedious, instead of using a wrapper. But maybe > you want to learn opengl at its heart and not use a wrapper.. and learn all > the fine details the hard way (full respect for that). Imo I think it pays off to learn the actual graphics pipeline and what the process is really doing from direct memory in CPU to GPU. Graphics are so sensitive to performance and minor optimizations it would no doubt bother me deep down inside if I didn’t have 100% control over the process. Overall it’s only a minor part of the code actually so once you get it down it can be buried and not worried about later. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] OpenGL and SDL frustrations
> On May 25, 2017, at 7:02 PM, Anthony Walterwrote: > > Ryan, > > Are you loading the OpenGL API functions using SDL_GL_GetProcAddress? You > really should be doing that or you're asking for problems. > > Anyways, if you want maximum capability you should probably use ES version 2, > as it's supported on the most devices. It requires you to drop the fixed > function pipeline, that is dropping glBegin/glEnd and using GLSL vertex and > fragment shaders. It's mostly like OpenGL 2.0, with a few differences, like > there is no glMatrixMode. > I loaded the functions using Load_GL_VERSION_3_3 (and similar) from the Free Pascal RTL and it seems to correctly load the functions. Right now I’m using 2.1 and the fixed pipeline because I don’t really need shaders but I’m learning shaders and matrix transforms now so if there’s any performance benefit I can update my code base. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] OpenGL and SDL frustrations
On 2017-05-23 22:13, Ryan Joseph wrote: I’ve wasted so much time on this I just need to stop and ask for help already. Over the last few years I’ve been picking away at OpenGL and only ever got the legacy 2.x API to work which has been fine for making 2D games but I wanted to at least learn the modern API and shaders. Not sure what ZenGL uses for opengl version but why do you struggle to use opengl directly instead of using a wrapper like zengl that has already made the functions available for you... The only problem with using a wrapper like zengl or andorra is that of course it could go stale and not be updated, I'm not even sure if it uses 2.x, I have forgotten. [...] if SDL_Init(SDL_INIT_VIDEO) < 0 then Fatal('SDL could not initialize! '+SDL_GetError); // load function pointers if Load_GL_VERSION_3_3 = false then Fatal('OpenGL is not loaded'); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); // NOTE: 4.0 doesn't work, GL_VERSION return null SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); All these calls look kind of tedious, instead of using a wrapper. But maybe you want to learn opengl at its heart and not use a wrapper.. and learn all the fine details the hard way (full respect for that). ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] OpenGL and SDL frustrations
In our previous episode, Anthony Walter said: > And if you're not using GLSL shaders, then you don't need anything greater > than Open 1.5. You can see the list of changes at the link below. With the > exception of frame buffer objects (better known as render to texture) in > version 3.0 and up, there's likely very little you're going to need in the > 3.0+ realm of APIs you're ever going to need. > > https://www.khronos.org/opengl/wiki/History_of_OpenGL#Summary_of_version_changes PBO speeds up texture upload on most DX10+ cards. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] OpenGL and SDL frustrations
Ryan, Are you loading the OpenGL API functions using SDL_GL_GetProcAddress? You really should be doing that or you're asking for problems. Anyways, if you want maximum capability you should probably use ES version 2, as it's supported on the most devices. It requires you to drop the fixed function pipeline, that is dropping glBegin/glEnd and using GLSL vertex and fragment shaders. It's mostly like OpenGL 2.0, with a few differences, like there is no glMatrixMode. And if you're not using GLSL shaders, then you don't need anything greater than Open 1.5. You can see the list of changes at the link below. With the exception of frame buffer objects (better known as render to texture) in version 3.0 and up, there's likely very little you're going to need in the 3.0+ realm of APIs you're ever going to need. https://www.khronos.org/opengl/wiki/History_of_OpenGL#Summary_of_version_changes ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] OpenGL and SDL frustrations
> On May 25, 2017, at 2:30 PM, Anthony Walterwrote: > > You need to tell SDL what OpenGL kind and version before you create a window. > For example if you want OpenGLES 2.0 you would write: > > SDL_Init(SDL_INIT_VIDEO); > SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, > SDL_GL_CONTEXT_PROFILE_ES); > SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); > SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); > > If you want normal OpenGL 4.0 you would write: > > SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, > SDL_GL_CONTEXT_PROFILE_CORE); > SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); > SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); > That’s just a hint to SDL but it doesn’t guarantee anything. See my example below where I asked for 3.3 but got 4.1. I learned I can use a lower version of GLSL so I can enforce that version but for OpenGL I’m stuck on 4.1 or 2.1, at least on my Mac. That wouldn’t be a problem I guess but I’m trying to follow tutorials which have subtle things not work but I’m not using the same version as them. Maybe it doesn’t matter though and 4.1 will run on older graphics cards? No idea but it’s worrying. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] OpenGL and SDL frustrations
Oh and another note, you cannot load your gl function such as (glClear in my previous reply, this time I use glGenTextures): var glGenTextures: procedure(n: GLsizei; var textures: GLuint); cdecl; Until you create and make current your OpenGL context. SDL_GL_MakeCurrent(window, context); // after this is done the first time you can then load the OpenGL functions matching your requested version So the order is SDL_Init() SDL_GL_SetAttribute() multiple times SDL_CreateWindow() returns your window SDL_GL_CreateContext() returns your context SDL_GL_MakeCurrent() makes gl functions available SDL_GL_GetProcAddress() for every gl function in your requested version Then you are done initializing everything and can write a game/demo/whatever thing you want. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] OpenGL and SDL frustrations
You need to tell SDL what OpenGL kind and version before you create a window. For example if you want OpenGLES 2.0 you would write: SDL_Init(SDL_INIT_VIDEO); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); If you want normal OpenGL 4.0 you would write: SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); Then you can create the SDL and load the appropriate OpenGL function prototypes using: glClear := SDL_GL_GetProcAddress('glClear'); It's up to you to know which functions are part of which which OpenGL spec, and you should need to load the functions dynamically to stubs: var glClear: procedure(mask: GLbitfield); cdecl; Don't forget, if you want a specific values for stencil bits, pixel order, multisampling levels and other stuff, you need to set those values before you create a window. Check the return values of SDL_CreateWindow and SDL_GL_CreateContext to see if anything above fails, for example the target device doesn't support OpenGL 4.0. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8); // 8x anti-aliasing, must be called before SDL_CreateWindow SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 16); // 16 bit stencil buffer, must be called before SDL_CreateWindow ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] OpenGL and SDL frustrations
> On May 24, 2017, at 7:18 PM, Graeme Geldenhuys >wrote: > >> Any ideas on what’s wrong with this? > Ok, I got an answer from a person on YouTube and figured this out. The problem was 1) that SDL is returning a different version then I asked for and I didn’t do proper error checking. glEnableVertexAttribArray was failing for example because with OpenGL 4.1 (or earlier) a VAO is required before using VBO’s and 2) again, since 4.x, a shader is required to even draw white triangle. The demos I saw must have been on some version of 3.x but I was on 4.1. I’m still now sure how to guarantee SDL returns the version I want and it looks in your code you didn’t even try to specify anything besides core compatibility, not that it makes any difference because I always get 4.1 on my Mac or 2.1 and GLSL 1.2 for legacy mode. This begs the question of how I can write shaders if on any given computer I get a different version of GLSL. At least I got it working FINALLY after so much hassle but everything I do could easily break on others computers so... Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] OpenGL and SDL frustrations
On 2017-05-24 04:13, Ryan Joseph wrote: Any ideas on what’s wrong with this? I actually used the Java + OpenGL tutorials on YouTube, and translating those examples to Object Pascal + OpenGL + SDL2 was pretty easy. This is my favourite one, and uses "modern OpenGL" only. https://www.youtube.com/watch?v=VS8wlS9hF8E=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP "OpenGL 3D Game Tutorial" by ThinMatrix. I also wanted something reusable, so I implemented classes in separate units that I can reuse between projects. Instead of 100's of loosely scattered OpenGL API calls. I was actually going to contribute all this work as part of my Lazarus Graphics Programming Contest entry, but I might just release it earlier than that. Anyway, attached is one such unit setting up my display. I use proprietary NVIDIA drivers under FreeBSD, and I only target OpenGL 4.x with my code. It works perfectly here. My program code is pretty much like this: TDisplayManager.CreateDisplay; while running do begin // do the "gaming loop" here TDisplayManager.UpdateDisplay; end; // clean-up code here TDisplayManager.CloseDisplay; Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp unit DisplayManager; {$mode objfpc}{$H+} interface uses SDL2, GL, GLext; type TDisplayManager = class(TObject) private class var FSDLWindow: PSDL_Window; class var FSDLGLContext: TSDL_GLContext; const cWIDTH = 856; cHEIGHT = 480; public class procedure CreateDisplay; static; class procedure UpdateDisplay; static; class procedure CloseDisplay; static; //property SDLWindow: PSDL_Window read FSDLWindow; end; implementation { TDisplayManager } class procedure TDisplayManager.CreateDisplay; begin if SDL_Init(SDL_INIT_VIDEO) < 0 then HALT; // setting so that deprecated functions are disabled SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); //get an OpenGL window and create OpenGL context FSDLWindow := SDL_CreateWindow('OpenGL Game Tutorial', SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, cWIDTH, cHEIGHT, SDL_WINDOW_OPENGL); if FSDLWindow = nil then HALT; FSDLGLContext := SDL_GL_CreateContext(FSDLWindow); if FSDLGLContext = nil then HALT; //init OpenGL and load extensions if Load_GL_VERSION_4_0 = false then if Load_GL_VERSION_3_3 = false then if Load_GL_VERSION_3_2 = false then //if Load_GL_VERSION_3_0 = false then begin writeln(' ERROR: OpenGL 3.2 or higher needed. '); HALT; end; glViewport(0, 0, cWIDTH, cHEIGHT); //print out OpenGL vendor, version and shader version writeln( 'Vendor: ' + glGetString( GL_VENDOR ) ); writeln( 'OpenGL Version: ' + glGetString( GL_VERSION ) ); writeln( 'Shader Version: ' + glGetString( GL_SHADING_LANGUAGE_VERSION ) ); end; class procedure TDisplayManager.UpdateDisplay; begin SDL_GL_SwapWindow(FSDLWindow); end; class procedure TDisplayManager.CloseDisplay; begin SDL_GL_DeleteContext(FSDLGLContext); SDL_DestroyWindow(FSDLWindow); SDL_Quit; end; end. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
[fpc-pascal] OpenGL and SDL frustrations
I’ve wasted so much time on this I just need to stop and ask for help already. Over the last few years I’ve been picking away at OpenGL and only ever got the legacy 2.x API to work which has been fine for making 2D games but I wanted to at least learn the modern API and shaders. Here’s a snippet I cobbled together from a test program. It merely wants to draw a triangle. The actual OpenGL is from a tutorial and I don’t see how anything could be simpler than this. The only thing curious to me is why I can’t load the version of OpenGL I want from SDL. If I attempt to load 4.0 (with SDL_GL_SetAttribute) GL_VERSION returns null but if I load 3.3 it works and GL_VERSION returns 4.1 anyways (I’m a Mac from 2015). I removed the error handling code here but I don’t get any errors, just a black screen. Despite the tutorial I was following not using a shader they still got a white triangle (I added a shader also but it still didn’t work so I removed it to reduce complexity). The only thing I can think of is they were using GLEW and it did some init that SDL isn’t doing but I doubt it. This is barebones simple OpenGL here. Any ideas on what’s wrong with this? I don’t care about this example in particular I just want to draw ANYTHING using OpenGL 3.3 so I can move forward. = type TVec2 = record x, y: GLfloat; end; var verts: array[0..2] of TVec2; bufferID: GLuint; vao: GLuint; // run sdl window if SDL_Init(SDL_INIT_VIDEO) < 0 then Fatal('SDL could not initialize! '+SDL_GetError); // load function pointers if Load_GL_VERSION_3_3 = false then Fatal('OpenGL is not loaded'); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); // NOTE: 4.0 doesn't work, GL_VERSION return null SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); // create window window := SDL_CreateWindow('SDL Tutorial', SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN + SDL_WINDOW_OPENGL); context := SDL_GL_CreateContext(window); SDL_GL_MakeCurrent(window, context); SDL_GL_SetSwapInterval(1); writeln('Vendor: ', glGetString(GL_VENDOR)); writeln('OpenGL Version: ', glGetString(GL_VERSION)); writeln('GLSL Version: ', glGetString(GL_SHADING_LANGUAGE_VERSION)); // NOTE: despite SDL_GL_SetAttribute asking for 3.3 and 4.0 failing GL_VERSION still returns 4.1 // Vendor: Intel Inc. // OpenGL Version: 4.1 INTEL-10.25.13 // GLSL Version: 4.10 // setup glViewPort(0, 0, width, height); // simplest example possible // https://www.youtube.com/watch?v=Dyue3MzJDss verts[0].x := 0.0; verts[0].y := 1.0; verts[1].x := -1.0; verts[1].y := -1.0; verts[2].x := 1.0; verts[2].y := -1.0; // NOTE: glEnableVertexAttribArray returns an error if I don't bind a vao glGenVertexArrays(1, @vao); glBindVertexArray(vao); // gen array buffer and bind to verts glGenBuffers(1, @bufferID); glBindBuffer(GL_ARRAY_BUFFER, bufferID); glBufferData(GL_ARRAY_BUFFER, sizeof(verts), @verts, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(TVec2), nil); // draw loop glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); SDL_GL_SwapWindow(window); ... Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal