Opengl绘制我们的小屋(三)纹理绘制
本准备先说光照相关实现,但是发现对那个模型实在看不下去了,于是先绘制纹理。
先看下基本纹理贴上去的显示效果。具体模型图请看上篇文章的实现,这篇只讲纹理实现。
我们常见的纹理绘制差不多如下,先写一个纹理坐标,然后是一个顶点坐标,GL.TexCoord2(1.0f,1.0f);GL.Vectex(1.f,1.f,1.f)。先说一下纹理坐标与顶点坐标的对应处理关系,为了好理解,我们只说二维纹理。先看下图。
我们设置一张16*8的纹理,如上图,我们设置GL.TexCoord2(1.0f,1.0f)就是在(16,8)位置,超出1的部分,会复制超出部分,如上图设置GL.TexCoord(2.0,2.0)就会在图上一共显示四张图,同理我们只要纹理的右下部分四分之一,那坐标应该分别是(1,0.5),(0.5,0.5),(0.5,0)(1,0).
在上个模型中,我们可以看到我们有很多的模型需要纹理贴图,如果采用一般的方法,需要在每个立方体的面上去计算我们相应的纹理坐标,这样花费时间太大,这样我们采用opengl里提供的自动生成纹理。首先要指定以什么样的模式(既什么样的算法)来生成纹理坐标。可以指定几种纹理坐标生成模式:GL_OBJECT_LINEAR, GL_EYE_LINEAR, GL_SPHERE_MAP等。
在这里我们只需要采用最容易理解的纹理生成模式。GL_OBJECT_LINEAR,在这种模式下,指定四个参数,p0,p1,p2,p3,对应顶点(x0,y0,z0,w0),生成的纹理坐标为p0*x0+p1*y0+p2*z0+p3*w0。
我们再来看我们的需求
1。要对立方体的各面自动生成纹理。
2。我们贴地面的,要像砖是一块一块的,而贴墙时,只需要贴一张。如最上图所绘,左下角与右上角分别对应的纹理坐标在贴砖是一块一块的应该是((0,0),(n,m))《m>0,n>0》,而贴墙时应该对应((0,0),(1,1))。
借用上篇的图。
第一点,根据我们的p0*x0+p1*y0+p2*z0+p3*w0算法来看,比如贴地面时,也就是垂直于Y轴时,用到的是图上的(4,5,1,0)这个面。
想象一下对应关系,纹理的S轴坐标对应是1-0这条线,T轴坐标对应的是1-5这条线,那么对应s轴大致如下[x;0.;0.;0],T轴坐标大致如下[0;0.;y;0].各面按照这样得到对应的参数。相关代码如下。
member this.GenTexture(vector:Vector3,ball) =
GL.Enable(EnableCap.TextureGenS)
GL.Enable(EnableCap.TextureGenT)
GL.TexGen(TextureCoordName.S,TextureGenParameter.TextureGenMode,int TextureGenMode.ObjectLinear)
GL.TexGen(TextureCoordName.T,TextureGenParameter.TextureGenMode,int TextureGenMode.ObjectLinear)
let mutable xa = [|.f;.f;.f;.f|]
let mutable xy = [|.f;.f;.f;.f|]
let mutable x,y,z=.f,.f,.f
if ball then z <-0.5f
if vector = Vector3.UnitY || vector = -Vector3.UnitY then
if ball then
x<-1.0f/Vector3.Subtract(v8.[],v8.[]).Length
y<-1.0f/Vector3.Subtract(v8.[],v8.[]).Length
xa <- [|x;.f;.f;z|]
xy <- [|.f;.f;y;z|]
if vector = Vector3.UnitZ || vector = -Vector3.UnitZ then
if ball then
x<-1.0f/Vector3.Subtract(v8.[],v8.[]).Length
y<-1.0f/Vector3.Subtract(v8.[],v8.[]).Length
xa <- [|x;.f;.f;z|]
xy <- [|.f;y;.f;z|]
if vector = Vector3.UnitX || vector = -Vector3.UnitX then
if ball then
x<-1.0f/Vector3.Subtract(v8.[],v8.[]).Length
y<-1.0f/Vector3.Subtract(v8.[],v8.[]).Length
xa <- [|.f;.f;x;z|]
xy <- [|.f;y;.f;z|]
GL.TexGen(TextureCoordName.S,TextureGenParameter.ObjectPlane,xa)
GL.TexGen(TextureCoordName.T,TextureGenParameter.ObjectPlane,xy)
其中ball参数表示贴墙这种一面只帖一张纹理。在ball时,我们可以看到我们的p0,p1,p2,p3,p3=0.5,这是因为我的矩形的画法所导致的(前看上篇所叙),比如我要生成宽为8的立方体,其中我画顶点是x=-4,x=4这种画法,如果不加0.5,那么我的帖图就会是左下到右上是(-0,5,-0,5),(0.5,0.5)这种。
在opengl是状态机模式,记的每画一面打开相应的状态后,在画完后,需要关掉,不然会影响下一部分的贴图。绘制部分的代码如下。
member this.DrawTexTure(ts:int*int*bool,vector:Vector3,indexs:int []) =
let ind,txtId,ball = ts
if txtId <> then
GL.BindTexture(TextureTarget.Texture2D,txtId)
this.GenTexture(vector,ball)
GL.Normal3(vector)
GL.DrawElements(BeginMode.Triangles,,DrawElementsType.UnsignedInt,indexs)
GL.Disable(EnableCap.TextureGenS)
GL.Disable(EnableCap.TextureGenT)
GL.Disable(EnableCap.TextureGenR)
GL.Disable(EnableCap.TextureGenQ)
最后附上源码与可执行文件。操作方式和网游一样,鼠标右键按下加鼠标上下左右移动是视角.EDSF行走。
下一章节会给大家讲到光照的运用。
Opengl绘制我们的小屋(三)纹理绘制的更多相关文章
- Opengl绘制我们的小屋(二)第一人称漫游
这章我们先讲第一人称漫游的实现.在openTK里,我们用函数Matrix4.LookAt(caram.Eye,caram.Target,Vector3.UnitY)来放置摄像机,其中三个参数分别与摄像 ...
- opengl基础学习专题 (三) 多边形绘制的几种样式
题外话 聪明人之所以不会成功,是由于他们缺乏坚韧的毅力. ——艾萨克·牛顿(1643年1月4日—1727年3月31日)英国 也许可以理解为 想更深一步的时候,坚持,努力和聪明缺一不可. 挺直腰杆在此向 ...
- OpenGL ES学习笔记(三)——纹理
首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <OpenGL ES学习笔记( ...
- WebGL简易教程(三):绘制一个三角形(缓冲区对象)
目录 1. 概述 2. 示例:绘制三角形 1) HelloTriangle.html 2) HelloTriangle.js 3) 缓冲区对象 (1) 创建缓冲区对象(gl.createBuffer( ...
- canvas学习总结三:绘制路径-线段
Canvas绘图环境中有些属于立即绘制图形方法,有些绘图方法是基于路径的. 立即绘制图形方法仅有两个strokeRect(),fillRect(),虽然strokezText(),fillText() ...
- OpenGL ES 3.0之Texturing纹理详解(二)
Texture Filtering and Mipmapping 纹理过滤与多级纹理 前面我们已经讲了单个2D图像的2D纹理的介绍,这篇文章主要讲解多级纹理.纹理坐标是用于生成一个2D索引,当放大和缩 ...
- OpenGL学习笔记(四)纹理
目录 要完成的纹理效果 纹理环绕方式 纹理过滤 多级渐远纹理 加载与创建纹理 stb_image库的使用方法 生成纹理对象 应用纹理 纹理单元 参考资料:OpenGL中文翻译 要完成的纹理效果 纹理是 ...
- 【Python 16】分形树绘制4.0(利用递归函数绘制分形树fractal tree)
1.案例描述 树干为80,分叉角度为20,树枝长度小于5则停止.树枝长小于30,可以当作树叶了,树叶部分为绿色,其余为树干部分设为棕色. 2.案例分析 由于分形树具有对称性,自相似性,所以我们可以用 ...
- 基于Cocos2d-x学习OpenGL ES 2.0之多纹理
没想到原文出了那么多错别字,实在对不起观众了.介绍opengl es 2.0的不多.相信介绍基于Cocos2d-x学习OpenGL ES 2.0之多纹理的,我是独此一家吧.~~ 子龙山人出了一个系列: ...
随机推荐
- [na]交换机接口文档
文档中有一些数据包等附件,pdf不能看,去这里.http://note.youdao.com/share/?id=5319680eb0c8b9c3f8fefd157534fd90&type=n ...
- SqlServer四种排序:ROW_NUMBER()/RANK()/DENSE_RANK()/ntile() over()
首先,我们创建一些测试数据. if OBJECT_ID('Tempdb.dbo.#Tmp') is not null drop table #Tmp create table #Tmp ( name ...
- jsack
https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr016.html#BABGHEJB
- InfoQ 趋势报告:架构和设计领域技术演变详解
https://www.infoq.cn/article/R7lWXd0R4VFf3E0bB*38 本文概述了我们对当前“架构和设计”领域的看法,这个领域侧重于基础设施模式.技术框架模式的实现,以及软 ...
- 解决最小化安装Centos7后无法上网的问题,以及安装成功后的基本配置
发现问题 刚装完最小化的系统后,如果直接ping外网,可能回出现如下情况 解决问题 首先编辑虚拟机的DHCP池: 在弹出的“虚拟网络编辑器”窗口中选择NAT模式的,编辑为其分配地址池: 然后编辑网卡的 ...
- Windows下断言的类型及实现
一.内容综述 本文主要介绍Windows下断言assert的实现,并总结断言的不同应用准则.最后给出一个windows自定义断言的方法. 本文行文参考<Debugging Windows Pro ...
- idea 实现热部署
Idea实现热部署需要以下几步 1.open module setting,设置path,使output path指向存放实时编译class的文件夹 2.设置Artifacts,选择exploded选 ...
- jetty 6.1 笔记
download: http://dist.codehaus.org/jetty/jetty-6.1.22/ jetty 6.2 代码启动 必要jar包 lib --->> lib---& ...
- JAVA-JSP内置对象之page对象调用Servlet
相关资料:<21天学通Java Web开发> page对象1.page对象代表JSP转译后的Servlet.2.通过page对象可以非常方便地调用Servlet类中定义的方法. pageD ...
- python 高级知识点
1.切片:截取List,tuple指定范围内的值:>>L[0,3] 2.如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Ite ...