粗糙的世界:Jeff Molofee(NeHe) 的 OPENGL 教程-第十课

OpenGL 通过Nehe教程改编 漫游3D场景 粗糙的世界 基于Nehe教程第十课粗糙的世界 继续完善的 漫游场景为一个仓库,有两个铁门,仓库两边堆着箱子。场景中的墙壁是通过读取txt文件中的数据构造的,想做修改的话可以改变txt文本做出你自己想要的简单的世界 立即下载

Jeff Molofee(NeHe) 的 OPENGL 教程

第十课

Translated by
CKER




  这一课是由Lionel Brits (βtelgeuse)所写的。在本课中我们只对增加的代码做解释。当然只添加课程中所写的代码,程序是不会运行的。如果您有兴趣知道下面的每一行代码是如何运行的话,请下载完整的源码,并在浏览这一课的同时,对源码进行跟踪。

 
好了现在欢迎来到名不见经传的第十课。到现在为止,您应该有能力创建一个旋转的立方体或一群星星了,对3D编程也应该有些感觉了吧?但还是请等一下!不要立马冲动地要开始写个Quake
IV,好不好...:)。只靠旋转的立方体还很难来创造一个可以决一死战的酷毙了的对手....:)。现在这些日子您所需要的是一个大一点的、更复杂些的、动态3D世界,它带有空间的六自由度和花哨的效果如镜像、入口、扭曲等等,当然还要有更快的帧显示速度。这一课就要解释一个基本的3D世界"结构",以及如何在这个世界里游走。

数据结构


当您想要使用一系列的数字来完美的表达3D环境时,随着环境复杂度的上升,这个工作的难度也会随之上升。出于这个原因,我们必须将数据归类,使其具有更多的可操作性风格。在程序清单头部出现了sector(区段)的定义。每个3D世界基本上可以看作是sector(区段)的集合。一个sector(区段)可以是一个房间、一个立方体、或者任意一个闭合的区间。


typedef struct tagSECTOR      // 创建Sector区段结构
{
int numtriangles;
// Sector中的三角形个数
TRIANGLE* triangle;
// 指向三角数组的指针
} SECTOR;
// 命名为SECTOR








 一个sector(区段)包含了一系列的多边形,所以下一个目标就是triangle(我们将只用三角形,这样写代码更容易些)。


typedef struct tagTRIANGLE     // 创建Triangle三角形结构
{
VERTEX vertex[3];
// VERTEX矢量数组,大小为3
} TRIANGLE;
// 命名为 TRIANGLE







三角形本质上是由一些(两个以上)顶点组成的多边形,顶点同时也是我们的最基本的分类单位。顶点包含了OpenGL真正感兴趣的数据。我们用3D空间中的坐标值(x,y,z)以及它们的纹理坐标(u,
v)来定义三角形的每个顶点。


typedef struct tagVERTEX      // 创建Vertex顶点结构
{
float x, y, z;
// 3D 坐标
float u, v;
// 纹理坐标
} VERTEX;
// 命名为VERTEX








载入文件


在程序内部直接存储数据会让程序显得太过死板和无趣。从磁盘上载入世界资料,会给我们带来更多的弹性,可以让我们体验不同的世界,而不用被迫重新编译程序。另一个好处就是用户可以切换世界资料并修改它们而无需知道程序如何读入输出这些资料的。数据文件的类型我们准备使用文本格式。这样编辑起来更容易,写的代码也更少。等将来我们也许会使用二进制文件。


问题是,怎样才能从文件中取得数据资料呢?首先,创建一个叫做SetupWorld()的新函数。把这个文件定义为filein,并且使用只读方式打开文件。我们必须在使用完毕之后关闭文件。大家一起来看看现在的代码:



// 先前的定义: char* worldfile = "data//world.txt";
void SetupWorld()
// 设置我们的世界
{
FILE *filein;
// 工作文件
filein = fopen(worldfile, "rt");
// 打开文件

...
(读入数据资料)
...

fclose(filein);
// 关闭文件
return;
// 返回
}
张彩放 0573-6082032(H)
 









下一个挑战是将每个单独的文本行读入变量。这有很多办法可以做到。一个问题是文件中并不是所有的行都包含有意义的信息。空行和注释不应该被读入。我们创建了一个叫做
readstr()的函数。这个函数会从数据文件中读入一个有意义的行至一个已经初始化过的字符串。下面就是代码:


void readstr(FILE *f,char *string)     // 读入一个字符串
{
do
// 循环开始
{
fgets(string, 255, f);
// 读入一行
} while ((string[0] == '/') || (string[0] == '/n'));
// 考察是否有必要进行处理
return;
// 返回
}








下一步我们读入区段数据。这一课将只处理一个区段,不过实现一个多区段引擎也很容易。让我们将注意力转回SetupWorld()。程序必须知道区段内包含了多少个三角形。我们在数据文件中以下面这种形式定义三角形数量:
NUMPOLLIES n

接下来是读取三角形数量的代码:


int numtriangles;       // 区段中的三角形数量
char oneline[255]; // 存储数据的字符串
...
readstr(filein,oneline);
// 读入一行数据
sscanf(oneline, "NUMPOLLIES %d/n", &numtriangles); // 读入三角形数量








余下的世界载入过程采用了相似的方法。接着,我们对区段进行初始化,并读入部分数据:


// 先前的定义: SECTOR sector1;
char oneline[255];
// 存储数据的字符串
int numtriangles;
// 区段的三角形数量
float x, y, z, u, v;
// 3D 和 纹理坐标
...
sector1.triangle = new TRIANGLE[numtriangles];
// 为numtriangles个三角形分配内存并设定指针
sector1.numtriangles = numtriangles;
// 定义区段1中的三角形数量
// 遍历区段中的每个三角形
for (int triloop = 0; triloop < numtriangles; triloop++)
// 遍历所有的三角形
{
// 遍历三角形的每个顶点
for (int vertloop = 0; vertloop < 3; vertloop++)
// 遍历所有的顶点
{
readstr(filein,oneline);
// 读入一行数据
// 读入各自的顶点数据
sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v);
// 将顶点数据存入各自的顶点
sector1.triangle[triloop].vertex[vertloop].x = x;
// 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 x =x
sector1.triangle[triloop].vertex[vertloop].y = y;
// 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 y =y
sector1.triangle[triloop].vertex[vertloop].z = z;
// 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 z =z
sector1.triangle[triloop].vertex[vertloop].u = u;
// 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 u =u
sector1.triangle[triloop].vertex[vertloop].v = v;
// 区段 1, 第 triloop 个三角形, 第 vertloop 个顶点, 值 e=v
}
}








数据文件中每个三角形都以如下形式声明:
X1 Y1 Z1 U1 V1
X2 Y2 Z2 U2 V2
X3 Y3 Z3 U3 V3

显示世界



现在区段已经载入内存,我们下一步要在屏幕上显示它。到目前为止,我们所作过的都是些简单的旋转和平移。但我们的镜头始终位于原点(0,0,0)处。任何一个不错的3D引擎都会允许用户在这个世界中游走和遍历,我们的这个也一样。实现这个功能的一种途径是直接移动镜头并绘制以镜头为中心的3D环境。这样做会很慢并且不易用代码实现。我们的解决方法如下:




  1. 根据用户的指令旋转并变换镜头位置。
  2. 围绕原点,以与镜头相反的旋转方向来旋转世界。(让人产生镜头旋转的错觉)
  3. 以与镜头平移方式相反的方式来平移世界(让人产生镜头移动的错觉)。

这样实现起来就很简单.
下面从第一步开始吧(平移并旋转镜头
)。



if (keys[VK_RIGHT])       //右方向键按下了么?
{
yrot -= 1.5f;
// 向左旋转场景
}



if (keys[VK_LEFT])
// 左方向键按下了么?
{
yrot += 1.5f;
// 向右侧旋转场景
}



if (keys[VK_UP])
// 向上方向键按下了么?
{
xpos -= (float)sin(heading*piover180) * 0.05f;
// 沿游戏者所在的X平面移动
zpos -= (float)cos(heading*piover180) * 0.05f;
// 沿游戏者所在的Z平面移动
if (walkbiasangle >= 359.0f)
// walkbiasangle>=359?
{
walkbiasangle = 0.0f;
// 将 walkbiasangle 设为l 0
}
else
// 否则
{
walkbiasangle+= 10;
// 如果 walkbiasangle < 359 ,则增加 10
}
walkbias = (float)sin(walkbiasangle * piover180)/20.0f;
// 使游戏者产生跳跃感
}



if (keys[VK_DOWN])
// 向下方向键按下了么?
{
xpos += (float)sin(heading*piover180) * 0.05f;
// 沿游戏者所在的X平面移动
zpos += (float)cos(heading*piover180) * 0.05f;
// 沿游戏者所在的Z平面移动
if (walkbiasangle <= 1.0f)
// walkbiasangle<=1?
{
walkbiasangle = 359.0f;
// 使 walkbiasangle 等于 359
}
else
// 否则
{
walkbiasangle-= 10;
// 如果 walkbiasangle > 1 减去 10
}
walkbias = (float)sin(walkbiasangle * piover180)/20.0f;
// 使游戏者产生跳跃感
}








 这个实现很简单。当左右方向键按下后,旋转变量yrot
相应增加或减少。当前后方向键按下后,我们使用sine和cosine函数重新生成镜头位置(您需要些许三角函数学的知识:-)。Piover180
是一个很简单的折算因子用来折算度和弧度。

接着您可能会问:walkbias是什么意思?这是NeHe的发明的单词:-)。基本上就是当人行走时头部产生上下摆动的幅度。我们使用简单的sine正弦波来调节镜头的Y轴位置。如果不添加这个而只是前后移动的话,程序看起来就没这么棒了。


现在,我们已经有了下面这些变量。可以开始进行步骤2和3了。由于我们的程序还不太复杂,我们无需新建一个函数,而是直接在显示循环中完成这些步骤。


int DrawGLScene(GLvoid)      // 绘制 OpenGL 场景
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 清除 场景 和 深度缓冲
glLoadIdentity();
// 重置当前矩阵
GLfloat x_m, y_m, z_m, u_m, v_m;
// 顶点的临时 X, Y, Z, U 和 V 的数值
GLfloat xtrans = -xpos;
// 用于游戏者沿X轴平移时的大小
GLfloat ztrans = -zpos;
// 用于游戏者沿Z轴平移时的大小
GLfloat ytrans = -walkbias-0.25f;
// 用于头部的上下摆动
GLfloat sceneroty = 360.0f - yrot;
// 位于游戏者方向的360度角
int numtriangles;
// 保有三角形数量的整数
glRotatef(lookupdown,1.0f,0,0);
// 上下旋转
glRotatef(sceneroty,0,1.0f,0);
// 根据游戏者正面所对方向所作的旋转

glTranslatef(xtrans, ytrans, ztrans);
// 以游戏者为中心的平移场景
glBindTexture(GL_TEXTURE_2D, texture[filter]);
// 根据 filter 选择的纹理

numtriangles = sector1.numtriangles;
// 取得Sector1的三角形数量

// 逐个处理三角形
for (int loop_m = 0; loop_m < numtriangles; loop_m++)
// 遍历所有的三角形
{
glBegin(GL_TRIANGLES);
// 开始绘制三角形
glNormal3f( 0.0f, 0.0f, 1.0f);
// 指向前面的法线
x_m = sector1.triangle[loop_m].vertex[0].x;
// 第一点的 X 分量
y_m = sector1.triangle[loop_m].vertex[0].y;
// 第一点的 Y 分量
z_m = sector1.triangle[loop_m].vertex[0].z;
// 第一点的 Z 分量
u_m = sector1.triangle[loop_m].vertex[0].u;
// 第一点的 U 纹理坐标
v_m = sector1.triangle[loop_m].vertex[0].v;
// 第一点的 V 纹理坐标
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
// 设置纹理坐标和顶点

x_m = sector1.triangle[loop_m].vertex[1].x;
// 第二点的 X 分量
y_m = sector1.triangle[loop_m].vertex[1].y;
// 第二点的 Y 分量
z_m = sector1.triangle[loop_m].vertex[1].z;
// 第二点的 Z 分量
u_m = sector1.triangle[loop_m].vertex[1].u;
// 第二点的 U 纹理坐标
v_m = sector1.triangle[loop_m].vertex[1].v;
// 第二点的 V 纹理坐标
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
// 设置纹理坐标和顶点

x_m = sector1.triangle[loop_m].vertex[2].x;
// 第三点的 X 分量
y_m = sector1.triangle[loop_m].vertex[2].y;
// 第三点的 Y 分量
z_m = sector1.triangle[loop_m].vertex[2].z;
// 第三点的 Z 分量
u_m = sector1.triangle[loop_m].vertex[2].u;
// 第二点的 U 纹理坐标
v_m = sector1.triangle[loop_m].vertex[2].v;
// 第二点的 V 纹理坐标
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
// 设置纹理坐标和顶点
glEnd();
// 三角形绘制结束
}
return TRUE;
// 返回
}










搞定!我们已经完成了自己的第一帧画面。这绝对算不上什么Quake,但咳...,我们绝对也不是Carmack或者Abrash。运行程序时,您可以按下F、B、
PgUp 和 PgDown 键来看看效果。PgUp /
PgDown简单的上下倾斜镜头。如果NeHe决定保留的话,程序中使用的纹理取自于我的学校ID证件上的照片,并且做了浮雕效果....:)。


现在您也许在考虑下一步该做什么。但还是不要考虑使用这些代码来实现完整的3D引擎,写这个程序的目的也并非如此。您也许希望您的游戏中不止存在一个Sector,尤其是实现类似入口这样的部分,您还可能需要使用多边形(超过3个顶点)。程序现在的代码实现允许载入多个Sector并剔除了背面(背向镜头不用绘制的多边形)。将来我会写个这样的教程,但这需要更多的数学知识基础。

NeHe (05/01/00):
我已经为教程中引用的每一行代码加上了注释。希望这对您有意义。在此之前只有少数几行代码作了注释...:)



如果对教程和代码有任何问题(这是我的第一个教程,我的解释也可能含混不清),请别犹豫 email 给我 (iam@cadvision.com)。



Lionel Brits
(βtelgeuse)

以下是源码的下载连接:

* DOWNLOAD Visual C++ Code For This Lesson.

* DOWNLOAD Visual C++ / OpenIL Code For This Lesson.
( Conversion by Denton Woods )

* DOWNLOAD Visual Basic Code For This Lesson.
( Conversion by Jarred Capellman )

* DOWNLOAD Visual Basic Code For This Lesson.
( Conversion by Ross Dawson )

* DOWNLOAD Cygwin (FREE Language) Code For This Lesson.
( Conversion by Stephan Ferraro )

* DOWNLOAD MASM Code For This Lesson.
( Conversion by Nico (Scalp) )

* DOWNLOAD Irix Code For This Lesson.
( Conversion by Rob Fletcher )

* DOWNLOAD Linux/GLX Code For This Lesson.
( Conversion by Mihael Vrbanec )

* DOWNLOAD Linux Code For This Lesson.
( Conversion by Richard Campbell )

* DOWNLOAD Visual Fortran Code For This Lesson.
( Conversion by Jean-Philippe Perois )

* DOWNLOAD Delphi Code For This Lesson.
( Conversion by Marc Aarts )

* DOWNLOAD Mac OS Code For This Lesson.
( Conversion by Anthony Parker )

* DOWNLOAD Power Basic Code For This Lesson.
( Conversion by Angus Law )

* DOWNLOAD Java Code For This Lesson.
( Conversion by Darren Hodges )

* DOWNLOAD MingW32 & Allegro Code For This Lesson.
( Conversion by Peter Puck )

* DOWNLOAD Borland C++ Builder 4.0 Code For This Lesson.
( Conversion by Patrick Salmons )




NeHe OpenGL 源码+教程(part10) NeHe OpenGL 源码+教程(part10) NeHe OpenGL 源码+教程(part10) 立即下载

相关推荐

Jeff Molofee(NeHe) 的 OPENGL 教程

Jeff Molofee(NeHe) 的 OPENGL 教程,详细的讲解助你学习OPENGL。

OpenGL 第一个多边形

 文:Lesson 2: Your First Polygon译 者:CKER   第一课中,我教您如何创建一个OpenGL窗口。这一课中,我将教您如何创建三角形和四边形。我们讲使用来创建GL_TRIANGLES一个三角形,GL_QUADS来创建一个四边形。  在第一课代码的基础上,我们只需在DrawGLScene()过程中增加代码。下面我重写整个过程。如果您计划修改上节课的代码,只需用下面的代码

痞子龙3D编程 1837

深度学习---双层神经网络中矩阵的运算及其含义记录

深度学习---双层神经网络中矩阵的运算及其含义记录神经网络的正向传播与反向传播正向传播第一层的权重矩阵第一层的输入矩阵Z^1^ = W^1^X^1^ + b^1^A^1^ = σ(Z^1^)第二层的权重矩阵第二层的输入矩阵Z^2^ = W^2^A^1^ + b^2^反向传播dz^2^ = A^2^ - Ydw^2^ = 1/n dz^2^A^1T^db^2^ = 1/n np.sum(dz^2...

qq_43228441的博客 3744

粗糙的世界:Jeff Molofee(NeHe) 的 OPENGL 教程-第十课 (转)

粗糙的世界:Jeff Molofee(NeHe) 的 OPENGL 教程-第十课 (转)[@more@] Jeff Molofee(NeHe) 的 OPENGL 教程 第十课 Translated by CKER .N...

ciya3282的博客 313

探索Three.js:利用ShaderMaterial实现动态着色器特效

本文深入探讨了Three.js中ShaderMaterial的应用,指导开发者利用GLSL编写自定义着色器实现动态特效。文章从核心概念GLSL、Uniforms与Attributes讲起,通过创建动态颜色变化平面的实战案例,逐步进阶到实现波纹扩散与动态光影等高级效果,并提供了性能优化与调试技巧,帮助读者掌握创建高性能WebGL视觉特效的关键技能。

weixin_29250403的博客 201

【Ablation Studies 理解】深度学习模型组件的对比实验/性能分析

Ablation Study 用于检测深度学习/机器学习模型中各部分构件对于整体的重要性。 可以理解为为:组件\tricks重要性测试、组件性能系统性分析、控制变量法、组件去除对比实验、性能敏感性测试、性能因子分析等 Ablation Studies 一些新颖的深度学习模型在论文中都会进行AblationStudy,这部分的主要意义在于系统性的移除模型中的各种组件/trick等因子或者是创新的...

TomRen 4588

JeffMolofee(NeHe)的OPENGL教程-第一课[2]-InitGL

接下的代码段中,我们将对OpenGL进行所有的设置。我们将设置清除屏幕所用的颜色,打开深度缓存,启用smooth shading(阴影平滑),等等。这个例程直到OpenGL窗口创建之后才会被调用。此过程将有返回值。但我们此处的初始化没那么复杂,现在还用不着担心这个返回值。int InitGL(GLvoid) // 此处开始对OpenGL进行所有设置 {下一行启用smooth shading(阴影...

weixin_30457881的博客 233

【老生谈算法】可视化通道流中瞬时涡量场的算法实现与MATLAB源码分析——瞬时涡量场

本文旨在探讨可视化通道流中瞬时涡量场的方法,并通过MATLAB编程实现这一过程。涡量场作为描述流体旋涡强度和方向的重要物理量,对于理解复杂流体运动具有重要意义。本文首先介绍了涡量场的基本概念,随后详细阐述了从测量数据收集到涡量场可视化的完整流程,并给出了相应的MATLAB源码。通过实际运行该源码,我们展示了涡量场的可视化结果,并讨论了其在流动结构识别和动力学行为理解中的应用。关键词: 涡量场;流体运动;MATLAB;可视化;PIV一、引言。

m0_53407570的博客 1124

新手上路:Jeff Molofee(NeHe) 的 OPENGL 教程-第一课

Jeff Molofee(NeHe) 的 OPENGL 教程#1<!--font { font-family: Arial; line-height: 140%; font-size: 12pt; margin-top: 1; margin-bottom: 1 }body { font-famil

没吃过猪肉,光看见猪跑啦.................... 5747

开源人形机器人硬件生态:关键技术、产业链与低成本突破 | OpenLoong 社区线下分享会

本文将深入探讨人形机器人硬件平台的关键技术、产业链与核心部件以及降低成本的策略。从硬件平台的核心技术,到机器人核心零部件的详细介绍,再到产业链各环节的协同发展以及实现低成本化的创新思路,将一同剖析人形机器人迈向广泛应用所面临的挑战与机遇,展望其未来的发展趋势,为开发者和相关从业者提供一些参考与启示。

OpenLoong_的博客 2419

Qt入门教程【数据类型篇】数值类型

Qt中的数值类型

小鱼酱的博客 1万+

OpenGL 漫游3D世界

原 文:Lesson 10: Loading And Moving Through A 3D World译 者:CKER  这一课是由Lionel Brits(βtelgeuse)所写的。在本课中我们只对增加的代码做解释。当然只添加课程中所写的代码,程序是不会运行的。如果您有兴趣知道下面的每一行代码是如何运行的话,请下载完整的源码,并在浏览这一课的同时,对源码进行跟踪。  好了,现在欢迎来到名

痞子龙3D编程 2896

vue - 网站接入微信扫码登录功能详细教程,完整详细流程及完整功能示例源代码(附常见问题的解决方案与二维码样式修改方案)

vue.js项目植入微信登录,vue网页项目怎么做微信扫码登录,VUE项目中的微信扫码登录,VUE中最简单的js调用微信扫一扫功能,vue:如何设计网页的微信扫码登录功能,微信扫码功能官方文档,通过vue方式实现二维码扫码功能,vue调用微信扫码,vue H5 调用微信扫描二维码,Vue前端实现微信扫码登录,vue-wxlogin 微信授权登录组件,网站引入的微信登录框如何修改宽高或其他样式,wxlogin 组件插件怎么改变宽高,vue-wxlogin组件怎么自定义样式,微信网页授权,vue调用微信JSDK

✅ 精选推荐文章 6364

Andriod OpenGL 教程 10 - 3D世界

关键字: android OpenGL 移动开发 教程           到目前为止,我们已经学会了如何创建3D物体,给物体着色,在空间中打开灯光,给物体贴上纹理等基本功能。并有能力创建一个旋转的立方体或者一群闪烁的星星了,对3D编程也有了一定的了解。          这一课,我们将演示如何加载3D世界,并在3D世界中遨游。为此我们采用一个文本文件来定义我们的3D世界。这样可以方便地加载

seniorwizard的专栏 1328

CODESYS无扰切换PID(ST源代码)

/运行信号//手自动切换//设置值、目标值yk : REAL;// 实际值、反馈信号;// 开环给定值;// 比例增益;// 积分时间 单位S;Td : REAL;// 微分时间 单位S;//采样时间 单位S// 滤波时间 单位S;//中断周期 默认10msEND_VARVAR_OUTPUT//uk : REAL;//控制器输出;//上一时刻的实际值;uDk : REAL;

RXXW_Dor的博客 1400

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Android OpenGL(3)

前面介绍了Android OpenGL的开发基础,绘制了一个3D的物体,在立体空间控制一个3D对象,但如何来构建一个3D的场景呢?接下来就讲讲怎样去完成一个3D世界的场景吧。 首先,我们应该明白的是,任何一个复杂的对象都是由一些简单的三角形构成的,所以在创建一个复杂的3D场景之前,要先定义一个场景的数据结构。三角形本质上是由一些(两个以上)顶点组成的多边形,顶点是最基本的分类单位,它包含...

acxm45824的博客 225

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

NeHe OpenGL Lesson 10 – Loading And Moving Through A 3D World

This sample shows us a small proto-type how to write a game with OpenGL. This is the first lesson that abandon using hard code game world. It seems like a engine, a small one. What is an engine?...

abc2912333的博客 213

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

OpenSceneGraph实现的NeHe OpenGL教程 - 第十课

简介 本文实现从外部文件中加载场景,并进行简单的场景漫游操作。 一般来说,场景都是通过外部建模工具生成的,然后再通过osg进行读取加载,一方面直接通过顶点生成场景对程序员来说十分困难,另一方面通过外部建模的方式加载场景使得程序变得十分灵活。像我们玩的CS游戏就是通过加载一些地图文件实现在不同的场景之中战斗。 实现 在NeHe教程中实现的过程介绍的非常清楚,不熟悉

ALLENJIAO的专栏 812

OpenGL教程之看起来很棒的雾

Jeff Molofee(NeHe)的OpenGL教程- 看起来很棒的雾原 文:Lesson 16: Cool Looking Fog译 者:sakura  难道你不想把“雾”加入到你的OpenGL程序中吗?那么在这课里我将要为您展现如何实现这项功能。这是我第一次写教程,而且相对来说我也是OpenGL/C++程序设计新手,所以如果您发现有什么错误的话,请让我知道。这课的代码是基于第7课的。  

3366

OpenGL教程之着色

Jeff Molofee(NeHe)的OpenGL教程- 着色原 文:Lesson 3: Colors译 者:CKER  上一课中我教给您三角形和四边形的绘制方法。这一课我将教您给三角形和四边形添加2种不同类型的着色方法。使用单调着色(Flat coloring)给四边形涂上固定的一种颜色。使用平滑着色(Smooth coloring)将三角形的三个顶点的不同颜色混合在一起,创建漂亮的色彩混合

3862

OpenGL 着色

原 文:Lesson 3: Colors译 者:CKER  上一课中我教给您三角形和四边形的绘制方法。这一课我将教您给三角形和四边形添加2种不同类型的着色方法。使用单调着色(Flat coloring)给四边形涂上固定的一种颜色。使用平滑着色(Smooth coloring)将三角形的三个顶点的不同颜色混合在一起,创建漂亮的色彩混合。  继续在上节课的DrawGLScene例程上修改。下面将整

痞子龙3D编程 1894

OpenGl中模拟走动效果

模拟走动效果;1、相应VK_UP按键消息,并作出如下处理    if (keys[VK_UP])    {     xpos -= (float)sin(heading*piover180) * 0.05f;     zpos -= (float)cos(heading*piover180) * 0.05f;     if (walkbiasangle >= 359.0f)     {    

skyspark的专栏 1463

漂亮的星星动画:Jeff Molofee(NeHe) 的 OPENGL 教程-第九课

Jeff Molofees OpenGL Windows Tutorial #9<!--font { font-family: Arial; line-height: 180%; font-size: 12pt; margin-top: 2; margin-bottom: 2 }body { font-fam

没吃过猪肉,光看见猪跑啦.................... 1万+

位图波浪:Jeff Molofee(NeHe) 的 OPENGL 教程-第十一课

Jeff Molofee(NeHe) 的 OPENGL 教程 第十一课 Translated by CKER 大家好!对那些想知道我在这里作了些什么的朋友,您可以先按文章的末尾所列出的链接,下载我那毫无意义的Demo看看先!我是bosco,我将尽我所能教您来实现一个以正弦波方式运动的图象。这一课基于NeHe的教程第六课,当然您至少也应该学会了一至六课的知

没吃过猪肉,光看见猪跑啦.................... 3257
上一篇: 漂亮的星星动画:Jeff Molofee(NeHe) 的 OPENGL 教程-第九课
下一篇: 位图波浪:Jeff Molofee(NeHe) 的 OPENGL 教程-第十一课
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值