As discussed in my last post I am working my way through some OpenGL 3+ tutorials. In the process I have had to use GLEW. GLEW is a wrapper for OpenGL functions in the newer versions of OpenGL. It means you don’t need to call glGetProcAddress a ton of times before you can actually draw anything. It is very handy but I find it does not play nice when you are trying to link to it. To begin with the dll does not strip anything from the symbol name. What that means is glewInit is called _glewInit@0 in the dll. This isn’t much of an issue in fact its quite nice to know that the @0 means that I don’t need to pass any params. Its only mildly annoying when you have got used to dlls not having it. The bigger issue is finding the function pointers.
glBindVertexArray is a function found in OpenGL 3+ it therefore has to be loaded through GLEW. The dll informs me that it is called __glewBindVertexArray. I can understand the change between gl and glew as its to prevent any collisions. The extra underscore threw me to begin with but then it is probably because this is a pointer to my function and it is an extra warning to treat it special. My main problem with it is if I am using the .lib file to link with then I can’t find the sysmbol __glewBindVertexArray. Instead the symbol happens to be __imp____glewBindVertexArray. I assume the __imp__ part is something to do with this being a variable that is filled out when GLEW inits but I will investigate this further. All in all it means I will have to create a macro if I want to be able to link my code with ALINK and MS LINK.
Whilst looking into this issue I also played about with changing to using static lib files. They would resolve my issues but at the same time I would never be able to link with ALINK since the static libs use parts of ALINK that were never finished. A big fancy macro looks like the best solution.
After successfully writing solutions for 1-10 of NeHe’s OpenGL tutorials I decided it was time to venture into newer technology. OpenGL 3+ is a bit harder to use compared to the older versions. The main issue is creating a render context. This was already a hard task in assembler and 3+ does not make the task any easier. First you create a context just like in NeHe’s tutorial but then you need to get function pointers for all of the OpenGL functions you plan on calling. After achieving this you destroy your context and remake it using the functions you have just found. It is a bit of tedious task I think I’m confident I could achieve it but I have decided I don’t want to focus on that for my latest endeavor.
What I plan to do instead is use GLFW and GLEW to help with OpenGL. GLFW is an OpenGL library that helps with creating windows and such. GLEW is an OpenGL extensions library that gets all of the function pointers I mentioned earlier and gets them ready for use. Again I plan to follow someone else’s tutorial as I do not have much knowledge of OpenGL at this point. The tutorials I plan to rewrite are from http://www.opengl-tutorial.org/. Their tutorials are using out of date versions of GLFW and GLEW and I plan to modify the solutions to use the latest versions.
At the same time I have decided that I will use Microsofts Incremental Linker (link.exe) instead of ALINK. My only reason for doing this is to try a different way of linking my executables. One of the changes with using the link.exe instead of alink is that NASM has to compile win32 obj files instead of borland compatible obj files. This change means that you can’t use the import directive to specify which dll you are linking with. When not using the import directive lib files are passed into the linker at link time. In the grand scheme of things it means you don’t have to specify anything in the import part. One disadvantage of this is that you have to use the correct names as specified in the lib file and these are not always the same as the names specified in documentation. For example from kernel32.dll:
_ExitProcess@4 instead of ExitProcess
The @4 informs you that the function is a std call and would like 4 bytes of information on the stack and you should clean up the stack after the call. ExitProcess( DWORD var ). If there is no @X then it is probably a cdecl call and you do not need to clean up the stack. It just so happens that the WinAPI and GLEW uses std calls and GLFW uses cdecl calls. This is important and there will probably be many bugs in my programs in the future due to me forgetting this.
All code for this can be found on my github.
The other day I had an idea to learn x86 assembler. Since I am never a fan of easy projects I decided for my first program I would try to rewrite the legacy OpenGL tutorials by NeHe. It is important to remember that these tutorials are based on very old versions of OpenGL and should not really be followed unless developing for ancient architecture. After I have rewritten NeHe’s tutorials at least up to 5 I plan to then try to change over to OpenGL 3.2 and higher. I will still stay in NASM assembler so I will have to have a few tricks up my sleeve as I can find no assembler references for newer versions of OpenGL. The new versions of OpenGL require some really extravagant techniques in order to display a simple window and most people now use a library to do all of this back end. I may have a look at the back end and see if it can be simplified in NASM but I think it will be quite likely that I will just use a library as well.
There is actually solutions to NeHe’s tutorials in assembler but it is FASM and it was made in 2000 so there is a possibility for improvements. These tutorials will hopefully give me a better understanding of x86 and how OpenGL operates. I was going to use the FASM code whenever I was unsure on how to proceed but found that it had few comments making it hard to read and follow. My attempt will hopefully have meaningful comments and will not use @@1 as a label for any loop! Another tool at my disposal is reading the assembler generated by the original c++ code.
One issue I encountered early on was alignment can cause many problems. For a long time I had a MessageBox that would display with the words in italics and rotated. It took a very long time to realise this was an alignment issue in the RAM due to me thinking that this bool I was using only required at max 1 bit so I placed it in a byte. After changing the bool to waste a dword all the MessageBox issues disappeared.
Another issue that I keep forgetting is whether something is a pointer or needs to be dereferenced. Whilst working through tutorial 2 I encountered many issues related with my box and triangle not being able to be drawn. I later realised the problem with this was not dereferencing a pointer!
I tried to use all open source programs whilst developing the tutorials some of them are very out of date nowadays such as ALINK. My reasoning for continuing to use ALINK was mainly due to being able to run it without installing anything. I would normally have used microsofts link.exe but I would need visual studio or the windows SDK.
All code can be found on github.