最近自己搞了一下opengl的配置,网上众多教程要么不是VS2022版本的,要么是要你改其内部库文件,甚至改SYSWOW64文件夹的,事实证明那种方式确实可以,但私以为不好。
本文章介绍在项目内部导入opengl的方法,好处是不用动VS库以及电脑内部文件,换言之把这个项目放到任何电脑上都能跑,而且如果想要再建一个项目的话可以直接复制项目文件夹,十分的方便。
背景知识
openGL本身是电脑自带的,你可以去C:\Windows\SysWOW64中看到有一个opengl32.dll。我们只需要下载三个opengl的扩展包,分别是glfw,glew,glut。后两者点链接直接下载
glfw下载这个32-bit的编译好的版本。

事前准备
VS2022(其实更早的版本也可以,差不多,区别我在下边会说一下)
如果你之前跟着别的教程下载了Nuget的包

先把这俩给卸了(项目->管理Nuget程序包)
因为我们是需要自己下载外部依赖并且配置,如果下载了这俩会造成冲突,产生一些奇奇怪怪的问题。
现在开始在vs2022中配置环境
先创建一个空项目,我命名为test

打开之后找到资源管理器,右键这个test


点击在文件资源管理器中打开文件夹,然后你就在文件资源管理器中打开了文件夹

在这里新建一个文件夹叫Dependencies,意为依赖,当然你也可以起其他名字,只是这个词比较有b格
我们下面就在这里面放刚才下载的三个外部包。

在这里面先建仨文件夹,名字随意大小写随意,然后把相应的下载的压缩包里的东西塞进去:
glew:全塞进来就行了,doc文件夹和那个txt不用也行,就是说明书

glfw:塞进去include和相应的VS版本的lib文件夹。

glut:全塞进去

好了,现在文件资源就绪了,下面就是要让这个项目知道要去哪里找到相应的头文件和链接文件。
回到项目:

右键test,选添加->新建项

建立一个cpp,我叫他test.cpp
然后再右键test,点属性

c/c++项下常规,最上边的那个附加包含目录,可以让项目到对应的地址下寻找头文件的。我们要让项目能找到glfw,glew,glut的头文件,所以我们要将这三者的目录写上,中间用分号隔开就行。那一行右边有个箭头,下拉列表有一个编辑,点开那个写起来方便一些。


这里有一个比较能装的知识,就是VS提供了一个宏$(SolutionDir),代表了当前项目的解决方案所在的文件夹路径,当然你也可以把完整路径写上,这样就存在一个潜在问题,就是如果把项目搬到其他位置的话需要更新这些路径,十分麻烦。如果用宏的话可以随意搬运项目文件夹,没有问题。
然后是链接器常规

这里在“附加库目录”那里把所有lib放进去,如下:
然后确定
最后在这个链接器输入的“附加依赖项”,先把原先有的内容删去,因为这些内容是默认的了,放不放一个样,删掉之后更顺眼一些,再在那里面写如下内容,最好按顺序。


ok了
最后一步就是配置动态链接库。动态链接库是一个包含可由多个程序同时使用的代码和数据的库,简单来说没有dll我们就不能正常的显示一些窗口。
而这一步也很简单,只需要把这几个dll文件copy(或者cut)到cpp文件所在目录即可。




一共四个,看好路径不要搞错了,尤其是glew的。
有的同学可能觉得最后这一步好不专业,乱改一些路径,没什么技术含量,其实你也可以去网上搜一下VS指定dll外部库路径的方式,这种方式虽然看起来非常专业,但其实对于程序的发行来说不是很好。我们可以看一下电脑上某些软件,这里拿qq举例

我们可以看到一个发行的程序,是直接把exe放在dll所在文件夹内部的,这样更加的方便,也省去了过度设计结构带来的管理负担。
所以这里我们就放心大胆的把dll放在这里就好。
到此为止就成功了,下面附几个代码可以检验一下是否成功配置。
#include <iostream>
using namespace std;
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const GLint WIDTH = 800, HEIGHT = 600; // 先设置窗口以及其大小
int main()
{
glfwInit(); //初始化,使用glfw来打开一个窗口
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // 缩放窗口的关闭
GLFWwindow* window_1 = glfwCreateWindow(WIDTH, HEIGHT, "Hello, friend! I'm a openGL window!", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window_1, &screenWidth, &screenHeight); // 获得实际占用的帧缓存大小
if (nullptr == window_1) //判断窗口输出是否成功
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window_1); // 捕获当前窗口,准备对当前窗口进行画图
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) // 判断glew初始化是否成功
{
cout << "Failed to initialise GLEW" << endl;
glfwTerminate();
return -1;
}
glViewport(0, 0, screenWidth, screenHeight); // 设置视口的大小
while (!glfwWindowShouldClose(window_1))
{
glfwPollEvents();
glClearColor(0.1f, 0.8f, 0.7f, 1.0f); // 分别是红、绿、蓝、透明度的四个参数。RGB三原色+透明度
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window_1); // 双缓存模式
}
glfwTerminate(); // 如果循环结束:glfw关闭
return 0;
}
#include <stdlib.h>
#define GLUT_DISABLE_ATEXIT_HACK
#include <glut.h>
void display(void)
{
/* 清除所有的像素*/
glClear(GL_COLOR_BUFFER_BIT);
/* 绘制一个对角顶点坐标分别为(0.25, 0.25, 0.0) 和(0.75, 0.75, 0.0) 的白色多边形
*(矩形) */
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);//glBegin支持的方式除了GL_POINTS和GL_LINES,还有GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN
//适当了解一些,当然,确认顶点的方式也有很多种:glVertex2d glVertex2f glVertex3f glVertex3fv等等~~~~
glVertex3f(0.25, 0.25, 0.0);
glVertex3f(0.75, 0.25, 0.0);
glVertex3f(0.75, 0.75, 0.0);
glVertex3f(0.25, 0.75, 0.0);
glEnd();
glBegin(GL_LINES);
glVertex2d(0.0, 0.0);
glVertex2d(5.0, 5.0);
glEnd();
/* 不等待!立刻开始处理在缓冲区中的OpenGL函数调用*/
glFlush();//保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待)。其作用跟fflush(stdout)类似。
}
void init(void)
{
/* 指定清除颜色*/
glClearColor(0.0, 0.0, 0.0, 0.0);
/* 初始化视景体*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
/* 指定窗口的初始大小和位置以及显示模式(单缓存和RGBA模式)
* 打开一个标题为“hello”的窗口,调用初始化函数
* 注册用于显示图形的回调函数,进入主循环并处理事件
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv); /*初始化GLUT并处理命令行参数*/
//设置显示方式,前面是缓冲的选择,有GLUT_SINGLE-使用单缓冲区 GLUT_DOUBLE-双缓冲区
//后面的是颜色表示的方式:GLUT_RGB使用RGB颜色 GLUT_INDEX使用索引颜色
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 600); /*指定窗口的大小,单位为像素*/
glutInitWindowPosition(200, 200); /*指定窗口左上角在屏幕上的位置*/
glutCreateWindow("Window-name"); /*使用一个OpenGL场景创建一个窗口*/
//注意的是:窗口创建之后,并不能立即显示在屏幕上,需要调用glutMainLoop()才能
init();
glutDisplayFunc(display);//暂时理解成:设置一个函数,当需要进行画图时,这个函数就会被调用
glutMainLoop();//进行消息循环(暂时这么理解吧)
return 0; /* ANSI C 要求main()返回一个int值*/
}
如果程序出错,可以往下看看FAQ(持续更新ing)
FAQ
1.“无法解析的外部符号”

在那个链接器->输入的附加依赖项中选上下边那个设置继承即可。

2.一堆红,头文件打不开


这个地方选上x86.
3.“无法打开。。。”

再检查一遍路径的拼写,很容易出错的,尤其是用了$(SolutionDir)宏的,注意后面的下一级目录前面不要带反斜杠。
如果还有别的问题欢迎在评论区留言或者私信d我。
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
注意:本文主要掌握DCN自研无线产品的基本配置方法和注意事项,能够进行一般的项目实施、调试与运维AP基本配置命令AP登录用户名和密码均为:adminAP默认IP地址为:192.168.1.10AP默认情况下DHCP开启AP静态地址配置:setmanagementstatic-ip192.168.10.1AP开启/关闭DHCP功能:setmanagementdhcp-statusup/downAP设置默认网关:setstatic-ip-routegeteway192.168.10.254查看AP基本信息:getsystemgetmanagementgetmanaged-apgetrouteAP配
1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模
我试图在rails中了解rubygems是如何变得可以自动使用的,而不是在使用required的文件中gem? 最佳答案 这是通过bundler/setup完成的:http://bundler.io/v1.3/bundler_setup.html.它在您的config/boot.rb文件中是必需的。简而言之,它首先将环境变量设置为指向您的Gemfile:ENV['BUNDLE_GEMFILE']||=File.expand_path('../../Gemfile',__FILE__)然后它通过要求bundler/setup将所有ge
我是ruby的新手,正在配置IRB。我喜欢pretty-print(需要'pp'),但总是输入pp来漂亮地打印它似乎很麻烦。我想做的是默认情况下让它漂亮地打印出来,所以如果我有一个var,比如说,'myvar',然后键入myvar,它会自动调用pretty_inspect而不是常规检查。我从哪里开始?理想情况下,我将能够向我的.irbrc文件添加一个自动调用的方法。有什么想法吗?谢谢! 最佳答案 irb中默认pretty-print对象正是hirb被迫去做。Theseposts解释hirb如何将几乎所有内容转换为ascii表。虽
我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO
我正在使用Ruby/Mechanize编写一个“自动填写表格”应用程序。它几乎可以工作。我可以使用精彩CharlesWeb代理以查看服务器和我的Firefox浏览器之间的交换。现在我想使用Charles查看服务器和我的应用程序之间的交换。Charles在端口8888上代理。假设服务器位于https://my.host.com。.一件不起作用的事情是:@agent||=Mechanize.newdo|agent|agent.set_proxy("my.host.com",8888)end这会导致Net::HTTP::Persistent::Error:...lib/net/http/pe