Jump to content

  • Log In with Google      Sign In   
  • Create Account


Cross-platform Extensions (porting from Linux -> Windows)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 Synival   Members   -  Reputation: 123

Like
0Likes
Like

Posted 11 August 2012 - 05:07 PM

I'm finally porting my game from Linux to Windows, and nothing from glext.h seems to be working. Under MinGW, I'm getting undefined references for just about everything:
[source lang="plain"]game/assets.c:178: error: ‘GL_VERTEX_SHADER’ undeclared (first use in this function)game/assets.c:178: error: (Each undeclared identifier is reported only oncegame/assets.c:178: error: for each function it appears in.)game/assets.c:182: error: ‘GL_FRAGMENT_SHADER’ undeclared (first use in this function)[/source]
I'm using the following #includes:
[source lang="plain"]#ifdef _WIN32 #include "../win/dirent.h"#else #include <dirent.h>#endif#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <GL/gl.h>#include <GL/glext.h>[/source]
...and here is the source code in question:
[source lang="plain"]... /* load shaders. */ else if (strcasecmp (ext, "vert") == 0) { if (shader_load (name, file, GL_VERTEX_SHADER)) return ""; } else if (strcasecmp (ext, "frag") == 0) { if (shader_load (name, file, GL_FRAGMENT_SHADER)) return ""; }[/source]
I've tried manually defining everything used from glext.h which, although it seems dangerous, does compile successfully, but doesn't link properly:
[source lang="plain"]game/maps.wo:maps.c:(.text+0x4711): undefined reference to `_glCreateProgram'game/maps.wo:maps.c:(.text+0x472c): undefined reference to `_glAttachShader'game/maps.wo:maps.c:(.text+0x476d): undefined reference to `_glAttachShader'game/maps.wo:maps.c:(.text+0x477b): undefined reference to `_glLinkProgram'game/maps.wo:maps.c:(.text+0x4789): undefined reference to `_glUseProgram'game/maps.wo:maps.c:(.text+0x479c): undefined reference to `_glGetUniformLocation'game/maps.wo:maps.c:(.text+0x47bc): undefined reference to `_glUniform1fv'game/maps.wo:maps.c:(.text+0x47cf): undefined reference to `_glGetUniformLocation'game/maps.wo:maps.c:(.text+0x4805): undefined reference to `_glUniform1fv'game/maps.wo:maps.c:(.text+0x4818): undefined reference to `_glGetUniformLocation'game/maps.wo:maps.c:(.text+0x4882): undefined reference to `_glUniform4fv'game/maps.wo:maps.c:(.text+0x4895): undefined reference to `_glGetUniformLocation'...[/source]
...and so on. All of the normal gl.h functions (glVertex3f, etc) link properly.
Everything in the game is written in C, not C++, but that shouldn't be a problem. From what I've read, it looks like I need to link to drivers provided by the video card, but if that's the case, I'd need to make a separate build for every graphics card? Please, please, please, tell me that's not the case :(
-- Synival

Sponsor:

#2 L. Spiro   Crossbones+   -  Reputation: 12240

Like
2Likes
Like

Posted 11 August 2012 - 05:30 PM

Windows® does not export functions beyond OpenGL 1.2 or so, and any functions in later versions need to be linked dynamically via wlgGetProcAddress().


L. Spiro
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#3 mhagain   Crossbones+   -  Reputation: 7436

Like
4Likes
Like

Posted 11 August 2012 - 05:36 PM

Extensions are nothing to do with the OS and everything to do with the driver and hardware, but you don't need a separate build for every gfx card.

Under Windows you generally don't have headers and libs for anything beyond GL1.1, so you need to fully use the extension loading mechanism to access higher level functionality. What this means is that you need to create a context then use wglGetProcAddress to access the entry points, as well as making sure that you've got a header containing all of the required defines and declarations.

This isn't particularly painful to do - e.g. look at one of the id Software GPL code releases for working examples - but it is rather tedious code grinding, so the general recommendation is to use something like GLEW for handling it all for you.

Edited by mhagain, 11 August 2012 - 05:39 PM.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#4 Synival   Members   -  Reputation: 123

Like
0Likes
Like

Posted 11 August 2012 - 05:54 PM

Ohhh, I think I get it. So I need to look up the function addresses individually for each extension call? I've found some examples of wglGetProcAddress to study... I'll try a few things, and report back if it works. Thanks!

Edited by Synival, 11 August 2012 - 05:55 PM.

-- Synival

#5 Synival   Members   -  Reputation: 123

Like
0Likes
Like

Posted 11 August 2012 - 07:51 PM

Hmm, frustrating. This should be working theoretically, but now I'm getting these linker errors:
[source lang="plain"]i586-mingw32msvc-gcc `/opt/SDL-1.2.13/bin/i586-mingw32msvc-sdl-config --cflags` debug.wo demo.wo game/assets.wo game/downloads.wo game/maps.wo game/math.wo game/messages.wo game/models.wo game/protocol.wo game/render.wo game/shaders.wo game/sprites.wo game/stats.wo game/telnet.wo game/tiles.wo main.wo ui/audio.wo ui/buttons.wo ui/canvas.wo ui/desktop.wo ui/fonts.wo ui/frames.wo ui/hgl.wo ui/logs.wo ui/network.wo ui/scrollbars.wo ui/text.wo ui/textures.wo ui/utils.wo ui/windows.wo -o ../harmonia.exe `/opt/SDL-1.2.13/bin/i586-mingw32msvc-sdl-config --libs` -lSDL_image -lSDL_net -lSDL_mixer -lopengl32ui/hgl.wo:hgl.c:(.text+0x19): undefined reference to `_wglGetProcAddress'ui/hgl.wo:hgl.c:(.text+0x59): undefined reference to `_wglGetProcAddress'ui/hgl.wo:hgl.c:(.text+0x99): undefined reference to `_wglGetProcAddress'ui/hgl.wo:hgl.c:(.text+0xd9): undefined reference to `_wglGetProcAddress'ui/hgl.wo:hgl.c:(.text+0x119): undefined reference to `_wglGetProcAddress'ui/hgl.wo:hgl.c:(.text+0x159): more undefined references to `_wglGetProcAddress' follow[/source]
I'm linking to opengl32 with the '-lopengl32' parameter. Could it be an issue with MinGW?

The code causing the error is a macro I set up for _WIN32:

[source lang="plain"]#ifdef _WIN32 #define hgl_bind(x, y, z)\ if ((x = (void *) wglGetProcAddress (z)) == NULL) {\ log_printf (LOG_ERROR, "Couldn't bind function '%s'.\n", z);\ global_hgl_errors++;\ }#else #define hgl_bind(x, y, z)\ x = y#endif[...] /* bind every function! */ hgl_bind (hglAttachShader, glAttachShader, "glAttachShader"); hgl_bind (hglBindFramebuffer, glBindFramebuffer, "glBindFramebuffer"); hgl_bind (hglBindRenderbuffer, glBindRenderbuffer, "glBindRenderbuffer"); [...][/source]
-- Synival

#6 Lazy Foo   Members   -  Reputation: 1103

Like
3Likes
Like

Posted 11 August 2012 - 07:58 PM

Just use GLEW. You will get every function available on your system and it's easy to check your available functionality.

Compare your code to this (from my GLEW tutorial)
[source lang="cpp"] //Initialize GLEW GLenum glewError = glewInit(); if( glewError != GLEW_OK ) { printf( "Error initializing GLEW! %s\n", glewGetErrorString( glewError ) ); return false; } //Make sure OpenGL 2.1 is supported if( !GLEW_VERSION_2_1 ) { printf( "OpenGL 2.1 not supported!\n" ); return false; }[/source]

Not only that it gives you some shortcuts. FBOs didn't get promoted to core until after 2.1, but I was still able to treat them as core in an OpenGL 2.1 context thanks to the syntactic sugar glew provides.

Edit: Also are you using what additional libraries besides OpenGL are you using? I know certain libraries like SOIL require it to be in the linker before OpenGL32.

Edited by Lazy Foo, 11 August 2012 - 08:01 PM.

Learn to make games with my SDL Tutorials.
Transition from OpenGL 2 to modern OpenGL using my OpenGL Tutorial.

#7 Synival   Members   -  Reputation: 123

Like
0Likes
Like

Posted 11 August 2012 - 08:14 PM

My first solution was to use GLEW, but glewInit() failed in my native Linux build for whatever reason. I played around with it a while, but had no luck, so I decided to stick with what I have. The code is already far enough along that I shouldn't have to rewrite it. The new code works fine using glXGetProcAddress(), but for whatever reason, it's not linking wglGetProcAddress().

As for other libraries, I'm using SDL, SDL_image, SDL_net, and SDL_mixer.
-- Synival

#8 Lazy Foo   Members   -  Reputation: 1103

Like
1Likes
Like

Posted 11 August 2012 - 08:25 PM

My first solution was to use GLEW, but glewInit() failed in my native Linux build for whatever reason. I played around with it a while, but had no luck, so I decided to stick with what I have. The code is already far enough along that I shouldn't have to rewrite it. The new code works fine using glXGetProcAddress(), but for whatever reason, it's not linking wglGetProcAddress().

As for other libraries, I'm using SDL, SDL_image, SDL_net, and SDL_mixer.


SDL actually has the ability to get the address of and OpenGL function if you want to use that, but I would recommend getting glew working.

Although I would recommend getting glew working because it will be a huge pain to get all the OpenGL functionality for a modern OpenGL program. What exactly was the error glew was giving you?
Learn to make games with my SDL Tutorials.
Transition from OpenGL 2 to modern OpenGL using my OpenGL Tutorial.

#9 Nairou   Members   -  Reputation: 418

Like
0Likes
Like

Posted 11 August 2012 - 10:39 PM

If you're using OpenGL 3.x, GLEW will fail unless you set it's "experimental" flag. Alternately, I recommend using flextGL instead of GLEW.

Edited by Nairou, 11 August 2012 - 10:40 PM.


#10 Lazy Foo   Members   -  Reputation: 1103

Like
0Likes
Like

Posted 11 August 2012 - 10:55 PM

If you're using OpenGL 3.x, GLEW will fail unless you set it's "experimental" flag. Alternately, I recommend using flextGL instead of GLEW.


That's strange, I managed to get GLEW to work with OpenGL 3.1 just fine as did the people testing my tutorial programs. I started the alpha test for the tutorial set back in January so I'm guessing this might have been an issue with older versions of GLEW.
Learn to make games with my SDL Tutorials.
Transition from OpenGL 2 to modern OpenGL using my OpenGL Tutorial.

#11 Nairou   Members   -  Reputation: 418

Like
0Likes
Like

Posted 11 August 2012 - 11:06 PM

That's strange, I managed to get GLEW to work with OpenGL 3.1 just fine as did the people testing my tutorial programs. I started the alpha test for the tutorial set back in January so I'm guessing this might have been an issue with older versions of GLEW.


To be more specific, GLEW fails during init while trying to get the list of available extensions, if you are using a OpenGL 3.x core profile, as it still uses the deprecated glGetString() function rather than glGetStringi().

The last time I used GLEW was a year ago, version 1.6.0, so it may have been fixed, but the GLEW changelog doesn't mention it.

#12 Synival   Members   -  Reputation: 123

Like
0Likes
Like

Posted 12 August 2012 - 02:38 AM

The error I was getting was a "Missing GL Version" error on glewInit(). Couldn't figure out what it meant, but I had enough of a headache as it was porting everything else to Windows, so I took the path of least resistance. The SDL_GL_GetProcAddress() solution wasn't all that bad, truthfully. I'll see how it goes in future builds on other machines.

Regardless, I'm really excited to have the first Windows build of my game! What blows my mind even more is that I somehow got a Windows executable built under a Linux environment. It runs under wine, so I can do all my testing from here Posted Image Some seriously crazy stuff, if you ask me. Anyway, if anyone's interested, they can check out the build here: http://www.harmonia-...rmonia_demo.zip

Edited by Synival, 12 August 2012 - 02:39 AM.

-- Synival

#13 Lazy Foo   Members   -  Reputation: 1103

Like
2Likes
Like

Posted 12 August 2012 - 03:46 AM

The error I was getting was a "Missing GL Version" error on glewInit().


Are you calling glewInit() after calling SDL_SetVideoMode()? There needs to be an active OpenGL context for GLEW to work.
Learn to make games with my SDL Tutorials.
Transition from OpenGL 2 to modern OpenGL using my OpenGL Tutorial.

#14 Synival   Members   -  Reputation: 123

Like
0Likes
Like

Posted 12 August 2012 - 03:45 PM

Are you calling glewInit() after calling SDL_SetVideoMode()? There needs to be an active OpenGL context for GLEW to work.


That could have been the issue, although I think I tried it. Probably not. I'll certainly look into using GLEW in the future or, when I have the time, convert what I already have into using it. Though this was an interesting exercise in low-level OpenGL programming, which I personally find fun. Still no clue why wglGetProcAddress wasn't linking. Then again, it's mind boggling that I was able to make a Windows build under Linux at all.
-- Synival

#15 Synival   Members   -  Reputation: 123

Like
0Likes
Like

Posted 19 August 2012 - 02:57 AM

Well, after lots of mucking around with OpenGL in cross-platform builds, I finally switched to GLEW and now everything is working wonderfully. Linking the functions manually felt better, but it's just too difficult to manage in Windows, Mac OSX, and Linux builds together.

Edit: Although using SDL_GetProcAddress() was compiling/linking properly and providing no run-time errors, the function pointers were causing heap corruptions in Windows. I suspect the prototype declarations are platform-specific, or at least really really picky.

Edited by Synival, 19 August 2012 - 05:34 AM.

-- Synival




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS