gpt4 book ai didi

c - glUseProgram 是否有任何原因可能导致我的程序崩溃? (C Win32)

转载 作者:行者123 更新时间:2023-11-30 20:41:53 25 4
gpt4 key购买 nike

我正在用 C 语言学习 OpenGL 和 Win32,我刚刚开始想要实现着色器。我这样做更多是作为一种学习体验而不是一个项目,所以我决定不使用典型的扩展管理器库,如 glew 或其他东西。这是我的扩展抓取器头文件:

glExtensions.h:

#include <windows.h>

#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GL_ARRAY_BUFFER 0x8892
#define GL_STATIC_DRAW 0x88E4
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_COMPILE_STATUS 0x8B81
#define GL_LINK_STATUS 0x8B82
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_TEXTURE0 0x84C0
#define GL_BGRA 0x80E1
#define GL_ELEMENT_ARRAY_BUFFER 0x8893

PROC glCreateProgram;
PROC glCreateShader;
PROC glShaderSource;
PROC glCompileShader;
PROC glAttachShader;
PROC glLinkProgram;
PROC glUseProgram;
PROC glGetShaderInfoLog;
PROC glDeleteShader;
PROC glDetachShader;
PROC glIsProgram;
PROC glGenBuffers;
PROC glBindBuffer;
PROC glBufferData;
PROC glEnableVertexAttribArray;
PROC glVertexAttribPointer;
PROC glGenVertexArrays;
PROC glBindVertexArray;

void GLEInit(int);

这是 c 文件,glExtions.c

#include "glExtensions.h"
#include <windows.h>
#include <gl/gl.h>
#include "consoleUtil.h"

extern PROC glCreateProgram;
extern PROC glCreateShader;
extern PROC glShaderSource;
extern PROC glCompileShader;
extern PROC glAttachShader;
extern PROC glLinkProgram;
extern PROC glUseProgram;
extern PROC glGetShaderInfoLog;
extern PROC glDeleteShader;
extern PROC glDetachShader;
extern PROC glIsProgram;
extern PROC glGenBuffers;
extern PROC glBindBuffer;
extern PROC glBufferData;
extern PROC glEnableVertexAttribArray;
extern PROC glVertexAttribPointer;
extern PROC glGenVertexArrays;
extern PROC glBindVertexArray;

PROC getProc(int hOut, const char* name) {
PROC p = wglGetProcAddress(name);
if(p == 0 ||
(p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) ||
(p == (void*)-1) )
{
HMODULE module = LoadLibraryA("opengl32.dll");
p = GetProcAddress(module, name);
}

return p;
}

void GLEInit(int hOut) {
glCreateProgram = getProc(hOut, "glCreateProgram");
glCreateShader = getProc(hOut, "glCreateShader");
glShaderSource = getProc(hOut, "glShaderSource");
glCompileShader = getProc(hOut, "glCompileShader");
glAttachShader = getProc(hOut, "glAttachShader");
glLinkProgram = getProc(hOut, "glLinkProgram");
glUseProgram = getProc(hOut, "glUseProgram");
glGetShaderInfoLog = getProc(hOut, "glGetShaderInfoLog");
glDeleteShader = getProc(hOut, "glDeleteShader");
glDetachShader = getProc(hOut, "glDetachShader");
glIsProgram = getProc(hOut, "glIsProgram");
glGenBuffers = getProc(hOut, "glGenBuffers");
glBindBuffer = getProc(hOut, "glBindBuffer");
glBufferData = getProc(hOut, "glBufferData");
glEnableVertexAttribArray = getProc(hOut, "glEnableVertexAttribArray");
glVertexAttribPointer = getProc(hOut, "glVertexAttribPointer");
glGenVertexArrays = getProc(hOut, "glGenVertexArrays");
glBindVertexArray = getProc(hOut, "glBindVertexArray");
}

GLEInit 在创建窗口后立即运行,然后运行此代码

int createBasicProgram(int hOut) {
//vertex shader bullcrap
FILE* basicVSFile = getFile("shaders/basic.vs");
FILEDATA* vsfd = getFileData(hOut, basicVSFile);
close(basicVSFile);

int vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, vsfd->numLines, vsfd->lines, vsfd->lengths);
glCompileShader(vs);

int actualLength = 0;
glGetShaderInfoLog(vs, ERROR_BUFFER_SIZE, &actualLength, errorBuffer);
if (actualLength > 0) {
print(hOut, "deleting vertex shader\n");
glDeleteShader(vs);
print(hOut, errorBuffer);
return -1;
}
freeFileData(vsfd);


//fragment shader bullcrap
FILE* basicFSFile = getFile("shaders/basic.fs");
FILEDATA* fsfd = getFileData(hOut, basicFSFile);
int fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, fsfd->numLines, fsfd->lines, fsfd->lengths);
glCompileShader(fs);

glGetShaderInfoLog(fs, ERROR_BUFFER_SIZE, &actualLength, errorBuffer);
if (actualLength > 0) {
print(hOut, "deleting fragment shader\n");
glDeleteShader(fs);
print(hOut, errorBuffer);
return -1;
}
freeFileData(fsfd);

int progId = glCreateProgram();
glAttachShader(progId, vs);
glAttachShader(progId, fs);
glLinkProgram(progId);
glGetShaderInfoLog(progId, ERROR_BUFFER_SIZE, &actualLength, errorBuffer);
if (actualLength > 0) {
print(hOut, errorBuffer);
}

glDetachShader(progId, vs);
glDetachShader(progId, fs);
glDeleteShader(vs);
glDeleteShader(fs);

return progId;
}

void init(hOut) {
bp = createBasicProgram(hOut);

glGenVertexArrays(1, &vaoId);
glBindVertexArray(vaoId);
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
}

这段代码不会导致错误,但是当我添加简单的语句时:

glUseProgram(bp);

进入显示函数,该函数每帧都会被调用,程序运行一秒钟,控制台和程序窗口打开并呈黑色大约 3 秒,然后崩溃,没有构建错误或输出错误可跟踪。这个 glUseProgram 有什么原因会导致我的程序崩溃吗?

堆栈转储显示:“异常:STATUS_ACCESS_VIOLATION at rip=001004016E6”,带有一堆内存位置和我不明白的东西。

最佳答案

我又花了 7 个小时在这个项目上,我终于弄清楚了。我所说的“它”是指我的旧代码有一些问题。前两个问题是glExtensions.c和glExtensions.h,最初我所做的只是调用使用getProc来获取函数指针并将其放入PROC宏中,这根本不是它所需要的。 PROC 不使用正确的调用约定或指定正确的参数,而是需要包含 glext.h,它由 khronos 维护,可以在此处找到:https://www.khronos.org/registry/OpenGL/api/GL/glext.h 。关于这些函数的作用的描述也可以在这里找到:https://www.khronos.org/opengl/wiki/Load_OpenGL_Functions 。需要更改的另一件事是在创建程序之前调用 glUseProgram。程序创建代码是正确的,但是我在 WM_PAINT 和 WM_SIZE 上调用显示,并且两者都被放入消息队列并在调用 GLEInit 之前进行处理。相反,如果 PeekMessage 找不到任何消息,则应在消息循环中调用 display。

这是自上次以来更改的相关代码:

glExtensions.h:

#include <windows.h>
#include "glext.h"
#include "wglext.h"

PFNGLCREATEPROGRAMPROC glCreateProgram;
PFNGLCREATESHADERPROC glCreateShader;
PFNGLSHADERSOURCEPROC glShaderSource;
PFNGLCOMPILESHADERPROC glCompileShader;
PFNGLATTACHSHADERPROC glAttachShader;
PFNGLLINKPROGRAMPROC glLinkProgram;
PFNGLUSEPROGRAMPROC glUseProgram;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
PFNGLDELETESHADERPROC glDeleteShader;
PFNGLDETACHSHADERPROC glDetachShader;
PFNGLISPROGRAMPROC glIsProgram;
PFNGLGENBUFFERSPROC glGenBuffers;
PFNGLBINDBUFFERPROC glBindBuffer;
PFNGLBUFFERDATAPROC glBufferData;
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
PFNGLGETINTEGERI_VPROC glGetIntegeri_v;
PFNGLGETSTRINGIPROC glGetStringi;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;

void GLEInit(HANDLE);

void checkGLError(HANDLE, char*);

glExtensions.c:

#include "glExtensions.h"

#include <windows.h>
#include <gl/gl.h>
#include "consoleUtil.h"

void* getProc(HANDLE hOut, const char* name) {
print(hOut, "loading %s\n", name);
void* p = wglGetProcAddress(name);
if (p == NULL) {
int e = GetLastError();
print(hOut, "error loading %s: %i\n", name, e);
return NULL;
}
if(p == 0 ||
(p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) ||
(p == (void*)-1) )
{
HMODULE module = LoadLibraryA("opengl32.dll");
if (module == NULL) {
int e = GetLastError();
print(hOut, "error loading library \"opengl32.dll\" for function pointer %s: %i\n", name, e);
return NULL;
}
p = GetProcAddress(module, name);
if (p == NULL) {
int e = GetLastError();
print(hOut, "error loading %s with getProcAddress: %i\n", name, e);
return NULL;
}
}

print(hOut, "success loading\n");
return p;
}

void checkGLError(HANDLE hOut, char* desc) {
GLenum e = glGetError();
if (e > 0) {
print(hOut, "Error %i: %s\n", e, desc);
return;
}
print(hOut, "%s completed with no errors\n", desc);
}

void GLEInit(HANDLE hOut) {
glCreateProgram = (PFNGLCREATEPROGRAMPROC)getProc(hOut, "glCreateProgram");
glCreateShader = (PFNGLCREATESHADERPROC)getProc(hOut, "glCreateShader");
glShaderSource = (PFNGLSHADERSOURCEPROC)getProc(hOut, "glShaderSource");
glCompileShader = (PFNGLCOMPILESHADERPROC)getProc(hOut, "glCompileShader");
glAttachShader = (PFNGLATTACHSHADERPROC)getProc(hOut, "glAttachShader");
glLinkProgram = (PFNGLLINKPROGRAMPROC)getProc(hOut, "glLinkProgram");
glUseProgram = (PFNGLUSEPROGRAMPROC)getProc(hOut, "glUseProgram");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)getProc(hOut, "glGetShaderInfoLog");
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)getProc(hOut, "glGetProgramInfoLog");
glDeleteShader = (PFNGLDELETESHADERPROC)getProc(hOut, "glDeleteShader");
glDetachShader = (PFNGLDETACHSHADERPROC)getProc(hOut, "glDetachShader");
glIsProgram = (PFNGLISPROGRAMPROC)getProc(hOut, "glIsProgram");
glGenBuffers = (PFNGLGENBUFFERSPROC)getProc(hOut, "glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC)getProc(hOut, "glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC)getProc(hOut, "glBufferData");
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)getProc(hOut, "glEnableVertexAttribArray");
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)getProc(hOut, "glVertexAttribPointer");
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)getProc(hOut, "glGenVertexArrays");
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)getProc(hOut, "glBindVertexArray");
glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)getProc(hOut, "glGetIntegeri_v");
glGetStringi = (PFNGLGETSTRINGIPROC)getProc(hOut, "glGetStringi");
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)getProc(hOut, "wglSwapIntervalEXT");
wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)getProc(hOut, "wglGetSwapIntervalEXT");
}

关于c - glUseProgram 是否有任何原因可能导致我的程序崩溃? (C Win32),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60211398/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com