我喜歡編程作爲一種愛好,因此我通常有很多樂趣會變得非常低。函數當輸入函數時,存儲在全局變量中的指針被設置爲0,並且在退出函數時返回到之前的狀態
在過去的幾天裏,我學習了Windows API,如何設置窗口,打開窗口並管理消息隊列。
渲染我決定使用OpenGL,並開始學習它。如果不使用像GLEW這樣的庫,它會自動加載所有必須手動完成的功能。
一切都很順利。我設法正確加載所有的函數指針,並將它們存儲在全局變量被任何人訪問,包括這個.h文件中:
#pragma once
#include "glCoreARB.h"
#include "wglExt.h"
#define internal static
extern "C"
{
//FUNCTION POINTERS
// Debug/Init Functions
static PFNGLGETERRORPROC glGetError;
static PFNGLGETINTEGERVPROC glGetIntegerv;
static PFNGLGETSTRINGIPROC glGetStringi;
static PFNGLGETSTRINGPROC glGetString;
... AND MANY MORE (Not gonna write all of them down, you get it)
//LOADING FUNCTIONS
internal void *GetAnyGLFuncAddress(const char *name)
{
void *p = (void *)wglGetProcAddress(name);
if ((p == 0) || (p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) || (p == (void*)-1))
{
HMODULE module = LoadLibraryA("opengl32.dll");
p = (void *)GetProcAddress(module, name);
}
return p;
}
internal void LoadGLFunc(HDC DeviceContext)
{
glGetIntegerv = (PFNGLGETINTEGERVPROC)GetAnyGLFuncAddress("glGetIntegerv");
glGetStringi = (PFNGLGETSTRINGIPROC)GetAnyGLFuncAddress("glGetStringi");
glGetString = (PFNGLGETSTRINGPROC)GetAnyGLFuncAddress("glGetString");
glGetError = (PFNGLGETERRORPROC)GetAnyGLFuncAddress("glGetError");
GLint Version = getGLVersion();
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)GetAnyGLFuncAddress("wglGetExtensionsStringARB");
const char *extensions = wglGetExtensionsStringARB(DeviceContext);
//Once I got the extensions I Loaded all of those function pointers
wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)GetAnyGLFuncAddress("wglGetPixelFormatAttribivARB");
... And so on
//Then based on the available OpenGL Version
if (Version >= 33)
{
glGetShaderiv = (PFNGLGETSHADERIVPROC)GetAnyGLFuncAddress("glGetShaderiv");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)GetAnyGLFuncAddress("glGetShaderInfoLog");
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)GetAnyGLFuncAddress("glGetProgramiv");
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)GetAnyGLFuncAddress("glGetProgramInfoLog");
... And many more...
所有這些函數指針都是我的Windows平臺代碼中通過函數加載, ScreenInfo結構包含DeviceContext和,至此一切都事先檢索
internal VOID Win32_SetupOpenGLRenderingContext(ScreenInfo *Screen)
{
PIXELFORMATDESCRIPTOR PixelFormat = {};
PixelFormat.nSize = sizeof(PIXELFORMATDESCRIPTOR);
PixelFormat.nVersion = 1;
PixelFormat.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
PixelFormat.iPixelType = PFD_TYPE_RGBA;
PixelFormat.cColorBits = 32; //Colordepth of the framebuffer
PixelFormat.cDepthBits = 24; //Number of bits for the depthbuffer
PixelFormat.cStencilBits = 8; //Number of bits for the stencilbuffer
Screen->DeviceContext = GetDC(Screen->WindowHandle);
s32 PixelFormatValue = ChoosePixelFormat(Screen->DeviceContext, &PixelFormat);
SetPixelFormat(Screen->DeviceContext, PixelFormatValue, &PixelFormat);
Screen->RenderingContext = wglCreateContext(Screen->DeviceContext);
wglMakeCurrent(Screen->DeviceContext, Screen->RenderingContext);
LoadGLFunc(Screen->DeviceContext);
}
現在WindowHandle 完美妝容的工作,所有的函數指針被正確加載,我可以打電話給所有的Windows裏面的GL功能平臺代碼。
但平臺的代碼,很明顯,調用應用程序的主循環裏它的消息循環:
while(Running)
{
MSG Msg;
while (PeekMessageA(&Msg, Screen.WindowHandle, 0, 0, PM_REMOVE))
{
Win32_ProcessKeyboard(&Keyboard, Msg);
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
if (Keyboard.isQuitting)
{
Running = FALSE;
}
}
Loop(&Screen); // THIS FUNCTION HERE!
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
if (SwapBuffers(Screen.DeviceContext) == FALSE)
{
DWORD Error = GetLastError();
LogError("In swapping buffers error: ", Error);
}
}
RIGHT進入循環功能一切正常了。這裏的循環功能代碼,這是在另一個文件:
extern "C" void GameLoop(ScreenInfo *Screen)
{
RenderTriangle(Screen);
return;
}
而且RenderTriangle電話:
internal void RenderTriangle(ScreenInfo *Screen)
{
GLuint shaderProgram;
GLuint VAO = 0;
if (Screen->wasTriangleInit == FALSE)
{
glViewport(0, 0, Screen->Width, Screen->Height);
glBindVertexArray(VAO);
GLfloat vertices[] =
{
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
THERE IS MORE TO THIS FUNCTION, BUT THE PROBLEM HAPPENS WAY BEFORE, SO I'M PRETTY SURE IT'S IRRELEVANT.
一旦我進入從平臺代碼迴路功能,ALL只有到了指針用在RenderTriangle CALL GET設置爲0x0
我試圖欺騙應用程序,通過添加如果(0){}上在任一切的頂框GL功能derTriangle調用,以避免崩潰,就像這樣:
internal void RenderTriangle(ScreenInfo *Screen)
{
GLuint shaderProgram;
GLuint VAO = 0;
if(0)
{
if (Screen->wasTriangleInit == FALSE)
{
glViewport(0, 0, Screen->Width, Screen->Height);
glBindVertexArray(VAO);
GLfloat vertices[] =
{
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
這樣,進入此功能時,所有的指針仍然可以設置爲0x0,但現在我站出來,重新進入Windows平臺的文件,所有函數指針被重新設置爲適當的值。
我真的不知道該做什麼或發生了什麼。任何幫助?
這是你想在你的信息清楚一件好事。但這只是太多的代碼。我建議你寫一個[小程序,重現你正在嘗試修復的錯誤](http://stackoverflow.com/help/mcve)。 – giusti
我認爲先回答的人說得對。我需要將所有函數指針定義爲__declspec(selectany)...但我不確定它會怎樣... – Lory