Reputation: 3535
I'm currently trying to create a custom OpenGL function loader so I can start designing my own custom game engine. The header containing all of the loader code is formatted as follows:
#ifndef SWOGLL_H_
#define SWOGLL_H_
#pragma once
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/glext.h>
#include <gl/wglext.h>
static PFNGLACTIVESHADERPROGRAMPROC glActiveShaderProgram;
static PFNGLACTIVETEXTUREPROC glActiveTexture;
// ...
static void* GetGLFunctionPointer(const char* functionName)
{
void* functionPointer = (void*)wglGetProcAddress(functionName);
if(
functionPointer == (void*)0x0 ||
functionPointer == (void*)0x1 ||
functionPointer == (void*)0x2 ||
functionPointer == (void*)0x3 ||
functionPointer == (void*)-0x1
)
{
HMODULE module = LoadLibraryA("opengl32.dll");
functionPointer = (void*)GetProcAddress(module, functionName);
}
return functionPointer;
}
static void GenerateGLFunctionPointers()
{
glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)GetGLFunctionPointer("glActiveShaderProgram");
glActiveTexture = (PFNGLACTIVETEXTUREPROC)GetGLFunctionPointer("glActiveTexture");
// ...
}
If I #include "SWOGLL.h"
in my main.cpp
file, the OpenGL functions work fine, assuming I've called GenerateGLFunctionPointers()
after creating an OpenGL context.
However, if I create a separate file and #include "SWOGLL.h"
, the OpenGL functions don't work at all, even if the OpenGL context has already been created.
What's the problem here?
Upvotes: 1
Views: 988
Reputation: 213318
You're declaring static
functions and variables in a header file. Unless you have an exceptionally good reason to do something so bizarre, don't do that.
static PFNGLACTIVESHADERPROGRAMPROC glActiveShaderProgram;
static void* GetGLFunctionPointer(const char* functionName)
This will create a different copy of glActiveShaderProgram
, GetGLFunctionPointer()
, and everything else declared static
in every C++ file that includes the header.
Remove static
, and do one of the following things:
Keep the declaration in the header, but move the definition to a C++ file.
Keep the declaration and definition in the header, but mark it inline
. This does not work with global variables.
The static
keyword, in this case, makes it so the functions and variables declared static
have "internal linkage", which means that you get a separate copy of them for every C++ file that defines them. This is different from declaring a member function static
, which has a completely unrelated effect. It is somewhat unfortunate that the keyword static
means different things in different places. C'est la vie.
Upvotes: 4