【OpenGL Tutorial】Lesson2 移动与旋转

OpenGL手册国内镜像,docs.gl,learnopengl-cn,opengl-tutorial docs.gl,learnopengl-cn,opengl-tutorial 国内镜像 阅读详情

移动和旋转

我们上一个程序有些简单,我们不是要学3D编程吗?上一个程序看起来完全是2D啊,现在就让我们做一些有意思的事情——让图形旋转起来。

为了做到这一点,我们要理解OpenGL里面的移动和旋转。我们想象有一只鸟在场景里面飞行。它从原点开始,沿着z轴的负方向飞行,它可以移动、旋转、长大和缩小。当我们用glVertex将点传输给OpenGL的时候,OpenGL就用它来将鸟进行关联起来。所以,如果我们将这只鸟扩大两倍,并向右移动两个单元,从它的角度看,点(0,4,0)对它来说就是(1,2,0)。如果我们将这只鸟以x轴旋转90度,向上移动2个单元,点(0,0,-1)相对于它来说就是(0,-1,-2)。下面的图片就是上面的描述的情况,鸟是我通过橡皮泥捏成的。



此时你会想,“这个太愚蠢了,我为什么不直接画出已经移动好的点呢?”,不要着急,这节课后你将会明白为什么这么做。

我们将从上一节课的代码继续将其,有些注释将会删除。首先,我们将我们的“鸟”移动5个单位长度,用0作为z坐标的值,而不是原来用-5作为z坐标的值。我们调用glTranslatef来移动图形。

    glLoadIdentity(); //Reset the drawing perspective
    glTranslatef(0.0f, 0.0f, -5.0f); //Move forward 5 units
    
    glBegin(GL_QUADS);
    
    //Trapezoid
    glVertex3f(-0.7f, -1.5f, 0.0f);
    glVertex3f(0.7f, -1.5f, 0.0f);
    glVertex3f(0.4f, -0.5f, 0.0f);
    glVertex3f(-0.4f, -0.5f, 0.0f);
    
    glEnd();
    
    glBegin(GL_TRIANGLES);
    
    //Pentagon
    glVertex3f(0.5f, 0.5f, 0.0f);
    glVertex3f(1.5f, 0.5f, 0.0f);
    glVertex3f(0.5f, 1.0f, 0.0f);
    
    glVertex3f(0.5f, 1.0f, 0.0f);
    glVertex3f(1.5f, 0.5f, 0.0f);
    glVertex3f(1.5f, 1.0f, 0.0f);
    
    glVertex3f(0.5f, 1.0f, 0.0f);
    glVertex3f(1.5f, 1.0f, 0.0f);
    glVertex3f(1.0f, 1.5f, 0.0f);
    
    //Triangle
    glVertex3f(-0.5f, 0.5f, 0.0f);
    glVertex3f(-1.0f, 1.5f, 0.0f);
    glVertex3f(-1.5f, 0.5f, 0.0f);
    
    glEnd();

如果我们编译运行这段代码,结果与上一节课的结果是一样的,这也是我们所希望的结果。

让我们再来看看上节课遗留下来的glLoadIdentity函数,它的作用就是重置我们的“鸟”,让我们的“鸟”回到原点,朝向z的负方向。

现在,让我们利用一下移动这个功能,使得我们要对图形进行处理的时候都是以图形的中心为参考点的。

    glLoadIdentity(); //Reset the drawing perspective
    glTranslatef(0.0f, 0.0f, -5.0f); //Move forward 5 units
    
    glPushMatrix(); //Save the transformations performed thus far
    glTranslatef(0.0f, -1.0f, 0.0f); //Move to the center of the trapezoid
    
    glBegin(GL_QUADS);
    
    //Trapezoid
    glVertex3f(-0.7f, -0.5f, 0.0f);
    glVertex3f(0.7f, -0.5f, 0.0f);
    glVertex3f(0.4f, 0.5f, 0.0f);
    glVertex3f(-0.4f, 0.5f, 0.0f);
    
    glEnd();
    
    glPopMatrix(); //Undo the move to the center of the trapezoid
    glPushMatrix(); //Save the current state of transformations
    glTranslatef(1.0f, 1.0f, 0.0f); //Move to the center of the pentagon
    
    glBegin(GL_TRIANGLES);
    
    //Pentagon
    glVertex3f(-0.5f, -0.5f, 0.0f);
    glVertex3f(0.5f, -0.5f, 0.0f);
    glVertex3f(-0.5f, 0.0f, 0.0f);
    
    glVertex3f(-0.5f, 0.0f, 0.0f);
    glVertex3f(0.5f, -0.5f, 0.0f);
    glVertex3f(0.5f, 0.0f, 0.0f);
    
    glVertex3f(-0.5f, 0.0f, 0.0f);
    glVertex3f(0.5f, 0.0f, 0.0f);
    glVertex3f(0.0f, 0.5f, 0.0f);
    
    glEnd();
    
    glPopMatrix(); //Undo the move to the center of the pentagon
    glPushMatrix(); //Save the current state of transformations
    glTranslatef(-1.0f, 1.0f, 0.0f); //Move to the center of the triangle
    
    glBegin(GL_TRIANGLES);
    
    //Triangle
    glVertex3f(0.5f, -0.5f, 0.0f);
    glVertex3f(0.0f, 0.5f, 0.0f);
    glVertex3f(-0.5f, -0.5f, 0.0f);
    
    glEnd();
    
    glPopMatrix(); //Undo the move to the center of the triangle

如果我们再次编译运行这段代码,结果还是一样的。

在这段代码里面,我们用到了两个新的并且重要的函数:glPushMatrix和glPopMatrix,我们利用这两个函数保存和恢复我们“鸟”的状态。glPushMatrix保存它的状态,glPopMatrix恢复它的状态。值得注意的是,就像每一个glBegin后都有一个glEnd一样,每一个glPushMatrix后都要有一个glPopMatrix。我们利用glPushMatrix来保存“鸟”的状态,以至于不用重新将坐标移动到-5值。

其实我们可以保存多个“鸟”的状态,因为我们有一个状态栈。每一次我们调用glPushMatrix就是将状态放入栈顶,每次调用过来PopMatrix就是将状态弹出栈。OpenGL的状态栈最大可以存储32个状态。

glPopMatrix和glPushMatrix之所以这样命名是因为OpenGL通过矩阵来表示“鸟”的状态。现在,你无需担心矩阵是怎样工作的。

现在让我们改变一下我们的程序。让每一个图形都选择30度,五角星图形缩小到原来的70%。

float _angle = 30.0f;

//Draws the 3D scene
void drawScene() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
    glLoadIdentity(); //Reset the drawing perspective
    glTranslatef(0.0f, 0.0f, -5.0f); //Move forward 5 units
    
    glPushMatrix(); //Save the transformations performed thus far
    glTranslatef(0.0f, -1.0f, 0.0f); //Move to the center of the trapezoid
    glRotatef(_angle, 0.0f, 0.0f, 1.0f); //Rotate about the z-axis
    
    glBegin(GL_QUADS);
    
    //Trapezoid
    glVertex3f(-0.7f, -0.5f, 0.0f);
    glVertex3f(0.7f, -0.5f, 0.0f);
    glVertex3f(0.4f, 0.5f, 0.0f);
    glVertex3f(-0.4f, 0.5f, 0.0f);
    
    glEnd();
    
    glPopMatrix(); //Undo the move to the center of the trapezoid
    glPushMatrix(); //Save the current state of transformations
    glTranslatef(1.0f, 1.0f, 0.0f); //Move to the center of the pentagon
    glRotatef(_angle, 0.0f, 1.0f, 0.0f); //Rotate about the y-axis
    glScalef(0.7f, 0.7f, 0.7f); //Scale by 0.7 in the x, y, and z directions
    
    glBegin(GL_TRIANGLES);
    
    //Pentagon
    glVertex3f(-0.5f, -0.5f, 0.0f);
    glVertex3f(0.5f, -0.5f, 0.0f);
    glVertex3f(-0.5f, 0.0f, 0.0f);
    
    glVertex3f(-0.5f, 0.0f, 0.0f);
    glVertex3f(0.5f, -0.5f, 0.0f);
    glVertex3f(0.5f, 0.0f, 0.0f);
    
    glVertex3f(-0.5f, 0.0f, 0.0f);
    glVertex3f(0.5f, 0.0f, 0.0f);
    glVertex3f(0.0f, 0.5f, 0.0f);
    
    glEnd();
    
    glPopMatrix(); //Undo the move to the center of the pentagon
    glPushMatrix(); //Save the current state of transformations
    glTranslatef(-1.0f, 1.0f, 0.0f); //Move to the center of the triangle
    glRotatef(_angle, 1.0f, 2.0f, 3.0f); //Rotate about the the vector (1, 2, 3)
    
    glBegin(GL_TRIANGLES);
    
    //Triangle
    glVertex3f(0.5f, -0.5f, 0.0f);
    glVertex3f(0.0f, 0.5f, 0.0f);
    glVertex3f(-0.5f, -0.5f, 0.0f);
    
    glEnd();
    
    glPopMatrix(); //Undo the move to the center of the triangle

现在我们程序的运行结果是这样的:


我们引入了一个新的变量,_angle,它用来存储我们想要图形的旋转度数。我们这里用到了两个新的函数。我们调用glRotatef来旋转我们的“鸟”。我们调用glRotatef(_angle,0.0f,0.0f,1.0f)来将我们的“鸟”绕着z轴旋转_angle大小的角度,我们调用glRotatef(_angle,1.0f,2.0f,3.0f)来将我们的“鸟”绕着向量(1,2,3)旋转_angle大小的角度。我们调用glScalef(0.7f,0.7f,0.7f)将我们的“鸟”的x、y、z坐标缩小70%。如果我们调用glScalef(2.0f,1.0f,1.0f),它会将我们的“鸟”的x坐标扩大2倍。

非常重要的一点是:glTranslatef、glRotatef、glScalef不能在glBegin-glEnd块中调用。

现在让我们改变镜头的角度——向左偏转10度。

float _cameraAngle = 10.0f;

//Draws the 3D scene
void drawScene() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
    glLoadIdentity(); //Reset the drawing perspective
    glRotatef(-_cameraAngle, 0.0f, 1.0f, 0.0f); //Rotate the camera
    glTranslatef(0.0f, 0.0f, -5.0f); //Move forward 5 units

我们程序的运行结果将会是:


我们用了一个小技巧来改变镜头的角度——将镜头反方向旋转10度。这是一个很好用的技术,我们在3D编程中常常用到。

在我们进入下一小节之前,我们先来介绍一下glMatrixMode函数。我们调用glMatrixMode(GL_MODEL_VIEW),我们设置点的转化用于场景的转化。如果我们调用glMatrixMode(GL_PORJECTION),就像handleResize函数中实现的那样,我们设置点的转化用于除正常转化外的其他转化。让我们看看handleResize函数,我们转换成投影矩阵模式,调用glLoadIdentity()函数重置它的矩阵,然后调用gluPerspective函数。gluPerspective函数执行了一个怪异的转化——给我们的点一个“视图”。不要担心他们是怎么工作,你只需要知道我们用GL_PROJECTION来设置我们的视图,用GL_MODEL_VIEW来说做其他的事情。

计时器

现在,让我们利用GLUT计时器加入一些动画。计时器的基本思想就是我们希望某段代码经常性的运行,让我们每2毫秒增加2度。下面代码展示了我们怎么去做的。
void update(int value) {
    _angle += 2.0f;
    if (_angle > 360) {
        _angle -= 360;
    }
    
    glutPostRedisplay(); //Tell GLUT that the scene has changed
    
    //Tell GLUT to call update again in 25 milliseconds
    glutTimerFunc(25, update, 0);
}

这就是我们的更新函数。首先我们对角度增加2度。如果角度达到了360度,我们就减去360度。其实我们没有必要去这样做,但我们让角度尽量小,因为它涉及到浮点型的精度问题。这里我们不详细去介绍浮点精度。我们调用glutPostRedisplay函数去通知OpenGL我们的场景已经改变,让GLUT重新绘制。最后我们调用glutTimierFunc(25,update,0)让程序每25毫秒调用一次。
参数value是GLUT传递给update的值。它就是我们传递给glutTimerFunc函数的最后一个值,它永远都是0。我们不需要使用这个参数,所以我们不去管它。

glutTimerFunc(25, update, 0); //Add a timer

在我们的主函数中增加另一个函数glutTimerFunc,以至于当程序运行时每25毫秒调用一次update。


在Visual C++中使用OpenGL构建虚拟现实应用实战 本文还有配套的精品资源,点击获取 简介:OpenGL是一个用于2D和3D图形编程的强大库,广泛应用于游戏、科学可视化和虚拟现实。在Visual C++(VC)环境下,开发者可以利用OpenGL库实现图形渲染和交互,构建虚拟现实应用。本文将介绍如何在VC中设置OpenGL环境、创建OpenGL上下文、绘制图形、处理用户输入、实现3D变换、设置光照和材质、纹理映射以及进行性能优... 阅读详情

相关推荐

OpenGL Tutorial(多个pdf集成在一起)

OpenGL Tutorial(多个pdf集成在一起) 非常全。。

OpenGL Tutorial

原文见这里 第一课:代码配置 第二课:简单画图 GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); 创建一个顶点数组对象,并将它设为当前对象。当窗口创建成功后(即OpenGL上下文创建后),马上做这一步工作;必须在任何其他OpenGL调用前完成。

vsooda的专栏 2194

Zynq工程IP核封装:XCI引用与约束继承实战指南

IP核封装是FPGA系统设计中实现模块复用、团队协作与技术资产沉淀的关键环节。其本质是将功能逻辑、时序约束、接口协议和硬件配置统一抽象为可配置、可验证、可演进的标准化组件。核心原理在于通过XCI文件保留IP核的参数化定义能力,依托Vivado IP Packager实现约束继承、端口自动映射与时钟域解耦,从而保障跨项目集成的时序可信性与约束完备性。该技术广泛应用于Zynq SoC视频处理、高速接口(如HDMI/TMDS)、多时钟域控制系统等场景,尤其在需要长期维护与版本迭代的工业级嵌入式开发中具有不可替代的

weixin_42593701的博客 122

学习OpenGL tutorials笔记(一)(入门)

本文适合新手参阅和讨论,高手欢迎提出批评,指出错误,不喜勿看~ 建议配合红宝书(新版本)配套学习 OpenGL tutorials 网站链接http://www.opengl-tutorial.org/ 具体环境搭建的问题之前博客有部分解决方案,有问题的可以提出来交流。 在基于网站教程的基础上,我对前三次课程(不包括环境搭建)进行了一次总结,在这里结合彩色立方体这一课,总结说明一下整个程序...

alexhu2010q的博客 967

低成本实现webhook接收端[python]

Webook本质上也是API,只不过是反向调用,即前端不主动发送请求,完全由后端推送。简单来说,Webhook是一个接受HTTP POST或是GET,PUT,DELETE的URL,一个实现了Webhook的API提供商就是在当事件发生的时候会向配置的URL发送信息,与请求-响应式不同,使用Webhook可以实时接收到变化。Ps:Webhook可能会发出大量的请求,确保接受的URL不被泄露或者应用能及时处理这些请求。

锡城小凯的博客 1万+

Python实现支付宝转账接口

由于工作需要使用python开发一个自动转账接口,记录一下开发过程。 首先需要在蚂蚁金服上申请开通开发者账户,有了开发者账户就可以使用沙箱进行开发了。 在开发之前我们需要在沙箱应用中填写密钥,密钥的获取可以使用阿里提供的工具包自动生成。 前期准备工作完成了,接下来是编写代码部分。主要用到了python-alipay-sdk库,使用pip安装即可,如果安装的过程中遇到问题推荐使用Anaconda...

FanMLei的博客 8516

【OpenGL Tutorial】Lesson1 基本图形

试一试 让我们先来看看我们的第一个OpenGL程序。下载“basic shapes”测试程序,编译并运行它(怎样用Visual Studio编译看第一节课程)。程序的运行样例如下图,点击ESC可以退出程序。 程序是怎样运行起来的 程序是怎样运行起来的呢?最基本的思想就是我们告知OpenGL每个图形顶点的3D坐标。OpenGL使用标准的x,y坐标系,x水平指向右方,y竖直指向上

whosemario的专栏 1359

Mathcad在LLC谐振变换器设计中的公式推导实战

本文通过Mathcad软件,详细演示了LLC谐振变换器设计的核心公式推导实战。文章阐述了如何利用Mathcad作为“会思考的草稿纸”,从定义基本参数、应用基波近似法(FHA)模型,到逐步推导电压增益公式及确定工作边界频率(fmin, fmax),并展示了如何通过动态参数扫描进行优化设计,帮助电源工程师高效、直观地完成理论计算,为后续仿真与实现奠定坚实基础。

q1w3e5r7t9y的博客 293

ChernoOpenGL_Tutorial(3):17~27

文章目录17. Textures in OpenGL18. Blending in OpenGL19. Maths in OpenGL20. Projection Matrices in OpenGL21. Model View Projection Matrices in OpenGL22. ImGui in OpenGL23. Rendering Multiple Objects in OpenGL24. Setting up a Test Framework for OpenGL关于 glClear、

weixin_47652005的博客 773

第三方系统(异构系统)基于token身份认证方式访问Ecology9的Restful接口Ecology9服务器配置部分

通过Token的认证方式调用Ecology9系统Restful业务接口服务器配置部分

svsou的专栏 2173

点云焊缝提取

本文介绍了一个基于PCL库的点云处理流程,包含三个核心模块:MLS平滑处理通过多项式拟合修正点云位置;差异提取通过双向匹配定位源/目标点云的非重叠区域;统计过滤剔除离群噪声点。该流程采用"平滑-筛选-净化"的通用思路,将复杂算法封装为可配置接口,实现了工业级点云预处理。文章重点分析了各模块的原理、PCL接口调用及参数设计逻辑,同时指出参数调优、算法扩展等深入探索方向,展现了PCL在点云处理中的模块化优势与实用价值。

weixin_45196569的博客 249

OpenGL Tutorial: (1) Setting up OpenGL with Visual Studio

本文的开发环境将基于Windows(无所谓Win7、Win8、Win10,XP应该也适用),Visual Studio 2013,FreeGLUT和GLEW。

辛亚平的专栏 2577

Android插件化和组件化面试题及参考答案

如何使用 Gradle 来管理 Android 项目中的模块依赖? Gradle 是一个强大的构建工具,在 Android 项目中管理模块依赖主要通过以下方式。 首先,在项目的根目录下的 build.gradle 文件中,需要配置仓库。一般会添加如 Google 的 Maven 仓库和 JCenter 等,例如在 repositories 部分添加: repositories { google() jcenter() } 对于模块依赖,在每个模块(例如 app

大模型大数据攻城狮的专栏 1182

iOS OpenGL ES2.0教程 Lesson03 旋转

http://jimmyzhouj.blog.51cto.com/2317513/884763 标签: 教程 iOS OpenGL ES tutorial 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://jimmyzhouj.blog.51cto.com/2317513/884763

any 1856

Python 爬虫实战:Twitter 数据定向抓取(特定话题 + 用户推文爬取与分析)

在社交媒体研究、舆情监测和市场分析等领域,Twitter 数据具有极高的价值。本文将详细介绍如何使用 Python 构建一个完整的 Twitter 数据爬取系统,包括特定话题和用户推文的爬取与分析。我们将涵盖从认证到数据存储、清洗、分析和可视化的全流程。

u014481728的博客 1033

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

ChernoOpenGL_Tutorial(1):1~12

文章目录前言1. Welcome to OpenGL2. Setting up OpenGL and Creating a Window in C++3. Using Modern OpenGL in C++4. Vertex Buffers and Drawing a Triangle in OpenGL5. Vertex Attributes and Layouts in OpenGL6. How Shaders Work in OpenGL7. Writing a Shader in OpenGL8.

weixin_47652005的博客 1698

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

OpenGL学习网站介绍

根据自身学习节奏选择适合的资源,建议理论与实践结合,多动手编写代码。

极客BIM工作室 1018

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

OpenGL ES入门教程(一)编写第一个OpenGL程序

编写第一个OpenGL程序,OpenGL入坑之“hello world”

Mekeater的博客 1711

如何实现完全离线的音频转录:Buzz本地语音处理终极指南

你是否需要处理会议录音、采访素材或播客内容,但又担心数据安全?**离线音频转录**技术为你提供了完美的解决方案。Buzz是一款基于OpenAI Whisper技术的隐私保护转录工具,让所有语音处理都在你的个人电脑上完成,彻底杜绝数据泄露风险。无论是商务会议记录、学术研究访谈,还是内容创作的字幕制作,Buzz都能在保护隐私的前提下,提供高质量的语音转文字服务。 ## 🎯 为什么选择离线音频转录?

gitblog_00095的博客 480

现代OpenGL教程(三):绘制彩色立方体(imgui+OpenGL3.3)

前言:imgui 是一个开源的GUI框架,自带的例子里面直接集成了glfw+gl3w环境,本例使用的版本是imgui v1.61,下载地址:https://github.com/ocornut/imgui/tags。本教程在上一个教程现代OpenGL教程(二):矩阵变换(imgui+OpenGL3.3)的基础上进行修改,绘制一个彩色立方体。 教程目录(持续更新中): 现代OpenGL教程(一):...

... 9424

Opengl入门版Windows教程-课程笔记

文章目录窗口创建笛卡尔坐标系点绘制线绘制CCW三角形绘制坐标系介绍矩阵变换矩阵压栈和弹栈BMP文件解析纹理绘制光照OBJ文件解析OBJ绘制学习中... 窗口创建 Windows API窗口创建 //窗口相关头文件 #include <Windows.h> #include <gl/GL.h> #include <gl/GLU.h> //链接opengl库,windows平台自带 #pragma comment(lib,"opengl32.lib") #pragma co

小鱼酱的博客 791

笔记:OpenGL Tutorial 02

OpenGL Tutorial 2 VAO:  OpenGL抛弃glEnable(),glColor(),glVertex(),glEnable()这一套流程的函数和管线以后,就需要一种新的方法来传递数据到Graphics Card来渲染几何体,我们可以用VBO, 在3+版本我们可以使用Vertex Array Object-VAO,VAO是一个对象,其中包含一个或者更多的Vertex B

SherrMoo 608

glrotatef如何绕自身轴旋转

首先我们知道所有的opengl操作都以点(0,0,0)作为基点。 glrotatef(旋转角度(0~360),x,y,z),z,y,z是旋转轴。由于旋转操作全都围绕点(0,0,0),所以如果你的物体并非在(0,0,0)点绘制,那么其旋转的时候就会有偏移。 比如,我们假设有一个正方体,近角点的坐标是(0,0,0)远角点的坐标是(1,1,1)。为了使这个正方体绕其中心旋转,我们必须把它的中心点移动

随便看看就好 1万+

opengl-tutorial(经典网站)

http://www.opengl-tutorial.org/cn/intermediate-tutorials/tutorial-13-normal-mapping/

tianyapai的专栏 890

OpenGL Tutorials - Billboards

原文:OpenGL-Turorial - Billboards Billboards Billboard 是3D世界中的2D元素。它不是一个在所有其他东西顶上显示的2D菜单,也不是一个可以让你旋转的3D平面;但介于他们之间的东西,如多数游戏中的:血条。 而Billboard区别在于他们的位置是可以指定的,但它们的朝向会一直的朝向镜头。 Solution #1 : The 2D way 解决方案1:...

Jave.Lin 的学习笔记 967

现代OpenGL系列教程(一)---旋转的三角形

【写在前面】 本章主要内容: 1、基本的矩阵变换 2、基本的OpenGL Buffer Object 3、基本的GLSL(OpenGL着色语言) 【正文开始】 在正式开始学习之前,我必须要说明的是: 接上一章,我假设你已经搭建好 glfw3 + glad + opengl 的环境。 为了简化开发,我把一些比较繁琐的、乱七八糟的一些 Api 简单的封装了一下,因此在后面的教程中,我...

梦起丶的博客 5068
上一篇: 【OpenGL Tutorial】Lesson1 基本图形
下一篇: 最大独立集问题
whosemario
博客等级 码龄16年 22粉丝 55原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值