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之多纹理的,我是独此一家吧.~~ 子龙山人出了一个系列: ...
随机推荐
- [tools]hugo&github构建静态网站/百度统计
hugo/github构建网站基本原理 1.hugo是一个静态化的工具,你写md,然后他把md转换成对应样式的html, 2.并给html嵌入百度统计的script.然后你将html放到github上 ...
- 深入理解Linux内核-回收页框
Linux 系统在为用户态进程和内核分配动态内存的时候,所作的检查是马马虎虎的对内核使用的许多磁盘高速缓存和内存高速缓存大小也同样不作限制. 页框回收算法(PFRA):1.在所有内存使用完之前,就必须 ...
- ny106 背包问题
背包问题 时间限制:3000 ms | 内存限制:65535 KB ...
- Android 网络请求get/post工具类:NetUtil
package com.net.util; import java.io.IOException; import java.io.UnsupportedEncodingException; imp ...
- Spark SQL inferSchema实现原理探微(Python)【转】
使用Spark SQL的基础是“注册”(Register)若干表,表的一个重要组成部分就是模式,Spark SQL提供两种选项供用户选择: (1)applySchema applySche ...
- 使用flume将kafka数据sink到HBase【转】
1. hbase sink介绍 1.1 HbaseSink 1.2 AsyncHbaseSink 2. 配置flume 3. 运行测试flume 4. 使用RegexHbaseEventSeriali ...
- 兼容ios和Android的复制js代码
//2种方法本人全部亲测有效 方法1:比较简单 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...
- 域控制器修改IP操作步骤
域控制器更改IP 在DC运维时,可能会碰上需要调整域控制器IP的情况,下面的操作就是在Windows Server 2008环境下域控制器更改IP的完整操作步骤. 1. 使用管理员帐号登录域控制器,依 ...
- tf.placeholder
tf.placeholder placeholder( dtype, shape=None, name=None ) 功能说明: 是一种占位符,在执行时候需要为其提供数据 参数列表: 参数名 必选 类 ...
- IOS修改Navigation Bar上的返回按钮文本颜色,箭头颜色以及导航栏按钮的颜色
自从IOS7后UINavigationBar的一些属性的行为发生了变化.你可以在下图看到: 现在,如果你要修改它们的颜色,用下面的代码: 1 2 3 4 self.navigationControll ...