-
opengl 图形学 椭圆算法
2009-12-18 19:32:09opengl 图形学 椭圆算法opengl 图形学 椭圆算法opengl 图形学 椭圆算法opengl 图形学 椭圆算法opengl 图形学 椭圆算法opengl 图形学 椭圆算法opengl 图形学 椭圆算法opengl 图形学 椭圆算法opengl 图形学 椭圆算法... -
opengl图形学例子
2012-12-30 11:50:01opengl图形学代码。各种功能的·的运用等等. -
OpenGL 图形学 囧版种子填充
2009-12-18 19:37:08OpenGL 图形学 囧版种子填充OpenGL 图形学 囧版种子填充OpenGL 图形学 囧版种子填充OpenGL 图形学 囧版种子填充OpenGL 图形学 囧版种子填充OpenGL 图形学 囧版种子填充OpenGL 图形学 囧版种子填充 -
OpenGL图形学实验源码
2013-06-13 19:13:28openGL图形学实验内容,DDA 中点算法画直线,中点、多边形逼近画圆,扫描线填充,种子填充,图形变换,直线和多边形的裁剪 -
OPENGL图形学课程设计
2012-03-07 09:19:01OPENGL图形学课程设计,右键弹出菜单,F1 F2 F3 F4分别控制线框/填充、纹理、光照、旋转 -
OpenGL图形学演示程序
2012-12-01 23:14:45OpenGL图形学演示程序 在计算机发展初期,人们就开始从事计算机图形的开发,但直到20世纪80年代末90年代初,三维图形才开始迅速发展。于是各种三维图形工具软件包相继推出,如GL,RenderMan等,但没有一种软件包... -
OpenGL图形学实验 关于Texture的简单操作
2014-05-03 21:50:01OpenGL图形学实验 关于Texture的简单操作 建立一个正方体并在六个面上映射不同的纹理 -
【Unity基础知识】OpenGL图形学创建窗口
2020-07-15 10:39:03图形学就是研究如何在...那么今天就带领大家一起学习如何创建一个基于OpenGL图形学技术的基本游戏窗口,如下图所示: 准备工作 在正式编程前我们需要一些准备工作下载两个OpenGL工具库: 1.freeGLUT 这是一个O图形学就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。是游戏引擎如Unity,UE4渲染模块的底层技术。可以这么说,我们熟悉的所有平台所有类型的游戏中炫酷的画面都是使用图形学渲染出来的。因此图形学是基础建设,游戏引擎是框架结构,而游戏本身就是高质量的成品。
那么今天就带领大家一起学习如何创建一个基于OpenGL图形学技术的基本游戏窗口,如下图所示:
准备工作
在正式编程前我们需要一些准备工作下载两个OpenGL工具库:
1.freeGLUT
这是一个OpenGL的窗口工具库,可以辅助我们创建OpenGL窗口,还集成了很多其他好用的和OpenGL程序框架相关的功能,下载地址为:
http://nchc.dl.sourceforge.net/project/freeglut/freeglut/2.8.0/freeglut-2.8.0.tar.gz
2.GLEW
这是一个跨平台的C++扩展库,基于OpenGL图形接口。GLEW能自动识别你的平台所支持的全部OpenGL高级扩展涵数,下载地址为:
http://glew.sourceforge.net/
创建一个C++空工程
双击打开VS2017,选择文件->新建,选择C++模板,选择空项目,在下面填好工程名称和保存路径后点击右下角确定按钮创建一个新的空C++工程。
添加一个C++源文件
在源文件上右键->新建,在弹出的对话框中选择C++文件并在下面修改名称为Main.cpp(.cpp或.cc为C++源代码文件的后缀),点击添加。
编写一个基本C++程序
接下来我们在代码区首先编写一个C++基本程序以用来生成我们的.sln工程结构。
双击打开Main.cpp,键入如下代码后按Ctrl+F5编译并运行:
编译运行基本C++程序结构
我们会看到一个程序运行的C++控制台程序窗口并打印“C++程序”字样,恭喜大家,我们第1步顺利完成了,接下来我们在此基础上将其改造成一个OpenGL窗口。
在工程文件目录加入两个工具库
在工程目录下创建Includes并放入如下头文件:
在工程目录下创建Libs并放入如下静态库文件:
在与工程文件.sln同一级的Debug目录下放入如下动态库文件:
在VS工程属性界面配置两个工具库
接下来我们回到VS,在工程上右键->属性,在弹出的面板中选择VC++目录,然后我们点开包含目录,加入刚才创建的Includes目录位置:
然后我们继续点开库目录,加入刚才创建的Libs目录位置:
然后我们选择链接器->输入,在附加依赖项选项中加入如下静态库的链接:
改写Main.cpp
OK,至此所有OpenGL程序的编码前准备配置工作都已经完成,接下来我们正式对Main.cpp中的主函数进行改造,给其加入OpenGL窗口功能。
想要了解更多unity知识,可以关注优就业官网(www.ujiuye.com),如果想要更多的学习资料,可以添加我们的qq群-741090028 (加群备注暗号:小小优即可获得免费学习资料)
-
opengl图形学作业
2011-09-19 19:06:50这是一个opengl入门的小程序,很学习opengl还是很有意义的。 -
OPENGL图形学模版
2009-12-15 09:50:15基于图形学的一个关于OPENGL的模板,可以在这个程序 上面直接编程 -
opengl图形学编程问题
2015-05-03 03:05:38// 150502_1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include ...不太懂那个setPixel函数怎样调用……opengl不太会,但是图形学算法和其他编程语言略懂。请指教。 -
-
opengl图形学程序 c++代码
2008-10-20 22:29:08含所有的图形学算法的opengl实现,c/c++代码 -
OpenGL 图形学一些功能实现 c语言
2009-07-11 13:57:22OpenGL-3D图形绘制 OpenGL-阴暗处理 OpenGL-旋转 OpenGL-纹理贴图 OpenGL-3D建模与绘制 OpenGL-简单的光照 OpenGL-雾 OpenGL-透明 -
OpenGL图形学中的DDA算法
2020-10-15 12:41:15DDA(Digital Differential Analyzer):数字积分法 计算机中,直线并不是连续的,二是离散的点,这是光珊化的本质决定的。 两点确定一条直线,假设如果给出了起点和终点分别是(x1,y1),(x2,y2),假设这条...DDA(Digital Differential Analyzer):数字积分法
计算机中,直线并不是连续的,二是离散的点,这是光珊化的本质决定的。
两点确定一条直线,假设如果给出了起点和终点分别是(x1,y1),(x2,y2),假设这条直线为 y = mx + b,那么斜率m就是:
m = dy / dx = (y2 - y1) / (x2 - x1)
b = (x2y1 - x1y2) / (x2 - x1)有限差分近似解是:
x(i+1) = x(i) + ∆x
y(i+1) = y(i) + ∆y = y(i) + ((y1 - y1) / (x2 - x1)) * ∆x考虑到不能让直线出现中断的情况,
斜率|m|<1时,要以x轴为步进的主方向,∆y每次比较小。
斜率|m|>1时,要以y轴为步进的主方向,∆x每次比较小。经过上述知识点描述,DDA算法的实现思路如下:
声明double类的变量dx,dy,e,x,y,其中dx和dy作为步进长度,e作为循环次数,x和y记录每次画点的坐标;dx=x2-x1,dy=y2-y1,计算斜率,如果斜率小于1则选择x为主步进方向,反之y为主步进方向。循环e次,每次循环画一个点,这里我选择x每次增大0.5,同时要将变化后的点从浮点类型转换为整型,同时更新下一次的x和y值。关键部分代码:
void DDA_Line(int x1, int y1, int x2, int y2) { double dx, dy, e, x, y; dx = x2 - x1; dy = y2 - y1; e = (fabs(dx) > fabs(dy)) ? fabs(dx) : fabs(dy); dx /= e; dy /= e; x = x1; y = y1; for (int i = 0; i < e; i++) { glPointSize(5.0); glBegin(GL_POINTS); glVertex2i(int(x + 0.5), int(y + 0.5)); glEnd(); glFlush(); x += dx; y += dy; } }
实现效果:
可以看到画出了一条直线。
举个例子手动用DDA画一下点:
完整实现代码:#include <GL/glut.h> #include <math.h> void DDA_Line(int x1, int y1, int x2, int y2) { double dx, dy, e, x, y; dx = x2 - x1; dy = y2 - y1; e = (fabs(dx) > fabs(dy)) ? fabs(dx) : fabs(dy); dx /= e; dy /= e; x = x1; y = y1; for (int i = 0; i < e; i++) { glPointSize(5.0); glBegin(GL_POINTS); glVertex2i(int(x + 0.5), int(y + 0.5)); glEnd(); glFlush(); x += dx; y += dy; } } void display(void) { glClearColor(1.0, 1.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, 500, 500); DDA_Line(0, 500, 500, 0); glFlush(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RED); glutInitWindowSize(500, 500); glutInitWindowPosition(0, 0); glutCreateWindow("DDA_line"); glutDisplayFunc(display); glColor3f(0.0, 1.0, 1.0);//颜色 gluOrtho2D(0.0, 500.0, 0.0, 500.0); glutMainLoop(); return 0; }
-
opengl图形学实验七 不同的光照渲染
2014-06-06 12:46:21Opengl不同光照渲染的效果。小键盘1 2 3 4 5 进行操作。有不对之处请指教。 -
opengl 图形学3个直线裁剪算法
2018-05-15 23:03:13图形学三个最基础的直线裁剪算法//根据x、y来编码 int EnCode(int x,int y){ int c = 0; if (x<XL) { c |= LEFT; } if (x>XR) { c |= RIGHT; } if (y>YT) { c |= TOP; } if...图形学三个最基础的直线裁剪算法
//根据x、y来编码 int EnCode(int x,int y){ int c = 0; if (x<XL) { c |= LEFT; } if (x>XR) { c |= RIGHT; } if (y>YT) { c |= TOP; } if (y<YB) { c |= BOTTOM; } return c; } //Cohen-Sutherland裁剪算法 void CS_LineClip(int idex,int XL,int YB,int XR,int YT) { int x1 = gdLDArr[idex].x0; int x2 = gdLDArr[idex].x1; int y1 = gdLDArr[idex].y0; int y2 = gdLDArr[idex].y1; int code1,code2,code,x,y; code1 = EnCode(x1,y1); code2 = EnCode(x2,y2); while (code1!=0||code2!=0) { if ((code1&code2) != 0) { gdLDArr[idex].x0 = 0; gdLDArr[idex].y0 = 0; gdLDArr[idex].x1 = 0; gdLDArr[idex].y1 = 0; return; } if (code1 != 0) { code = code1; x = x1; y = y1; } else { code = code2; x = x2; y = y2;} if ((LEFT&code)!=0) { x = XL; y = y1 + (y2 - y1)*(XL - x1) / (x2 - x1); } else if ((RIGHT&code)!=0) { x = XR; y = y1 + (y2 - y1)*(XR - x1) / (x2 - x1); } else if ((BOTTOM&code) != 0) { y = YB; x = x1 + (x2 - x1)*(YB - y1) / (y2 - y1); } else if ((TOP&code) != 0) { y = YT; x = x1 + (x2 - x1)*(YT - y1) / (y2 - y1); } if (code==code1) { x1 = x; y1 = y; code1 = EnCode(x, y); } else { x2 = x; y2 = y; code2 = EnCode(x, y); } } gdLDArr[idex].x0 = x1; gdLDArr[idex].x1 = x2; gdLDArr[idex].y0 = y1; gdLDArr[idex].y1 = y2; } //中点裁剪算法 void MP_LineClip(int idex, int XL, int YB, int XR, int YT) { int x1 = gdLDArr[idex].x0; int x2 = gdLDArr[idex].x1; int y1 = gdLDArr[idex].y0; int y2 = gdLDArr[idex].y1; int code1, code2, code,xm, ym,xl,xr,yl,yr; code1 = EnCode(x1, y1); code2 = EnCode(x2, y2); while (code1 != 0 || code2 != 0) { if ((code1&code2) != 0) { gdLDArr[idex].x0 = 0; gdLDArr[idex].y0 = 0; gdLDArr[idex].x1 = 0; gdLDArr[idex].y1 = 0; return; } if (code1 != 0) { code = code1;} else { code = code2;} if ((LEFT&code) != 0) { xl = x1 < x2 ? x1 : x2; xr = x1 < x2 ? x2 : x1; yl = xl == x1 ? y1 : y2; yr = xl == x1 ? y2 : y1; xm = (xl + xr) / 2; ym = (yl + yr) / 2; while (xm!=XL) { if (xm<XL) { xl = xm; yl = ym; } else { xr = xm; yr = ym; } xm = (xl + xr) / 2; ym = (yl + yr) / 2; } } else if ((RIGHT&code) != 0) { xl = x1 < x2 ? x1 : x2; xr = x1 < x2 ? x2 : x1; yl = xl == x1 ? y1 : y2; yr = xl == x1 ? y2 : y1; xm = (xl + xr) / 2; ym = (yl + yr) / 2; while (xm != XR) { if (xm<XR) { xl = xm; yl = ym; } else { xr = xm; yr = ym; } xm = (xl + xr) / 2; ym = (yl + yr) / 2; } } else if ((BOTTOM&code) != 0) { yl = y1 < y2 ? y1 : y2; yr = y1 < y2 ? y2 : y1; xl = yl == y1 ? x1 : x2; xr = yl == y1 ? x2 : x1; xm = (xl + xr) / 2; ym = (yl + yr) / 2; while (ym != YB) { if (ym<YB) { yl = ym; xl = xm; } else { yr = ym; xr = xm; } xm = (xl + xr) / 2; ym = (yl + yr) / 2; } } else if ((TOP&code) != 0) { yl = y1 < y2 ? y1 : y2; yr = y1 < y2 ? y2 : y1; xl = yl == y1 ? x1 : x2; xr = yl == y1 ? x2 : x1; xm = (xl + xr) / 2; ym = (yl + yr) / 2; while (ym != YT) { if (ym<YT) { yl = ym; xl = xm; } else { yr = ym; xr = xm; } xm = (xl + xr) / 2; ym = (yl + yr) / 2; } } if (code == code1) { x1 = xm; y1 = ym; code1 = EnCode(x1, y1); } else { x2 = xm; y2 = ym; code2 = EnCode(x2, y2); } } gdLDArr[idex].x0 = x1; gdLDArr[idex].x1 = x2; gdLDArr[idex].y0 = y1; gdLDArr[idex].y1 = y2; } bool ClipT(float p, float q, float *u1, float *u2) { float r; if (p<0) { r = q / p; if (r>*u2) { return false; } if (r > *u1) { *u1 = r; } } else if (q>0) { r = q / p; if (r<*u1) { return false; } if (r<*u2) { *u2 = r; } } else { return (q >= 0); } return true; } //Liang-Barskey裁剪算法 void LB_LineClip(int idex, int XL, int YB, int XR, int YT) { int x1, x2, y1, y2; x1 = gdLDArr[idex].x0; x2 = gdLDArr[idex].x1; y1 = gdLDArr[idex].y0; y2 = gdLDArr[idex].y1; float dx, dy, u1, u2; u1 = 0; u2 = 1; dx = x2 - x1; dy = y2 - y1; if (ClipT(-dx,x1-XL,&u1,&u2)) if (ClipT(dx, XR - x1, &u1, &u2)) if (ClipT(-dy, y1 - YB, &u1, &u2)) if (ClipT(dy, YT - y1, &u1, &u2)) { gdLDArr[idex].x0 = x1 + u1 * dx; gdLDArr[idex].y0 = y1 + u1 * dy; gdLDArr[idex].x1 = x1 + u2 * dx; gdLDArr[idex].y1 = y1 + u2 * dy; return; } gdLDArr[idex].x0 = 0; gdLDArr[idex].y0 = 0; gdLDArr[idex].x1 = 0; gdLDArr[idex].y1 = 0; }
-
OpenGL图形学实验 正方体绕固定点旋转
2014-05-03 21:56:25定义一个球为中心,一个正方体沿以这个球心为圆心的圆周移动。正方体的正面永远朝向球心进行平滑旋转。 -
三维地形的模拟 VC opengl 图形学
2010-03-23 14:04:30VC+opengl的方式进行三维地形的模拟,效果不错哦 -
opengl计算机图形学
2019-06-15 16:24:50这个是计算机图形学的基于MFC的OpenGL编程,其中实现了四个功能,五角星随机的转动,小球碰撞,种子算法,等等 -
图形学opengl 模型
2010-06-06 15:53:11图形学opengl 模型图形学opengl 模型图形学opengl 模型图形学opengl 模型图形学opengl 模型图形学opengl 模型 -
图形学实用实验openGL
2009-12-28 23:24:11openGl 图形学学期实验 划线(三种划线方法) 填充多边形 二维三维图形移动等多个实验。以及其他可供参考的,都能运行 -
计算机图形学基于opengl图形变换源代码(包含可执行文件)
2018-01-28 22:54:24在vc++6.0环境下,基于OPENGL实现图形学设计内容。包括实现五边形到五角星的动态变换;利用DDA、中点画线法、Bresenham算法画直线;利用中点画圆法、Bresenham算法画圆;利用栅栏填充、扫描线填充实现多边形内部颜色... -
基于java的opengl计算机图形学学习资料源码
2016-12-24 11:02:59基于java的opengl计算机图形学学习资料源码,包含各种小例子,如机器人,3D模型,镜面等,深入浅出,适合初学者学习 -
OpenGL&图形学基础
2018-05-23 17:00:47通过自主完成并开发一套软3D引擎,让学员站在设计者的高度去看OpenGL,打通任督二脉,学员会深深的体会到什么是"会当凌绝顶,一览众山小". -
图形学OpenGL
2012-05-02 10:33:36该文档时关于图形学中OpenGL, 该资源绝对原创 -
【计算机图形学-2】OpenGL图形编程总览
2021-01-01 21:47:55图形系统总览 图形API处在应用接口和底层硬件的中间,负责:控制显卡的编程接口、计算与存储资源,输入显示内容,如三维场景/模型,生成输出图像。 图形开发史 两种主流图形API 严格来讲,OpenGL并不是一个API,...图形系统总览
图形API处在应用接口和底层硬件的中间,负责:控制显卡的编程接口、计算与存储资源,输入显示内容,如三维场景/模型,生成输出图像。图形开发史
两种主流图形API
严格来讲,OpenGL并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范。OpenGL规范严格规定了每个函数该如何执行,以及它们的输出值。至于内部具体每个函数是如何实现的,由OpenGL库的开发者自行决定。值得一提的是,2009年兴起的OpenGL 3.1并不向下兼容。在OpenGL 3.1以前,OpenGL使用立即渲染模式,这个模式下绘制图形很方便。OpenGL的大多数功能都被库隐藏起来,开发者很少有控制OpenGL如何进行计算的自由,且绘制效率较低。从OpenGL3.2开始,开始废弃立即渲染模式,开发者在OpenGL的核心模式下开发,这样就完全移除了旧的特性。OpenGL编程和着色器语言
OpenGL的编程,相对于普通编程难度较大,需要先有一些前置知识做铺垫:
-
两个重要的概念——vao和vbo(顶点数组对象和顶点缓冲对象)
早期的OpenGL为了将模型的顶点数据传送到显卡,需要逐个顶点进行(冗余问题),如果还需要额外的信息(纹理坐标和法线)的话,当模型比较复杂时,将导致大量函数的调用,传输开销是相当大的!为了解决这个问题引入了VBO(Vertex Buffer Object),VBO可以将顶点数据保存在显存中,绘制时直接从显存中取数据,减少了数据传输的开销。一句话总结就是:vbo保存要传递给GPU的数据。
虽然通过VBO我们可以将顶点属性数据保存在显存中,但是当绘制时,问题又来了,需要调用好几个函数,过程挺复杂的。为了解决这个问题,OpenGL又引入了==VAO(Vertex Array Object)==来关联VBO中的数据,有了VAO,任何数组形式的GL函数调用都会添加到VAO的绘制列表当中(直到解除VAO绑定),当需要绘制的时候,我们仅需要重新绑定VAO,那么之前创建的绘制列表将会重新激活,使得绘制代码更加简洁。一句话总结:vao定义了GPU读取vbo中数据的方式。
-
重要工具——着色器
OpenGL着色器有几种,最重要也是最常用的是顶点着色器和片元着色器,顶点着色器对顶点信息进行处理,片元着色器对片元进行处理。最简单的着色器长下面这样:
gl_Position默认是归一化的裁剪空间坐标,xyz各个维度的范围为-1到1,仅能在顶点着色器中使用,既是输入也是输出。 -
OpenGL库
-
OpenGL的渲染管线(Pipeline)
图元与观察
图元:一般指基本图形元素,显卡处理流水线能够理解的几何与图像数据单元分为几何图元与光栅图元两类。
常见图元种类:
-
点图元
GL_POINTS -
多边形图元:
GL_TRIANGLES
GL_TRIANGLE_SRTIP
GL_TRIANGLE_FAN
GL_QUADS
GL_QUAD_STRIP
GL_POLYGON
点图元就是一个点一个点地绘制;多边形图元按照一定的顺序绘制,示意图如下:
生成图元时,我们总是希望图元好绘制一些,因此,像一些角度极小,特别尖锐的图形,在绘制系统中是不希望看到的。传统是采用三角剖分来解决。三角剖分解决的问题是:解决复杂非凸多边形的绘制问题。
相机:OpenGL中的相机默认被放置在世界坐标系的原点,指向z轴的负方向;默认的视景体是一个中心在原点,边长为2的立方体。
属性和颜色
属性:属性是OpenGL中状态的一部分,确定对象的外观,例如颜色、点的大小、线段的宽度以及虚实模式、多边形的模式。
颜色:能理解RGB即可,注意颜色的每个分量在帧缓冲区中是分开存储的。OpenGL程序结构
为了能绘制图形,除了OpenGL,我们还需要其他的一些框架:
- 由于不同显卡公司的不同产品对OpenGL标准的实现以及OpenGL的扩展都不相同,因此需要一个能够发现并加载这些库的接口。GLEW提供了有效的运行机制,以寻找和识别用户平台所支持的全部 OpenGL 高级扩展函数。也就是说,只要包含一个 glew.h 头文件,用户就能使用以 gl、glu、glext 等开头的全部函数。
- 在使用OpenGL绘制图形前,需要先创建OpenGL运行环境和用于显示的窗口。然而,这些操作在每个系统上并不一样,OpenGL有目的地从这些操作抽象出去。这意味着用户不得不自己处理创建窗口,定义OpenGL上下文以及处理用户输入。FreeGLUT主要用来创建窗口,初始化 OpenGL 环境,管理用户鼠标、键盘的输入,使 OpenGL 程序变得简单和提升可移植性。(时下比较流行的另外一个窗口框架是GLFW)
总而言之,它们的关系可以用下面这幅图概括:
OpenGL编程概貌如下:
初始化窗口:#include <glew.h> #include <GL/glut.h> int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(500, 500); glutInitWindowPosition(0, 0); glutCreateWindow("simple OpenGL example"); glewExperimental = GL_TRUE; glewInit(); init(); glutDisplayFunc(display); // 绘制回调函数 glutMainLoop(); // 进入GLUT事件处理循环 return 0; }
绑定数据及指定绘制方式部分:
GLuint abuffer; glGenVertexArrays(1, &abuffer); glBindVertexArray(abuffer); GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
绘制:
void mydisplay(void) { glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_POINTS, 0, N); glFlush(); }
图形编程的交互
交互主要是通过键鼠交互,一般查文档就行了。一般流程是,得有一个注册了的Listener,这个Listener监听事件,如果某事件发生了就调用相应的Handler,处理相应。GLUT采用的就是事件驱动模型进行响应。
双缓冲
现代显示器的刷新频率一般在60-100Hz之间,单缓存会出现数据更新频率跟不上屏幕刷新频率,导致闪屏,采用双缓冲可以解决这个问题。双缓冲就是让写数据操作与刷新操作异步,前端缓冲直接与显示设备交互,后端缓冲存储需要显示的内容。
总结:图形绘制系统的任务流水线
-
-
opengl_图形学详细资料
2012-12-30 18:59:38关于opengl_计算机图形学的详细资料。