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之多纹理的,我是独此一家吧.~~ 子龙山人出了一个系列: ...
随机推荐
- JDK 1.6 写Webservice时,runtime modeler error: Wrapper class com.ws.jaxws.DoSomething is not found问题的解决办法
转自:http://blog.csdn.net/forandever/article/details/5276038 1.问题如下: Exception in thread "main&qu ...
- vue-cli项目配置图解
配置vue项目机构步骤1.搭建环境:node.npm2.安装vue脚手架工具:npm install -g vue-cli3.初始化项目:vue init webpack vuedemo(“vuede ...
- android笔记---百度地图api应用 (二) 获取公交路线的详细信息
package com.example.bdtest; import com.baidu.mapapi.MKEvent; import com.baidu.mapapi.MKPlanNode; imp ...
- Spark Streaming的接收KAFKA的数据
https://github.com/lw-lin/CoolplaySpark/blob/master/Spark%20Streaming%20%E6%BA%90%E7%A0%81%E8%A7%A3% ...
- python(48):re.split 多分隔符
问题描述: 使用多个界定符分割字符串 问题 你需要将一个字符串分割为多个字段,但是分隔符(还有周围的空格)并不是固定的. 解决方案 string 对象的 split() 方法只适应于非常简单的字符串分 ...
- 【qt】QT 的信号与槽机制
QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT ...
- 【Acm】算法之美—Jugs
题目概述:Jugs In the movie "Die Hard 3", Bruce Willis and Samuel L. Jackson were confronted wi ...
- SpringBoot热部署配置(基于Maven)
热部署的意思是只要类中的代码被修改了,就能实时生效,而不用重启项目.spring-boot-devtools 是一个为开发者服务的一个模块,其中最重要的功能就是自动应用代码更改到最新的App上面去.原 ...
- hive sequencefile导入文件遇到FAILED: SemanticException Unable to load data to destination table. Error: The file that you are trying to load does not match the file format of the destination table.错误
hive sequencefile导入文件遇到FAILED: SemanticException Unable to load data to destination table. Error: Th ...
- 管理 python logging 日志使用
1.日志级别 日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICAL. DEBUG:详细的信息,通常只出现在诊断问题上INFO:确认一切按预期运行WA ...