OpenGL Core Profile Tutorials lazarus / 70-OpenGL ---------------------------------------------------------------------- ChrisR · 2017-01-31 14:47 I created three sample projects that demonstrate using the Core Profile of OpenGL using Lazarus  https://github.com/neurolabusc/OpenGLCoreTutorials In order to achieve the Lazarus goal of "write once/compile anywhere", you need to either target OpenGL 2.1 (the last legacy version supported by MacOS) or the modern Core profile (which drops deprecated legacy functions). I hope others find this useful, and would be grateful for any suggestions to improve these tutorials. ---------------------------------------------------------------------- Handoko · 2017-01-31 15:17 Thank you for writing those tutorials. I'm sure use it. I only have the basic old OpenGL knowledge, wanting to learn the modern OpenGL unfortunately all I found on the web are written on C++. Bookmarked the link, and will visit it later. Do you know we have a contest for writing graphics programs? http://forum.lazarus.freepascal.org/index.php/topic,35313.0.html I'm now writing a simple game and will publish the source code with tutorial about it. I guess you may interested to join in the contest. ---------------------------------------------------------------------- Akira1364 · 2017-02-03 18:48 A note: I'm on 64-bit Windows 10, and your "glcorearb" header unit doesn't work for me. When I refactored all the examples and helper units to use dglOpenGL (as is my normal method for using OpenGL with Lazarus) everything worked fine. ---------------------------------------------------------------------- Graeme · 2017-02-04 00:20 Any new information on “modern OpenGL” is very much welcomed. So thanks for that, I’ll definitely take a look. I can add that I found a ton of excellent “modern OpenGL” tutorials on YouTube. A lot of them use LWJGL (Lightweight Java Game Library), but the actual OpenGL code all translates very easily to Object Pascal and SDL2+OpenGL. I’ve had no problems following along with some of those YouTube tutorials. ---------------------------------------------------------------------- marcov · 2017-02-07 14:21 Quote from: Graeme on February 04, 2017, 01:20:28 amAny new information on “modern OpenGL” is very much welcomed. So thanks for that, I’ll definitely take a look. Did you look at my unit test ? I mentioned in a SDL thread, so you might have skipped it. http://forum.lazarus- ide.org/index.php/topic,30556.msg194484.html#msg194484 It was the development app for our widget that shows some 2D Canvas (texture, circle,lines etc) in a fairly modern style, and upgrade for an older codebase that Ales Katona made for us in the 2007-2008 timeframe. Specially the fonts still need work, but the codebase has been moved into production last fall. ---------------------------------------------------------------------- Graeme · 2017-02-07 15:33 Quote from: marcov on February 07, 2017, 03:21:26 pmDid you look at my unit test ? I mentioned in a SDL thread, so you might have skipped it. http://forum.lazarus- ide.org/index.php/topic,30556.msg194484.html#msg194484 Thanks Marco, I'll definitely take a look at that. ---------------------------------------------------------------------- jacmoe · 2017-02-12 22:59 Really nice tutorial! Unfortunately, since I am using Mesa and non proprietary Nouveau nVidia graphics driver, I can't convince OpenGL that my card is up for profile 3.3. In C, I use GLEW to make that happen. Is there a GLEW for Pascal? ---------------------------------------------------------------------- Akira1364 · 2017-02-12 23:18 I'm not sure it has anything to do with your drivers. FPC is just somewhat shaky when it comes to the way the method pointers are being initialized in the "glcorearb" unit he included. (By which I mean declaring the methods as variables and then assigning directly to them, as opposed to declaring them as types and then assigning to variables of those types, which seems to be much more stable.) Try it with dglOpenGL. https://github.com/SaschaWillems/dglOpenGL ---------------------------------------------------------------------- jacmoe · 2017-02-12 23:37 Thanks! I'll give it a try. If I am not lucky with that, I will probably have to bite and get my hands dirty with creating a Pascal interface to GLEW. ---------------------------------------------------------------------- Akira1364 · 2017-02-12 23:49 All you need to do is call Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i InitOpenGL;ReadExtensions; in the places he was previously calling Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Load_GL_version_3_3_CORE; Also I would recommend moving all the stuff he does in FormCreate to FormShow, as doing it in FormCreate can interfere with the creation of TOpenGLControl's context. ---------------------------------------------------------------------- jacmoe · 2017-02-13 05:27 I did that, but the program died by a segfault, until I left in a call to Load_GL_version_3_2_CORE: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure  InitGL(var GLcontrol: TOpenGLControl);begin  GLcontrol.MakeCurrent();  InitOpenGL;  ReadExtensions;  //ReadImplementationProperties;  if not Load_GL_version_3_2_CORE() then begin     GLcontrol.ReleaseContext;     {$IFNDEF Windows} writeln('Unable to load OpenGL');{$ENDIF}     showmessage('Unable to load OpenGL 3.2');     halt();  end;  GLForm1.caption := glGetString(GL_VENDOR)+'; OpenGL= '+glGetString(GL_VERSION)+'; Shader='+glGetString(GL_SHADING_LANGUAGE_VERSION);  gShader.shaderProgram :=  initVertFrag(kVert,  kFrag);  LoadBufferData;  GLcontrol.ReleaseContext;  if GLErrorStr <> '' then begin     showmessage(GLErrorStr);     GLErrorStr := '';  end;end;  There is probably some stuff that gets done in that function that I need to do - but now I get OpenGL 4.3 !  If I try something higher than 3_2, it will fail to find it. Ironically, because what I am really getting is 4.3 both for core and for the shader. This is the basic project, btw. ---------------------------------------------------------------------- Akira1364 · 2017-02-13 05:44 You shouldn't really be using both the glcorearb unit and dglOpenGL at the same time, as they contain identically named functions (for obvious reasons) and will conflict with each other. That is probably what caused the segfault. Did you try it without glcorearb in the uses section? Either way, good to see you've got it working. ---------------------------------------------------------------------- jacmoe · 2017-02-13 05:55 If I remove glcorearb, still a sigsegv. Yes, I know it's strange that I have to call that function, but it probably has to do with some shader related stuff that I need to do that somehow gets triggered in the function. I will compare to see if I can't figure out what else I need to call, in order to get rid of that unnecessary function call.  The next step is (obviously) to fish out that one function and put it into the main form's unit so that I can get rid of the glcorearb unit. And then comment out some lines in it .. And/or read my own C source code - whatever. But thanks for the pointers! ---------------------------------------------------------------------- Graeme · 2017-02-13 09:49 Quote from: jacmoe on February 13, 2017, 12:37:17 amThanks! I'll give it a try. If I am not lucky with that, I will probably have to bite and get my hands dirty with creating a Pascal interface to GLEW. I'm using the GL and GLext units included with FPC as standard. They are working perfectly for me, and I'm programming and targeting OpenGL 4+ only. Just curious... Why would I need other OpenGL header translations? ie: dlgOpenGL? ---------------------------------------------------------------------- marcov · 2017-02-13 10:33 Quote from: Graeme on February 13, 2017, 10:49:51 am Just curious... Why would I need other OpenGL header translations? ie: dlgOpenGL? They work in Delphi (the FPC opengl headers have macro support) and are generally more complete on windows and more regularly updated. IMHO Pascal opengl is too small to fragment. ---------------------------------------------------------------------- Graeme · 2017-02-13 11:08 Quote from: marcov on February 13, 2017, 11:33:30 amThey work in Delphi Ah, okay... Not much of a concern for me then. Quote... and more regularly updated. Seeing as they should only be C header translations, backporting anything to the FPC files should be pretty straight forward. QuoteIMHO Pascal opengl is too small to fragment. It's just header translations right? In theory they should be pretty similar everywhere,  or even [ideally] auto-generated. As for fragmentation, I can't really see that happening in this case. I've ported tons of C, C+SDL2 and Java OpenGL examples to Free Pascal... all that is required in most cases are minor tweaks to the glXXX API calls, where the parameter types are slightly different (due to programming language). But even for somebody totally new to OpenGL (as myself) it wasn't very hard to figure out how to adjust the code. ---------------------------------------------------------------------- jacmoe · 2017-02-13 11:47 Quote from: Graeme on February 13, 2017, 10:49:51 amI'm using the GL and GLext units included with FPC as standard. They are working perfectly for me, and I'm programming and targeting OpenGL 4+ only. Just curious... Why would I need other OpenGL header translations? ie: dlgOpenGL? I don't need anything other than a couple helper functions to convince my system that Mesa and Nouveau can deliver OpenGL 4.3. For that, I use GLEW in C. ---------------------------------------------------------------------- Akira1364 · 2017-02-13 16:35 The main reason I prefer dglOpenGL is because it only takes two function calls to guarantee that all supported extensions will be loaded, regardless of the computer the software is being run on. Whereas the FPC units have no "load everything" functionality, and you need to call functions for each specific version/extension set/e.t.c. (And as Marco said, they're not 100% complete.) Also, the FPC units have the platform-specific methods spread across different files, whereas dglOpenGL includes all of them and uses IFDEFS to choose the relevant ones. ---------------------------------------------------------------------- ChrisR · 2017-04-02 13:01 Jacmoe Can you help me troubleshoot this? The code works on my MacOS, Windows and Linux machines. It would help my greatly if you could tell me which function(s) in the Load_GL_VERSION_3_3_CORE call cause your program to crash. Simply edit glcorearb.pas and initially comment out HALF of the functions  glBindFragDataLocationIndexed  ...  glVertexAttribP4uiv := getProc('glVertexAttribP4uiv', OK); If that compiles, one of the functions in the commented half is problematic, if it fails, try commenting out another quarter. Through a process of elimination we should see which are not supported universally. I have tried this on Nvidia, Intel and AMD cards, so I am puzzled by your problems. //28 procedures for GL_VERSION_3_3 function Load_GL_VERSION_3_3_CORE : boolean; Quote from: jacmoe on February 13, 2017, 06:27:10 amI did that, but the program died by a segfault, until I left in a call to Load_GL_version_3_2_CORE: ---------------------------------------------------------------------- ChrisR · 2017-04-02 13:08 Akira1364,   Yes, your method works by using the dglOpenGL library. The issue with this is that it is hard to compile Core code, as all the non-core functions and constants are available. You can easily write an application that compiles nicely on Linux and Windows (which support the compatibility profile) but fail on MacOS. I have just updated my PlyView to show how a couple compiler switches at the top of a program allow you to select between glcorearb (modern OpenGL only), gl/glext (does not support modern OpenGL on MacOS) or dglOpenGL   https://github.com/neurolabusc/plyview I think each of these libraries is useful for developers, and as this project shows, you can switch between them seamlessly. Quote from: Akira1364 on February 13, 2017, 12:49:18 amAll you need to do is call Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i InitOpenGL;ReadExtensions; in the places he was previously calling Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Load_GL_version_3_3_CORE; ---------------------------------------------------------------------- ChrisR · 2017-04-02 13:17 I agree, my updated project  https://github.com/neurolabusc/plyview shows how you can choose between GL/EXT, dglOpenGL, and glcorearb at the same time. You only use one at a time, but you can choose which one depending on what you want to achieve. The pros and cons of each seem to be: 1.) GL/GLEXT:  Pro: Comes with FPC as default library.  Con: Unable to support modern OpenGL on MacOS 2.) dglOpenGL:  Pro: can run modern OpenGL on all platforms (Windows, MacOS, Linux)  Con: some have criticized X dependency http://mantis.freepascal.org/view.php?id=29051 3.) glcorearb  Pro: hides legacy OpenGL functions and constants, ensuring that you do not accidentally include them. This makes it easier to write software that works on all platforms (Windows, MacOS, Linux)  Pro: can run modern OpenGL on all platforms (Windows, MacOS, Linux)  Con: Hides legacy functions and constants, so Windows and Linux users can not mix and match old functions (e.g. immediate mode) with modern code. Note that due to the MacOS Core specification, Mac users must choose EITHER legacy or modern versions, they can never mix and match. Quote from: Akira1364 on February 13, 2017, 06:44:13 amYou shouldn't really be using both the glcorearb unit and dglOpenGL at the same time, as they contain identically named functions (for obvious reasons) and will conflict with each other. That is probably what caused the segfault. Did you try it without glcorearb in the uses section? Either way, good to see you've got it working. ---------------------------------------------------------------------- ChrisR · 2017-04-02 13:25 Quote from: Graeme on February 13, 2017, 10:49:51 amI'm using the GL and GLext units included with FPC as standard. They are working perfectly for me, and I'm programming and targeting OpenGL 4+ only. Just curious... Why would I need other OpenGL header translations? ie: dlgOpenGL? If you only use Windows or Linux, and never plan to support MacOS, there is no need to use any other translation. However, for me the appeal of Lazarus is the "Write Once, Compile Anywhere" nature, and these other libraries support modern OpenGL on MacOS. One other point, in my experience I can get much better performance using only the modern Core features: while the legacy features of immediate mode are supported, they tend to bog down the rendering. So having a library that helps you determine which features are not available in Modern OpenGL is useful for writing optimized code. 1.) GL/GLEXT:  Pro: Comes with FPC as default library.  Con: Unable to support modern OpenGL on MacOS 2.) dglOpenGL:  Pro: can run modern OpenGL on all platforms (Windows, MacOS, Linux)  Con: some have criticized X dependency http://mantis.freepascal.org/view.php?id=29051 3.) glcorearb  Pro: hides legacy OpenGL functions and constants, ensuring that you do not accidentally include them. This makes it easier to write software that works on all platforms (Windows, MacOS, Linux)  Pro: can run modern OpenGL on all platforms (Windows, MacOS, Linux)  Con: Hides legacy functions and constants, so Windows and Linux users can not mix and match old functions (e.g. immediate mode) with modern code. Note that due to the MacOS Core specification, Mac users must choose EITHER legacy or modern versions, they can never mix and match. ---------------------------------------------------------------------- ChrisR · 2017-04-02 13:30 Quote from: jacmoe on February 13, 2017, 06:55:04 amIf I remove glcorearb, still a sigsegv. The reason you get the error is that dglOpenGL returns strings differently from GL/EXT and glcorearb. If you look at my updates to   https://github.com/neurolabusc/plyview you will see that by choosing a {$DEFINE *} you can compile to dglOpenGL, GL/EXT, glcorearb (but only one at a time). If you look at the code's "{$IFDEF DGL}" you will see that you can need to make a couple minor adjustments for dglOpenGL. ---------------------------------------------------------------------- Thaddy · 2017-04-02 16:50 Quote from: ChrisR on April 02, 2017, 03:17:09 pm2.) dglOpenGL:  Pro: can run modern OpenGL on all platforms (Windows, MacOS, Linux)  Con: some have criticized X dependency http://mantis.freepascal.org/view.php?id=29051 That's a valid criticism: OpenGL is independent of X. The maintainers should correct that. The changes are minor: introduce an opaque instead of a dependency on an X specific structure. This is - btw - how to conform to the KHRONOS reference code for GL. It is just a small mistake in a header translation. With big consequences: it ties OpenGL to X.