opengl入门教程(关于opengl 的问题)
本文目录
关于opengl 的问题
创建 窗口 是 WIN32 的问题吧,Opengl 只是 负责 绘制,光照,纹理等等的处理
OpenGL入门-4
图像存储空间 = 图像的高度 * 图像宽度 * 每个像素的字节数
RGB(8位),宽度:199像素点。图片每行需要多少存储空间? 199 * 3 * 8 = 597字节
tga(纹理文件)。1个字节1个字节。 OpenGL纹理文件:.tga文件.
OpenGL ES! 压缩图片文件.png/jpeg压缩 当纹理来使用。
//改变像素存储方式 void glPixelStorei(GLenum pname, GLint param); //恢复像素存储方式 void glPixelStoref(GLenum pname,GLfloat param); //举例: //参数1:GL_UNPACK_ALTGNMENT 指定OpenGL 如何从数据缓存区中解包图像数据 //参数2:表示参数GL_UNPACK_ALIGNMENT 设置的值
//GL_UNPACK_ALIGNMENT 指内存中每个像素行起点的排列请求,允许设置为1(byte排列)、2(排列为偶数btye的行)、4(字word排列)、8(行从双字节边界开始) glPixelStorei(GL_UNPACK_ALIGNMENT,1);
参数1:x,矩形左下角的窗口坐标 参数2:y,矩形左下角的窗口坐标 参数3:width,矩形的宽,以像素为单位 参数4:height,矩形的高,以像素为单位 参数5:format,OpenGL的像素格式 参数6:type,解释参数pixels指向的数据,告诉OpenGL 使用缓存区中的什么数据类型来存储颜色分量,像素数据的数据类型。 参数7:pixels,指向图形数据的指针 void glReadPixls(GLint x, GLint y, GLSizei width, GLSizei height, GLenum format, GLenum type, const void *pixels);
glReadBuffer(mode); -》指定读取的缓存 glWriteBuffer(mode); -》 指定写入的缓存
void glTexImage1D(GLenum target,GLint level, GLint internalformat,GLsizei width, GLint border, GLenum format, GLenum type, void *data);
void glTextImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint bordr, GLenum format, GLenum type,void *data);
void glTextImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,GLsizei depth, GLint bordr, GLenum format, GLenum type,void *data);
void glTexSubImage1D(GLenum target, GLint level, GLint xOffset, GLsizei width, GLenum format, GLenum type, const GLvoid *data);
void glTexSubImage2D(GLenum target, GLint level, GLint xOffset,GLint yOffset,GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data);
void glTexSubImage3D(GLenum target, GLint level, GLint xOffset,GLint yOffset,GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data);
void glCopyTexSubImage1D(GLenum target, GLint level, GLint xOffset, GLint x, GLint y, GLsizei width);
void glCopyTexSubImage2D(GLenum target,GLint level,GLint xOffset, GLint yOffset,GLint x, GLint y,GLsizei width, GLsizei height);
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glCopyTexImage1D(GLenum target, GLint level, GLenum internalformt, GLint x, GLint y, GLsizei width, GLint border);
void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformt, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
x,y在颜色缓存区中指定了开始读取纹理数据的位置;缓存区里的数据,是源缓存区通过glReadBuffer设置的。
//使用函数分配纹理对象 //指定纹理对象的数量 和 指针(指针指向一个屋符号整形数组,由纹理对象标识符填充)。 void glGenTextures(GLsizei n, GLint *texTures);
//绑定纹理状态 //参数target: GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D //参数texture:需要绑定的纹理对象 void glBindTexture(GLenum target, GLunit texture);
//删除绑定纹理对象 //纹理对象 以及 纹理对象指针(指针指向一个无符号整形数组,由纹理对象标识符填充)。 void glDeleteTexture(GLsizei n, GLint *textures);
//测试纹理对象是否有效 //如果texture是一个已经分配空间的纹理对象。那么这个函数会返回GL_TRUE,否则返回GL_FALSE. GLboolean glIsTexture(GLuint texture);
glTexParameterf(GLenum target, GLenum pname, GLFloat param); glTexParameteri(GLenum target, GLenum pname, GLint param); glTexParameterfv(GLenum target, GLenum pname,GLint param); glTexParameteriv(GLenum target, GLenum pname, GLint *param);
参数1:target,指定这些参数将要应用在那个纹理模式上,比如GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D。 参数2:pname,指定需要设置那个纹理参数。 参数3:param,设定特定的纹理参数值。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST); //纹理缩小时,使用邻近过滤
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GLLINEAR) //纹理放大时,使用线性过滤
参数1:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D 参数2:GL_TEXTURE_WRAP_S、GL_TEXTURE_T、GL_TEXTURE_R,针对s,t,r坐标 参数3:GL_REPEAT、GL_CLAMP、GL_CLAMP_TO_EDGE、GL_CLAMP_TO_BORDER GL_REPEAT:OpenGL在纹理坐标超过1.0的方向上对纹理进行重复; GL_CLAMP:所需要的纹理单元取自纹理边界或TEXTURE_BORDER_COLOR. GL_CLAMP_TO_EDGE环绕模式强制对范围之外的纹理坐标沿着合法的纹理单元的最后一行或者最后一列来进行采样。 GL_CLAMP_TO_BORDER:在纹理坐标在0.0到1.0范围之外的只使用边界纹理单元。边界纹理单元是作为围绕基本图像的额外的行和列,并与基本纹理图像一起加载的。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAR_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP_TO_EDGE);
OpenGL像素格式
像素数据的数据类型
//设置mip贴图基层 glTexParamteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0); //设置mip贴图最大层 glTexParamteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_LEVEL,0);
GLint comFlag; //判断纹理是否被成功压缩 glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_COMPRESSED,&comFlag);
//根据选择的压缩纹理格式,选择最快、最优、自行选择的算法方式选择压缩格式 glHint(GL_TEXTURE_COMPRESSION_HINT,GL_FASTEST); glHint(GL_TEXTURE_COMPRESSION_HINT,GL_NICEST); glHint(GL_TEXTURE_COMPRESSION_HINT,GL_DONT_CARE);
void glCompressedTexImage1D(GLenum target,GLint level,Glenum internalFormat,GLsizei width,GLint border, GLsizei imageSize, void *data);
void glCompressedTexImage2D(GLenum target,GLint level, GLenum internalFormat, GLsizei width, GLint height, GLint border, GLsizei imageSize, void *data);
void glCompressedTextImage3D(GLenum target, Glint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,GLint border, GLsizei imageSize,void *data);
target: GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D. level:指定所加载的mip贴图层次。一般我们都把这个参数设置为0. internalformat:每个纹理单元中存储多少颜色成分 width、height、depth参数:指加载纹理底层的宽度、高度、深度。注意:这些值必须是2的整数次方。(这是因为旧版本上遗留下的一个要求。当然现在已经可以支持不是2的整数次方。但是开发者还是习惯使用2的整数次方去设置参数) border参数:允许为纹理贴图指定一个边界宽度。 format、type、data参数:与我们在讲glDrawPixels函数对应的参数相同
(20分)求openGL较为简单的入门教程,适合于自学,谢谢
如果你要下载电子书学习:OpenGL电子书籍集:***隐藏网址***推荐利用网站学习:***隐藏网址***关键是里面的教程1-48课如果你看不懂英文nehe教程,则搜索下载人们翻译的中文教程NeHe.chm找不到的话,告诉我你的邮箱,我给你发。
OpenGL入门 - 1
简单来说就是实现图形的底层渲染 A. 比如在游戏开发中,对于游戏场景/游戏人物的渲染 B. 比如在音视频开发中,对于视频解码后的数据渲染 C. 比如在地图引擎,对于地图上的数据渲染 D. 比如在动画中,实现动画的绘制 E. 比如在视频处理中,对于视频加上滤镜效果 OpenGL/OpenGL ES/Metal 在任何项目中解决问题的本质就是利用 GPU 芯片来高效渲染图形图像。 图形 API 是 ios 开发者唯一接近 GPU 的方式。
OpenGL 阶段:
OpenGL ES 阶段:
Metal 阶段:
固定管线/存储着⾊器
顶点数据是由CPU/GPU来处理? 顶点缓存区:区域(不在内存!-》显卡显存中。) 片元着色器 像素着色器 片元函数 GPUImage
标准化设备坐标系(NDC)
物体/世界/照相机空间-》右手系 规范化设备坐标:左手系。 x,y,z =》 0,1,2 注意OpenGL中坐标系 OpenGL中的物体,世界,照相机坐标系都属于右手坐标系,而规范化设备坐标系(NDC)属于左手坐标系。笼统的说OpenGL使用右手坐标系是不合适的
OpenGL希望每次顶点着色后,我们的可见顶点都为标准化设备坐标系 (Normalized Device Coordinate, NDC)。也就是说每个顶点的x,y,z都应该在-1到1之间,超出这个范围的顶点将是不可见的。 通常情况下我们会自己设定一个坐标系范围,之后再在顶点着色器中将这些坐标系变换为标准化设备坐标,然后这些标准化设备坐标传入光栅器(Rasterizer),将他们变换为屏幕上的二维坐标和像素。
将坐标变换为标准化设备坐标,接着再转化为屏幕坐标的过程通常是分布进行的,也是类似于流水线那样。在流水线中,物体的顶点在最终转化为屏幕坐标之前还会被变换到多个坐标系系统(Coordinate System)。将物体的坐标变到几个过渡坐标系(Intermediate Coordinate System)的优点在于 在这些特定的坐标系统中,一些操作或运算更加方便和容易,这一点很快就变得明显。对我们来说比较重要的总共有5个不同的坐标系统。
这是一个顶点在最终被转化为片段之前需要经历的所有不同的状态。为了将坐标从一个坐标系变换到另一个坐标系,我们需要用到几个变换矩阵,最重要的几个分别是 模型(Model)、观察(View)、投影(Projection)三个矩阵。 物体顶点的起始坐标在局部空间(Local Space),这里称为局部坐标(Local Coordinate),他在之后在变成世界坐标(World Coordinate),观察坐标(View Coordinate),裁剪坐标(Clip Coordinate),并最后转为屏幕坐标(Screen Coordinate) 的形式结束。
物体坐标系: 每个物体都有他独立的坐标系,当物理移动或者改变方向时。该物体相关联的坐标系将随之移动或改变方向。 物体坐标系是以物体本身而言,比如,我先向你发指令,”向前走一步“,是向你的物体坐标系发指令。我并不知道你会往哪个绝对的方向移动。比如说,当你开车的时候,有人会说向左转,有人会说向东。但是,向左转是物体坐标系的概念,而向东则是世界坐标系概念。 在某种情况下,我们可以理解物体坐标系为模型坐标系。因为模型顶点的坐标都是在模型坐标系中描述的。
照相机坐标系: 照相机坐标系是和观察者密切相关的坐标系。照相机坐标系和屏幕坐标系相似,差别在于照相机坐标系处于3D空间中,而屏幕坐标系在2D平面里。
为什么要引入惯性坐标系? 因为物体坐标系转换到惯性坐标系只需要旋转,从惯性坐标系转换到世界坐标系只需要平移。
OpenGL最终的渲染设备是2D的,我们需要将3D表示的场景转换为最终的2D形式,前面使用模型变换和视觉变换将物体坐标转到照相机坐标系后,需要进行投影变换,将坐标从照相机坐标系转换为裁剪坐标系,经过透视除法后,变换到规范化设备坐标系(NDC),最后进行视口变换后,3D坐标才变换到屏幕上的2D坐标,这个过程入下图:
在上面的图中, 注意,OpenGL只定义了裁剪坐标系、规范化设备坐标系、屏幕坐标系,而局部坐标系、世界坐标系、照相机坐标系都是为了方便用户设计而自定义的坐标系,他们的关系如下图:
OpenGL 然后对裁剪坐标执行透视除法从而将他们变换到标准化设备坐标。 OpenGL 会使用glViewPort内部的参数来将标准化设备坐标映射到屏幕坐标,每个坐标关联一个屏幕上的点。这个过程称为视口变换
局部坐标系(模型坐标系)是为了方便构造模型而设立的坐标系,建立模型时我们无需关心最终对象显示在屏幕那个位置。 模型变换的主要目的是通过变换使得用顶点属性定义或者3d建模软件构造的模型,能够按照需要,通过缩小、平移等操作放置到场景中合适的位置, 通过模型变换后,物体放置在一个全局的世界坐标系中,世界坐标系是所有物体交互的一个公共坐标系
视变换是为了方便观察场景中物体而建立的坐标系,在这个坐标系中相机是个假设的概念,是为了便于计算而引入的。相机坐标系中的坐标,就是从相机的角度来解释世界坐标系中的位置
OpenGL中相机始终位于原点,指向 -Z轴,而以相反的方式来调整场景中物体,从而达到相同的观察效果。例如要观察-Z轴方向的一个立方体的右侧面,可以有两种方式:
GLShaderManager的初始化 GLShaderManager shaderManager; shaderManager.InitializeStockShaders();
更多文章:
asp编程培训(ASP.NET开发实战1200例的内容简介)
2024年7月9日 22:28
sessionid怎么生成的(httpsession中的SessionID是如何生成的)
2024年7月16日 08:46
oracle怎么解锁用户(在Oracle11g中给scott用户解锁)
2024年4月20日 18:15
鼠标滑过特效(鼠标划过图片的css特效是否必须有div的支持才能使用)
2024年7月24日 00:02
vc2010注册密钥(Microsofe office2010激活密钥)
2023年12月23日 18:40
oracle存储过程调用存储过程(oracle数据库调用存储过程)
2024年7月18日 17:40
lantern怎么读(lantern怎么读 lantern如何读)
2024年7月15日 15:27
网页制作模板之家(做个模板大家用!教你如何自己制作PPT模板及使用模板方法图文介绍)
2024年7月23日 04:47
android 瀑布流布局(RecyclerView详解(四):LayoutManager布局管理器)
2024年7月24日 07:41