OPENGL的纹理(转)

原创 2007年09月28日 15:53:00
在3D图形中,纹理映射是广泛使用的。纹理映射也是相当复杂的过程:
一 定义纹理
二 控制滤波
三 说明映射方式
四 绘制场景给出顶点的纹理坐标和几何坐标
注意!!纹理映射只能在RGBA模式下使用,不适用于颜色索引模式

1.纹理定义
void glTexImage2D( GLenum target, GLint level, GLint components,
GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, const GLvoid *pixels );
定义一个二维纹理映射。
target是常数 GL_TEXTURE_2D
level表示多级分辨率的纹理图象的级数。若只有一种分辨率,level为0。
components是从1到4的整数,1:选择R;2:选择R A;3:选择R G B;
4:选择R G B A;
width height是纹理的尺寸。
format和type描述映射格式和数据类型。它们与前面讲的glDrawPixels()中
OPENGL的纹理
在3D图形中,纹理映射是广泛使用的。纹理映射也是相当复杂的过程:
一 定义纹理
二 控制滤波
三 说明映射方式
四 绘制场景给出顶点的纹理坐标和几何坐标
注意!!纹理映射只能在RGBA模式下使用,不适用于颜色索引模式

1.纹理定义
void glTexImage2D( GLenum target, GLint level, GLint components,
GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, const GLvoid *pixels );
定义一个二维纹理映射。
target是常数 GL_TEXTURE_2D
level表示多级分辨率的纹理图象的级数。若只有一种分辨率,level为0。
components是从1到4的整数,1:选择R;2:选择R A;3:选择R G B;
4:选择R G B A;
width height是纹理的尺寸。
format和type描述映射格式和数据类型。它们与前面讲的glDrawPixels()中
GL_NEAREST_MIPMAP_NEAREST
GL_NEAREST_MIPMAP_LINEAR
GL_LINEAR_MIPMAP_NEAREST
GL_LINEAR_MIPMAP_LINEAR
2.1 滤波
原始纹理图象是个方形图象,把它映射到奇形怪状的物体上,一般不可能图象
上的一个象素对应屏幕的一个象素。因此局部放大缩小时,就要定义合适的滤
波方式(以2D为例):
void glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
void glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
前者是放大滤波(GL_TEXTURE_MAG_FILTER),
后者是缩小滤波(GL_TEXTURE_MIN_FILTER);
另外,GL_NEAREST是利用最坐标最靠近象素中心的纹理元素,这有可能使图样
走型,但计算速度快;GL_LINEAR利用线形插值,效果好但计算量大。

2.2重复与缩限
纹理映射可以重复映射或者缩限映射,重复映射时纹理可以在自己的坐标S T方
向重复。
对于重复映射:
void glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
void glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
参数GL_REPEAT改为GL_CLAMP,则缩限,所有大于1的纹理元素值置为1。所有小于
0的纹理元素值置为0。
0的纹理元素值置为0。

3. 映射方式
处理纹理本身图案颜色和物体本身颜色的关系:
void glTexEnv{if}[v](GLenum target,GLenum pname,TYPE param);
target必须是GL_TEXTURE_ENV;

pname是GL_TEXTURE_ENV_MODE,则param可以是 GL_DECAL GL_MODULATE或
GL_BLEND,说明纹理值与原来颜色不同的处理方式。
pname是GL_TEXTURE_ENV_COLOR,则参数param是包含4个浮点数(R、G、B、A)
的数组。这些值只在采用GL_BLEND纹理函数时才采用。

4. 纹理坐标
坐标的定义:纹理图象是方形的,纹理坐标可定义成s,t,r,q坐标,仿照齐次
坐标系的x,y,z,w坐标。
void glTexCoord{1234}{sifd}[v](TYPE coords);
设置当前纹理坐标,此后调用glVertex*()所产生的顶点都赋予当前的纹理坐标。

5. 坐标自动产生
有时不需要为每个物体顶点赋予纹理坐标,可以使用
void glTexGen{if}(GLenum coord,GLenum pname,TYPE param);
coord为:GL_S GL_T GL_R或GL_Q,指明哪个坐标自动产生
pname为GL_TEXTURE_GEN_MODE时
param为常数:GL_OBJECT_LINEAR GL_EYE_LINEAR或GL_SPHERE_MAP,它们决定用
哪个函数来产生纹理坐标

pname为GL_OBJECT_PLANE或GL_EYE_PLANE,param时一个指向参数数组的指针。

先请看一个简单的例子:
////////////////////////////////////////////
//sample.cpp
#include "glos.h"
#include <GL/gl.h>
#include <GL/glaux.h>
#include "windows.h"
void myinit(void);
void CALLBACK display(void);
void CALLBACK reshape(GLsizei w,GLsizei h);

//创建纹理图象的子程序
#define TEXTUREWIDTH 64
#define TEXTUREHEIGHT 64
GLubyte Texture[TEXTUREWIDTH][TEXTUREHEIGHT][3];
void makeTexture(void)
void makeTexture(void)
{
int i,j,r,g,b;
for(i=0;i<TEXTUREWIDTH;i++)
{
for(j=0;j<TEXTUREHEIGHT;j++)
{
r=(i*j)%255;
g=(4*i)%255;
b=(4*j)%255;
Texture[i][j][0 =(GLubyte)r;
Texture[i][j][1 =(GLubyte)g;
Texture[i][j][2 =(GLubyte)b;
}
}
}


void myinit(void)
{
auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
auxInitPosition(0,0,500,500);
auxInitWindow("sample1");
auxInitWindow("sample1");
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);

//创建纹理图象的原始数据保存在Texture[][][]中
makeTexture();
glPixelStorei(GL_UNPACK_ALIGNMENT,1);

//定义二维纹理
glTexImage2D(GL_TEXTURE_2D,0,3,TEXTUREWIDTH,
TEXTUREHEIGHT,0,GL_RGB,GL_UNSIGNED_BYTE,
&Texture[0][0][0]);
//控制滤波
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

//说明映射方式
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);

//这个应该很熟了,启用纹理模式
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_2D);
// glShadeModel(GL_FLAT);
}

void CALLBACK reshape(GLsizei w,GLsizei h)
{

glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//定义立体视景体
gluPerspective(60.0,1.0*(GLfloat)w/(GLfloat)h,1.0,30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-3.6);
}

void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glBegin(GL_QUADS);//绘制四边形
//先绘制正方形,用来显示实际未变形的纹理图样
//先绘制正方形,用来显示实际未变形的纹理图样
glTexCoord2f(0.0,0.0);glVertex3f(-2.0,-1.0,0.0);
glTexCoord2f(0.0,1.0);glVertex3f(-2.0,1.0,0.0);
glTexCoord2f(1.0,1.0);glVertex3f(0.0,1.0,0.0);
glTexCoord2f(1.0,0.0);glVertex3f(0.0,-1.0,0.0);

//绘制一个不规则四边形,用来显示纹理是如何随物体形状而变形的。
glTexCoord2f(0.0,0.0);glVertex3f(0.0,-1.0,0.0);
glTexCoord2f(0.0,1.0);glVertex3f(0.0,1.0,0.0);
glTexCoord2f(1.0,1.0);glVertex3f(1.41421,1.0,-1.41421);
glTexCoord2f(1.0,0.0);glVertex3f(1.41421,-1.0,-1.41421);
glEnd();

glFlush();
}
void main(void)
{
myinit();

auxReshapeFunc(reshape);
auxMainLoop(display);
}
//end of sample
从例子来看,除了纹理的定义和控制比较麻烦和不容易理解外,其应用是十分
方便的。只须从纹理的坐标系选出合适点附在实际物体顶点上即可。对于复杂
的纹理定义和控制,你也可以自行改变一些参数,看看效果如何。例如把
GL_LINEAR改成GL_NEAREST,则纹理的明显变的粗糙,但计算结果却快的多。
你也可以改动glTexCoord2f()的参数,看看如何选定纹理的一部分(例子中是
选定全部纹理)来贴图。例如1.0改成0.5则选择实际纹理的左上1/4部分来贴图。
下次将给出一个更复杂的纹理应用的例子和说明。18:03 98-1-21

---------------------------------------------


这次将结束纹理的内容。紧接上次,在上次平面纹理贴图中,我们先
定义了一个数组(一维或二维...)来定义纹理的数据,所以纹理本身
是一个N维空间,有自己的坐标和顶点。在上次的例子中,我们学会了
如何把纹理数据中的坐标和屏幕物体坐标相结合,就象把一块布料扯成
合适的形状贴在物体表面。而上次唯一没有使用的函数是纹理坐标的自
动产生(最后一个给出的函数),它的意义是产生一个环境纹理,所有
环境内的物体都赋予此纹理,很象一个特殊光源。
/////////////////////////////////////////////////////////////
//sample.cpp
#include "glos.h"
#include <GL/gl.h>
#include <GL/glaux.h>
#include "windows.h"
void myinit(void);
void CALLBACK display(void);
void CALLBACK reshape(GLsizei w,GLsizei h);

//定义一个一维纹理的数据,从生成来看,保持红色、兰色分量255(MAX),
//所以是渐变的紫色纹理,饱和度不断变化。
//所以是渐变的紫色纹理,饱和度不断变化。
#define TEXTUREWIDTH 64
GLubyte Texture[3*TEXTUREWIDTH];
void makeTexture(void)
{
int i;
for(i=0;i<TEXTUREWIDTH;i++)
{
Texture[3*i =255;
Texture[3*i+1 =255-2*i;
Texture[3*i+2 =255;
}
}
GLfloat sgenparams[]={1.0,1.0,1.0,0.0};

void myinit(void)
{
auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
auxInitPosition(0,0,500,500);
auxInitWindow("sample1");
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
//创建纹理
makeTexture();
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
//控制纹理
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexParameterf(GL_TEXTURE_1D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D,0,3,TEXTUREWIDTH,0,
GL_RGB,GL_UNSIGNED_BYTE,Texture);
//唯一与前面例子不同的地方:启用纹理坐标自动产生,生成环境纹理
//纹理的方向S
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
glTexGenfv(GL_S,GL_OBJECT_PLANE,sgenparams);
//启用纹理
glEnable(GL_TEXTURE_1D);
glEnable(GL_TEXTURE_GEN_S);


//启用消隐
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthFunc(GL_LESS);

//一些绘图控制,详细可参阅VC5联机帮助
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glMaterialf(GL_FRONT,GL_SHININESS,64.0);
// glShadeModel(GL_FLAT);
}

void CALLBACK reshape(GLsizei w,GLsizei h)
{

glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

if(w<=h)
glOrtho(-4.0,4.0,-4.0*(GLfloat)h/(GLfloat)w,
glOrtho(-4.0,4.0,-4.0*(GLfloat)h/(GLfloat)w,
4.0*(GLfloat)h/(GLfloat)w,-4.0,4.0);
else
glOrtho(-4.0*(GLfloat)h/(GLfloat)w,
4.0*(GLfloat)h/(GLfloat)w,-4.0,4.0,-4.0,4.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(30.0,1.0,0.0,0.0);
//功能强大的辅助库函数:呵呵画出一个大茶壶。
auxSolidTeapot(1.5);
glPopMatrix();
glFlush();
}
void main(void)
{
myinit();
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(30.0,1.0,0.0,0.0);
//功能强大的辅助库函数:呵呵画出一个大茶壶。
auxSolidTeapot(1.5);
glPopMatrix();
glFlush();
}
void main(void)
{
myinit();

auxReshapeFunc(reshape);
auxMainLoop(display);
}
//end of sample
////////////////////////////////////////////////////////////
至此纹理的全部内容已经完毕。从运行结果来看,一个物体全部进行
了表面的纹理映射 

opengl读取24位BMP文件为纹理并处理黑色背景为透明

原理: 直接用BITMAP数据而未用
  • nisigesazi
  • nisigesazi
  • 2014年05月26日 13:23
  • 1735

Android 中使用OpenGL ES进行2D开发(纹理Texture使用)

OpenGL纹理是一种位图,可以把它粘贴到OpenGL物体的表面上。比如可以获取一张邮票的图像粘贴到正方形中,使正方形看起来像一张邮票。要使邮票保持合适的方向,以便图像井然有序地排列,则必须获得形状的...
  • prike
  • prike
  • 2017年06月06日 10:04
  • 423

OpenGL ES利用纹理绘制实时视频的关键步骤

基于协议保密的原因,不能具体介绍情况,只是说说注意的地方。  首先视频数据能基本解码成功了,采用OpenGL ES技术是想在原来的基础上提升性能。我试验的结果是性能没有什么变化;从执行时间来说还慢了1...
  • nogodoss
  • nogodoss
  • 2014年03月13日 18:14
  • 4320

如何将OpenCV中的Mat类绑定为OpenGL中的纹理

如果要调用外接的USB摄像头获取图像通常使用OpenCV来调用,如果调用摄像头请参考本人的另一篇博客如果用OpenCV调用USB摄像头,如果不是,在读取本地图片和视频进行图像处理和分析也通常用Open...
  • TTTTzTTTT
  • TTTTzTTTT
  • 2016年12月04日 20:44
  • 785

Opencv 导入图片 Opengl 显示纹理(含用例代码)

本篇主要是讲使用Opencv导入一副图片,然后讲该副图片当成纹理显示在opengl当中。 首先说如何配置Opencv 我的硬件环境是: Windows10+Visual Stu...
  • u013898698
  • u013898698
  • 2017年08月14日 18:08
  • 220

OpenGL的渲染成纹理技术(转)

OpenGL的渲染成纹理技术(转) 2007-08-12 20:59:48 分类: IT综合技术 OpenGL的渲染成纹理技术(转)[@more@] ...
  • zkl99999
  • zkl99999
  • 2015年09月23日 10:28
  • 1454

OpenGL_Qt学习笔记之_05(纹理映射)

OpenGL_Qt学习笔记之_05(纹理映射)        纹理映射基础知识   什么叫纹理映射,一开始我也不明白,感觉这个词好专业(毕竟没有学过图形学),后面经过网上查找资料和这次实验...
  • hbyzl
  • hbyzl
  • 2015年11月09日 20:35
  • 1419

openGL 纹理使用

openGL 纹理的使用 总结 纹理 openGL
  • haithink
  • haithink
  • 2016年08月10日 19:32
  • 2502

OpenGL-对纹理的理解

看了《OpenGL编程指南》第九章纹理贴图之后,一开始还对纹理的理解思路还是有点乱,后面不断的阅读别人的博客之后才慢慢的有了更加清晰的认识,于是通过博客再进一步理顺一下思路。1.关于纹理的一些基本概念...
  • yanglusheng
  • yanglusheng
  • 2016年10月06日 10:31
  • 2868

2.x终于照着教程,成功使用OpenGL ES 绘制纹理贴图,增加了灰度图

在之前成功绘制变色的几何图形之后,今天利用Openg ES的可编程管线绘制出第一张纹理。学校时候不知道OpenGL的重要性,怕晦涩的语法,没有跟老师学习OpenGL的环境配置,如今只能利用cocos2...
  • jingzhewangzi
  • jingzhewangzi
  • 2014年09月28日 23:46
  • 2896
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OPENGL的纹理(转)
举报原因:
原因补充:

(最多只允许输入30个字)