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之多纹理的,我是独此一家吧.~~ 子龙山人出了一个系列: ...
随机推荐
- git add 不必要的文件 如何撤回
[root@666 IT-DOC]# git status -s ?? a.txt [root@666 IT-DOC]# git add a.txt [root@666 IT-DOC]# git st ...
- 菜鸟学SSH(三)——Struts2国际化自动检测浏览器语言版
前几天发了一篇Struts国际化的博客——<菜鸟学习SSH(二)——Struts2国际化手动切换版>,有网友提了一个意见,见下图: 于是就有了下面修改的版本: web.xml <?x ...
- NET Core 1.1 版本项目和2.0环境下的项目开发注意事项
在NET Core 1.1开发下的项目最好不要随便把工具更新升级到2.0,这样最容易导致之前的.NETCore直接被升级不兼容早前版本 会引起项目无法启动在运行调试IIS express 时候直接一闪 ...
- python(47):range和xrange的区别和联系
range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个序列. 比如: >>> range(5)[0, 1, 2, ...
- Custom Sublime Text Build Systems For Popular Tools And Languages
Sublime Text is currently the text editor of choice for a number of developers in the open-source co ...
- CSS实现:标题两侧画线效果
如图: html代码: <div class="detail-news"> <h5 class="detail-news-title"> ...
- Mac上把python源文件编译成so文件
把python源文件编译成so文件 前言 实际上属于一种代码混淆/加密的技术,大家知道python的源文件放在那里,大家是都可以看的,不像C语言编译出来可以拿编译后的东西去运行,所以就出现了这种需求. ...
- signal函数的原型声明void (*signal(int signo, void (*fun(int))))(int)分析
转:http://blog.sina.com.cn/s/blog_4850a7880100hnam.html void (*signal(int signo, void (*fun(int))))(i ...
- 安装VCSA6.5(vCenter Server Appliance 6.5)
相关文章:http://www.ctoclubs.com/?p=756 一.简介 VCSA(vCenter Server Appliance 6.5),相对于Windows版本的vCenter,VCS ...
- 自定义NSOperation下载图片
自定义NSOperation的话,只是需要将要下载图片的操作下载它的main方法里面,考虑到,图片下载完毕,需要回传到控制器里,这里可以采用block,也可以采用代理的方式实现,我采用的是代理的方式实 ...