GLEW 和 GLFW 未定义引用
GLEW and GLFW undefined references
我正在尝试使用 glfw 和 glew 设置 openGl。这是源代码:
#define GLFW_INCLUDE_GLU
#ifdef _WIN32
#define GLFW_DLL // -> windows
#include <GL/glew.h>
#elif __linux__
#include <GL/glew.h>
#endif
#include <GLFW/glfw3.h>
#include <iostream>
#include <stdexcept>
GLFWwindow* window = NULL;
GLFWmonitor* monitor = NULL;
int window_width = 800;
int window_height = 600;
static void window_hints() {
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
glfwWindowHint(GLFW_RED_BITS, mode->redBits);
glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
}
static void set_window_callbacks() {
glfwSetWindowCloseCallback(window, [] (GLFWwindow *window) {
std::cout << "closing window!";
});
glfwSetKeyCallback(window, [] (GLFWwindow *window, int key,int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
});
glfwSetWindowSizeCallback(window, [] (GLFWwindow *window, int width, int height) {
glViewport(0, 0, width, height);
window_width = width;
window_height = height;
glLoadIdentity();
GLdouble aspect = (GLdouble)window_width / window_height;
glOrtho(-1, 1, -1 / aspect, 1 / aspect, 0.01, 10000);
glTranslatef(0, 0, -10);
});
}
void GLAPIENTRY
MessageCallback( GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam )
{
fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
type, severity, message );
}
int main(int argc, char *argv[])
{
glfwSetErrorCallback([] (int code, const char * err_msg) {
std::cerr << "GLFW Error " << code << ": \n\t" << err_msg << std::endl;
});
if(!glfwInit())
throw std::runtime_error("glfwInit failed");
monitor = glfwGetPrimaryMonitor();
window_hints();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
window = glfwCreateWindow(window_width, window_height, "test window", NULL, NULL);
if(!window)
throw std::runtime_error("glfwOpenWindow failed.");
set_window_callbacks();
// GLFW settings
glfwMakeContextCurrent(window);
glewInit();
glfwSwapInterval(1);
std::cout << glGetString(GL_VERSION) << std::endl;
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(MessageCallback, 0);
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, window_width, window_height);
glLoadIdentity();
GLdouble aspect = (GLdouble)window_width / window_height;
glOrtho(-1, 1, -1 / aspect, 1 / aspect, 0.01, 10000);
glTranslatef(0, 0, -10);
while(!glfwWindowShouldClose(window))
{
// process pending events
glfwPollEvents();
glClearColor(0, 0, 0, 1); // black
glClear(GL_COLOR_BUFFER_BIT);
//glRotatef(1, 0, 0, 0.1);
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(-0.5, -0.5);
glColor3f(0.0, 1.0, 0.0);
glVertex2f( 0.5, -0.5);
glColor3f(0.0, 0.0, 1.0);
glVertex2f( 0.0, 0.5);
glEnd();
glfwSwapBuffers(window);
}
// clean up and exit
glfwTerminate();
std::cerr << std::endl;
return 0;
}
这在 Linux 下使用以下 makefile 完美运行:
main: main.cpp makefile
g++ main.cpp -g -o main -lglfw -lGL -lX11 -lGLEW -std=c++2a
然后,我也想让它在 windows 下编译,所以我尝试使用这个 makefile:
main.exe: main.cpp makefile
g++ main.cpp -g -o main.exe -I"D:\cpp_libraries\glfw-3.3.5.bin.WIN64\include" -I"D:\cpp_libraries\glew-2.1.0\include" -L"D:\cpp_libraries\glfw-3.3.5.bin.WIN64\lib-mingw-w64" -L"D:\cpp_libraries\glew-2.1.0\lib\Release\x64" -lglfw3dll -lglew32 -lopengl32
此处,“glew-2.1.0”和“glfw-3.3.5.bin.WIN64”是从预编译 windows 二进制文件的相应下载页面下载的。我已将“D:\cpp_libraries\glew-2.1.0\bin\Release\x64”和“D:\cpp_libraries\glfw-3.3.5.bin.WIN64\lib-mingw-w64”添加到 Path 环境变量中它们包含 glew32.dll 和 glfw3.dll.
当我尝试编译时,g++ 在每个 glew/gl/glfw 函数调用中给出“未定义的引用”。我还通过 VS Code 的 tasks.json 尝试了 运行 相同的 g++ 命令,结果相同。
然后我注意到互联网上的每个人都说我必须 link 反对“glfw3.lib”,我注意到 g++ 的第一个 -L 参数是一个实际上不包含任何 . lib 文件,因为它应该。但是我在之前下载的 zip 中找不到任何地方的“glfw3.lib”。我什至尝试使用 CMake、Make 和 Code::Blocks 从源代码构建 glfw,但其中 none 生成了一个我可以 link 反对的 .lib 文件。
编辑:我忘了说我没有将 dll 添加到我的项目目录中,但确实没有必要。无论如何我都试过了,但没有解决问题。
编辑 2:最好 link 使用 -lglfw,而不是 -lglfwdll,所以我更改了它。
编辑 3:实际上,gl 函数 linked 很好。问题仅在于 glfw 和 glew。
我终于让它工作了。事实证明,glew 和 glfw 的预编译二进制文件在我的机器上不起作用。我必须自己下载这两个源代码并编译库。这是最终起作用的 makefile:
main.exe: main.cpp makefile
g++ main.cpp -g -o main.exe -I"D:/cpp_libraries/glfw-3.3.5-source/include" -I"D:/cpp_libraries/glew-2.1.0-source/include" -L"D:/cpp_libraries/glfw-3.3.5-compiled/src" -L"D:/cpp_libraries/glew-2.1.0-compiled/lib" -lglfw3 -lglew32 -lopengl32
我正在尝试使用 glfw 和 glew 设置 openGl。这是源代码:
#define GLFW_INCLUDE_GLU
#ifdef _WIN32
#define GLFW_DLL // -> windows
#include <GL/glew.h>
#elif __linux__
#include <GL/glew.h>
#endif
#include <GLFW/glfw3.h>
#include <iostream>
#include <stdexcept>
GLFWwindow* window = NULL;
GLFWmonitor* monitor = NULL;
int window_width = 800;
int window_height = 600;
static void window_hints() {
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
glfwWindowHint(GLFW_RED_BITS, mode->redBits);
glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
}
static void set_window_callbacks() {
glfwSetWindowCloseCallback(window, [] (GLFWwindow *window) {
std::cout << "closing window!";
});
glfwSetKeyCallback(window, [] (GLFWwindow *window, int key,int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
});
glfwSetWindowSizeCallback(window, [] (GLFWwindow *window, int width, int height) {
glViewport(0, 0, width, height);
window_width = width;
window_height = height;
glLoadIdentity();
GLdouble aspect = (GLdouble)window_width / window_height;
glOrtho(-1, 1, -1 / aspect, 1 / aspect, 0.01, 10000);
glTranslatef(0, 0, -10);
});
}
void GLAPIENTRY
MessageCallback( GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam )
{
fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
type, severity, message );
}
int main(int argc, char *argv[])
{
glfwSetErrorCallback([] (int code, const char * err_msg) {
std::cerr << "GLFW Error " << code << ": \n\t" << err_msg << std::endl;
});
if(!glfwInit())
throw std::runtime_error("glfwInit failed");
monitor = glfwGetPrimaryMonitor();
window_hints();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
window = glfwCreateWindow(window_width, window_height, "test window", NULL, NULL);
if(!window)
throw std::runtime_error("glfwOpenWindow failed.");
set_window_callbacks();
// GLFW settings
glfwMakeContextCurrent(window);
glewInit();
glfwSwapInterval(1);
std::cout << glGetString(GL_VERSION) << std::endl;
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(MessageCallback, 0);
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, window_width, window_height);
glLoadIdentity();
GLdouble aspect = (GLdouble)window_width / window_height;
glOrtho(-1, 1, -1 / aspect, 1 / aspect, 0.01, 10000);
glTranslatef(0, 0, -10);
while(!glfwWindowShouldClose(window))
{
// process pending events
glfwPollEvents();
glClearColor(0, 0, 0, 1); // black
glClear(GL_COLOR_BUFFER_BIT);
//glRotatef(1, 0, 0, 0.1);
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(-0.5, -0.5);
glColor3f(0.0, 1.0, 0.0);
glVertex2f( 0.5, -0.5);
glColor3f(0.0, 0.0, 1.0);
glVertex2f( 0.0, 0.5);
glEnd();
glfwSwapBuffers(window);
}
// clean up and exit
glfwTerminate();
std::cerr << std::endl;
return 0;
}
这在 Linux 下使用以下 makefile 完美运行:
main: main.cpp makefile
g++ main.cpp -g -o main -lglfw -lGL -lX11 -lGLEW -std=c++2a
然后,我也想让它在 windows 下编译,所以我尝试使用这个 makefile:
main.exe: main.cpp makefile
g++ main.cpp -g -o main.exe -I"D:\cpp_libraries\glfw-3.3.5.bin.WIN64\include" -I"D:\cpp_libraries\glew-2.1.0\include" -L"D:\cpp_libraries\glfw-3.3.5.bin.WIN64\lib-mingw-w64" -L"D:\cpp_libraries\glew-2.1.0\lib\Release\x64" -lglfw3dll -lglew32 -lopengl32
此处,“glew-2.1.0”和“glfw-3.3.5.bin.WIN64”是从预编译 windows 二进制文件的相应下载页面下载的。我已将“D:\cpp_libraries\glew-2.1.0\bin\Release\x64”和“D:\cpp_libraries\glfw-3.3.5.bin.WIN64\lib-mingw-w64”添加到 Path 环境变量中它们包含 glew32.dll 和 glfw3.dll.
当我尝试编译时,g++ 在每个 glew/gl/glfw 函数调用中给出“未定义的引用”。我还通过 VS Code 的 tasks.json 尝试了 运行 相同的 g++ 命令,结果相同。
然后我注意到互联网上的每个人都说我必须 link 反对“glfw3.lib”,我注意到 g++ 的第一个 -L 参数是一个实际上不包含任何 . lib 文件,因为它应该。但是我在之前下载的 zip 中找不到任何地方的“glfw3.lib”。我什至尝试使用 CMake、Make 和 Code::Blocks 从源代码构建 glfw,但其中 none 生成了一个我可以 link 反对的 .lib 文件。
编辑:我忘了说我没有将 dll 添加到我的项目目录中,但确实没有必要。无论如何我都试过了,但没有解决问题。
编辑 2:最好 link 使用 -lglfw,而不是 -lglfwdll,所以我更改了它。
编辑 3:实际上,gl 函数 linked 很好。问题仅在于 glfw 和 glew。
我终于让它工作了。事实证明,glew 和 glfw 的预编译二进制文件在我的机器上不起作用。我必须自己下载这两个源代码并编译库。这是最终起作用的 makefile:
main.exe: main.cpp makefile
g++ main.cpp -g -o main.exe -I"D:/cpp_libraries/glfw-3.3.5-source/include" -I"D:/cpp_libraries/glew-2.1.0-source/include" -L"D:/cpp_libraries/glfw-3.3.5-compiled/src" -L"D:/cpp_libraries/glew-2.1.0-compiled/lib" -lglfw3 -lglew32 -lopengl32