qt opengl纹理映射怎么贴上去只有一种颜色

opengl_qt_simple_draw 本文来讲讲怎样使用 来画平面几何图形,这一节本来是很简单的,因为某些问题都弄 program 238万源代码下载-
&文件名称: opengl_qt_simple_draw
& & & & &&]
&&所属分类:
&&开发工具: C-C++
&&文件大小: 246 KB
&&上传时间:
&&下载次数: 57
&&提 供 者:
&详细说明:本文来讲讲怎样使用opengl来画平面几何图形,这一节本来是很简单的,因为某些问题都弄大半天了。当然,这还是按照NeHe的教程来的学习的。
这次实现的功能是在窗口中画一个三角形,一个矩形,一个圆形。
下面来看看怎么绘制平面几何图形。在设置好需要画的几何图形的属性后,比如颜色信息,就以glBegin()开始,以glEnd()结束,glBegin()中的参数为所画几何图形的类型,比如说GL_ TRIANGLES代表三角形,GL_QUADS为矩形等等。
在glBegin()和glEnd()之间是放的点,这里是三维的点,这些点是对应所画矩形的类型的。
画圆的话稍微麻烦一点,因为opengl中没有直接对应的类型,一般都是采用三角形来逼近,其它很多几何图形也是类似的。在用三角形逼近时,是用的画连续三角形,一般有2种类型。-This article say something about how to use opengl to draw a plane geometry, this section was very simple, because some of the issues Dounong most of the day. Of course, this is in accordance with the NeHe the tutorial come to learn. The functions realized in the window, drawing a triangle, a rectangle, a circle. Let&#39 s take a look at how to draw a plane geometry. After setting up the need to draw geometric properties, such as color, glBegin () to glEnd () end glBegin () in the argument is drawn geometry type, for example, on behalf of the triangle GL_ TRIANGLES GL_QUADS is rectangular, etc.. GlBegin () and glEnd () between the discharge point, here is the three-dimensional points, these points correspond painted rectangular type. Draw a circle, then a little difficult, because opengl not directly correspond to the type of triangle are generally used to approximate many other geometry is similar. Painting with continuous triangle with triangular approximation, generally 2 types.
文件列表(点击判断是否您需要的文件,如果是垃圾请在下面评价投诉):
&&opengl_nehe_02&&..............\glwidget.cpp&&..............\glwidget.h&&..............\glwidget.ui&&..............\main.cpp&&..............\opengl_nehe_02.pro&&..............\opengl_nehe_02.pro.user&&OpenGL_Qt学习笔记之_02(绘制简单平面几何图形).pdf
&近期下载过的用户:
&相关搜索:
&输入关键字,在本站238万海量源码库中尽情搜索:
四棱锥由5个面构成一个封闭的立体图,其中4个共顶点的侧面是三角形,底面是个四边形。如果我们要绘制一个3D的四棱锥只需要绘制这5个面即可,绘制的方法和前一篇文章Opengl_Qt学习笔记之_03(平面图形的着色和旋转)的相同。只不过这里的顶点坐标是3维的,所以图像深度那一维不一定为0。因此我们可以事
&[] - 本次试验的目的很简单,只是显示一个窗口,可以通过F1键值来切换全屏显示和普通屏显示,并当按下ESE键时退出程序。窗口的颜色背景和透视效果(其实该试验都没用上)等用opengl来实现,主要是为后面的学习写了个框架,其实这里主要是重写了3个函数:initializeGL() paintGL() resi
&[] - 在这一节中主要简单介绍下怎样给平面几何着色,以及怎样让绘制出来的几何图形旋转起来。在上一节Opengl_Qt学习笔记之_02(绘制简单平面几何图形) 中已经介绍了如何利用opengl画一些简单的图像,那么这一节就在上面的基础上给它着色,且让他旋转。
&[] - 纹理映射简单的讲,就是把一个纹理(其实说白了,纹理可以理解为一幅图像)映射到空间物体的表面上,因此纹理映射也叫贴图,这个表明不一定是矩形,比如说我可以是球面,或者是任意曲面。在上一篇文章Opengl_Qt学习笔记之_04(3D图形的绘制和旋转)中,我们绘制的空间体的表面都是一些光滑的颜色,如果要在其
&[] - 本次实验主要是学习下opengl中光照的使用方法,opengl中的光照分为环境光,漫射光,镜面光,反射光4种,这里主要是学习环境光和漫射光的设置,同时对比下opengl中支持的几种纹理滤波方式的效果,另外也可以加入色彩融合效果。这次实验是将一个木箱纹理贴到一个立方体上,然后我们在空间屏幕正外方设置了qt opengl纹理怎么贴上去只有一种颜色_opengl吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:4,221贴子:
qt opengl纹理怎么贴上去只有一种颜色收藏
这张纹理贴上去后只有一种颜色了。我拉进拉远都一样。换其他纹理就变成其他颜色。但也只有1种颜色。
IKEA宜家-汉尼斯系列85折优惠!
代码拿出来看看
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或下次自动登录
现在的位置:
& 综合 & 正文
Qt OpenGL纹理映射
用到的OpenGL函数
GLAPI void APIENTRY glGenTextures( GLsizei n, GLuint *textures );
生成n个纹理,将纹理索引存放在textures中
GLAPI void APIENTRY glBindTexture( GLenum target, GLuint texture );
target —— 纹理被绑定的目标,它只能取值GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D或者GL_TEXTURE_CUBE_MAP;
texture —— 纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用。
glBindTexture可以让你创建或使用一个已命名的纹理,调用glBindTexture方法,将target设置为GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D或GL_TEXTURE_CUBE_MAP,并将texture设置为你想要绑定的新纹理的名称,即可将纹理名绑定至当前活动纹理单元目标。
GLAPI void APIENTRY glTexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint
border, GLenum format, GLenum type, const GLvoid *pixels );
target 指定目标纹理,这个值必须是GL_TEXTURE_2D。
level 执行细节级别。0是最基本的图像级别,你表示第N级贴图细化级别。
internalformat 指定纹理中的颜色组件,这个取值和后面的format取值必须相同。可选的值有GL_ALPHA,GL_RGB,GL_RGBA,GL_LUMINANCE, GL_LUMINANCE_ALPHA .
width 指定纹理图像的宽度,必须是2的n次方。纹理图片至少要支持64个材质元素的宽度
height 指定纹理图像的高度,必须是2的m次方。纹理图片至少要支持64个材质元素的高度
border 指定边框的宽度。必须为0。
format 像素数据的颜色格式,必须和internalformatt取值必须相同。可选的值参考internalformat。
type 指定像素数据的数据类型。可以使用的值有
GL_UNSIGNED_BYTE,GL_UNSIGNED_SHORT_5_6_5,GL_UNSIGNED_SHORT_4_4_4_4,GL_UNSIGNED_SHORT_5_5_5_1。
pixels 指定内存中指向图像数据的指针
该函数的功能是,根据指定的参数,生成一个2D纹理(Texture)。
GLAPI void APIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param );
该函数可以设置图像放大、缩小时的滤波方式
GLAPI void APIENTRY glTexCoord2f( GLfloat s, GLfloat t );
设置贴图的坐标位置
1.pro文件添加
2.nglWidget.h
#ifndef NGLWIDGET_H
#define NGLWIDGET_H
#include &QGLWidget&
namespace Ui {
class NGLW
class NGLWidget : public QGLWidget
GLfloat xR
GLfloat yR
GLfloat zR
explicit NGLWidget(QGLWidget *parent = 0);
~NGLWidget();
Ui::NGLWidget *
GLuint texture[1];
void loadGLTexture();
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
void keyPressEvent(QKeyEvent *e);
public slots:
void onTimer();
#endif // NGLWIDGET_H
3.nglWidget.cpp
#include "nglwidget.h"
#include "ui_nglwidget.h"
#include &GL/gl.h&
#include &GL/glu.h&
#include &QKeyEvent&
#include &QTimer&
NGLWidget::NGLWidget(QGLWidget *parent) :
QGLWidget(parent),
ui(new Ui::NGLWidget)
ui-&setupUi(this);
resize(600,500);
xRot=10.0;
yRot=10.0;
zRot=10.0;
QTimer* t = new QT
connect(t,SIGNAL(timeout()),this,SLOT(onTimer()));
t-&start(10);
NGLWidget::~NGLWidget()
void NGLWidget::loadGLTexture()
QImage tex,
if(!buf.load("G:/lena.jpg")){
QImage dummy(128,128,QImage::Format_RGB32);
dummy.fill(QColor(Qt::green).rgb());
tex = QGLWidget::convertToGLFormat(buf);
//创建一个纹理名字
glGenTextures(1,&texture[0]);
//将纹理名字绑定到目标上
glBindTexture(GL_TEXTURE_2D,texture[0]);
//创建纹理
glTexImage2D(GL_TEXTURE_2D,0,3,tex.width(),tex.height(),0,
GL_RGBA,GL_UNSIGNED_BYTE,tex.bits());
//设置显示图像时的放大、缩小的滤波方式
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
初始化opengl
void NGLWidget::initializeGL()
//载入纹理
loadGLTexture();
//启用纹理
glEnable(GL_TEXTURE_2D);
//其他初始化
glShadeModel(GL_SMOOTH);
glClearColor(0.0,0.0,0.0,0.0);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
void NGLWidget::resizeGL(int w, int h)
glViewport(0,0,(GLint)w,(GLint)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,(GLfloat)w/(GLfloat)h,0.1,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
着色分为两种:平滑着色、单调着色
void NGLWidget::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D,texture[0]);
glPushMatrix();
glTranslatef(-0.5,-0.5,-3.0);
glRotatef(xRot,1.0,0.0,0.0);
glRotatef(yRot,0.0,1.0,0.0);
glRotatef(zRot,0.0,0.0,1.0);
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.0,0.0);
glTexCoord2f(1.0,0.0);glVertex3f(1.0,0.0,0.0);
glTexCoord2f(1.0,1.0);glVertex3f(1.0,1.0,0.0);
glTexCoord2f(0.0,1.0);glVertex3f(0.0,1.0,0.0);
glTexCoord2f(0.0,0.0);glVertex3f(0.0,1.0,1.0);
glTexCoord2f(1.0,0.0);glVertex3f(0.0,0.0,1.0);
glTexCoord2f(1.0,1.0);glVertex3f(1.0,0.0,1.0);
glTexCoord2f(0.0,1.0);glVertex3f(1.0,1.0,1.0);
glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.0,0.0);
glTexCoord2f(1.0,0.0);glVertex3f(0.0,1.0,0.0);
glTexCoord2f(1.0,1.0);glVertex3f(0.0,1.0,1.0);
glTexCoord2f(0.0,1.0);glVertex3f(0.0,0.0,1.0);
glTexCoord2f(0.0,0.0);glVertex3f(1.0,0.0,0.0);
glTexCoord2f(1.0,0.0);glVertex3f(1.0,1.0,0.0);
glTexCoord2f(1.0,1.0);glVertex3f(1.0,1.0,1.0);
glTexCoord2f(0.0,1.0);glVertex3f(1.0,0.0, 1.0);
glTexCoord2f(0.0,0.0);glVertex3f(0.0,1.0,0.0);
glTexCoord2f(1.0,0.0);glVertex3f(0.0,1.0,1.0);
glTexCoord2f(1.0,1.0);glVertex3f(1.0,1.0,1.0);
glTexCoord2f(0.0,1.0);glVertex3f(1.0,1.0,0.0);
glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.0,0.0);
glTexCoord2f(1.0,0.0);glVertex3f(0.0,0.0,1.0);
glTexCoord2f(1.0,1.0);glVertex3f(1.0,0.0,1.0);
glTexCoord2f(0.0,1.0);glVertex3f(1.0,0.0,0.0);
glPopMatrix();
void NGLWidget::keyPressEvent(QKeyEvent *e)
switch(e-&key()){
case Qt::Key_Escape:
showNormal();
case Qt::Key_F1:
showFullScreen();
void NGLWidget::onTimer()
xRot += 0.3;
yRot += 0.3;
zRot += 0.3;
//重新绘制
updateGL();
&&&&推荐文章:
【上篇】【下篇】opengl纹理贴图后画面很暗
[问题点数:40分,结帖人qwesdfok]
opengl纹理贴图后画面很暗
[问题点数:40分,结帖人qwesdfok]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。  在三维图形中,纹理映射(Texture Mapping)的方法运用得很广,尤其描述具有真实感的物体。比如绘制一面砖墙,就可以用一幅真实的砖墙图像或照片作为纹理贴到一个矩形上,这样,一面逼真的砖墙就画好了。如果不用纹理映射的方法,则墙上的每一块砖都必须作为一个独立的多边形来画。另外,纹理映射能够保证在变换多边形时,多边形上的纹理图案也随之变化。例如,以透视投影方式观察墙面时,离视点远的砖块的尺寸就会缩小,而离视点 较近的就会大些。此外,纹理映射也常常运用在其他一些领域,如飞行仿真中常把一大片植被的图像映射到一些大多边形上用以表示地面,或用大理石、木材、布匹等自然物质的图像作为纹理映射到多边形上表示相应的物体。  纹理映射有许多种情况。例如,任意一块纹理可以映射到平面或曲面上,且对光亮的物体进行纹理映射,其表面可以映射出周围环境的景象;纹理还可按不同的方式映射到曲面上,一是可以直接画上去(或称移画印花法),二是可以调整曲面颜色或把纹理颜色与曲面颜色混合;纹理不仅可以是二维的,也可以是一维或其它维的。  本章将详细介绍OpenGL纹理映射有关的内容:基本步骤、纹理定义、纹理控制、映射方式和纹理坐标等。12.1 基本步骤  纹理映射是一个相当复杂的过程,这节只简单地叙述一下最基本的执行纹理映射所需的步骤。基本步骤如下:  1)定义纹理、2)控制滤波、3)说明映射方式、4)绘制场景,给出顶点的纹理坐标和几何坐标。  注意:纹理映射只能在RGBA方式下执行,不能运用于颜色表方式。下面举出一个最简单的纹理映射应用例子:  例12-1 简单纹理映射应用例程(texsmpl.c)
#include "glos.h"
#include &GL/gl.h&
#include &GL/glu.h&
#include &GL/glaux.h&&
void myinit(void);
void makeImage(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK display(void);&
/* 创建纹理 */
#define ImageWidth 64#define ImageHeight 64GLubyte Image[ImageWidth][ImageHeight][3];&
void makeImage(void)
  int i, j, r,g,b;&
  for (i = 0; i & ImageW i++)
    for (j = 0; j & ImageH j++)
      r=(i*j)%255;
      g=(4*i)%255;
      b=(4*j)%255;
      Image[i][j][0] = (GLubyte)
      Image[i][j][1] = (GLubyte)
      Image[i][j][2] = (GLubyte)
void myinit(void)
  glClearColor (0.0, 0.0, 0.0, 0.0);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LESS);&
  makeImage();
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);&
  /* 定义纹理 */
  glTexImage2D(GL_TEXTURE_2D, 0, 3, ImageWidth,
ImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, &Image[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_NEAREST);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);&
  /* 说明映射方式*/
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);&
  /* 启动纹理映射 */
  glEnable(GL_TEXTURE_2D);&
  glShadeModel(GL_FLAT);
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(1.0, -1.0, 0.0);
  glTexCoord2f(0.0, 1.0);
  glVertex3f(1.0, 1.0, 0.0);
  glTexCoord2f(1.0, 1.0);
  glVertex3f(2.41421, 1.0, -1.41421);
  glTexCoord2f(1.0, 0.0);
  glVertex3f(2.41421, -1.0, -1.41421);
  glEnd();&
  glFlush();
void CALLBACK myReshape(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 main(void)
  auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);
  auxInitPosition (0, 0, 500, 500);
  auxInitWindow ("Simple Texture Map");
  myinit();
  auxReshapeFunc (myReshape);
  auxMainLoop(display);
  以上程序运行结果是将一块纹理映射到两个正方形上去。这两个正方形都是按透视投影方式绘制,其中一个正对观察者,另一个向后倾斜45度角。图形的纹理是由函数makeImage()产生的,并且所有纹理映射的初始化工作都在程序myinit()中进行。由glTexImage2d()说明了一个全分辨率的图像,其参数指出了图像的尺寸、图像类型、图像位置和图像的其它特性;下面连续调用函数glTexParameter*()说明纹理怎样缠绕物体和当象素与纹理数组中的单个元素(texel,暂称纹素)不能精确匹配时如何过滤颜色;接着用函数glTexEnv*()设置画图方式为GL_DECAL,即多边形完全用纹理图像中的颜色来画,不考虑多边形在未被纹理映射前本身的颜色;最后,调用函数glEnable()启动纹理映射。子程序display()画了两个正方形,其中纹理坐标与几何坐标一起说明,glTexCoord*()函数类似于glNormal*()函数,不过它是设置纹理坐标,之后任何顶点都把这个纹理坐标与顶点坐标联系起来,直到再次调用 glTexCoord*()改变当前纹理坐标。12.2、纹理定义  12.2.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的整数,指出选择了R、G、B、A中的哪些分量用于调整和混合,1表示选择了R分量,2表示选择了R和A两个分量,3表示选择了R、G、B三个分量,4表示选择了R、G、B、A四个分量。  参数width和height给出了纹理图像的长度和宽度,参数border为纹理边界宽度,它通常为0,width和height必须是2m+2b,这里m是整数,长和宽可以有不同的值,b是border的值。纹理映射的最大尺寸依赖于OpenGL,但它至少必须是使用64x64(若带边界为66x66),若width和height设置为0,则纹理映射有效地关闭。  参数format和type描述了纹理映射的格式和数据类型,它们在这里的意义与在函数glDrawPixels()中的意义相同,事实上,纹理数据与glDrawPixels()所用的数据有同样的格式。参数format可以是GL_COLOR_INDEX、GL_RGB、GL_RGBA、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_LUMINANCE或GL_LUMINANCE_ALPHA(注意:不能用GL_STENCIL_INDEX和GL_DEPTH_COMPONENT)。类似地,参数type是GL_BYPE、GL_UNSIGNED_BYTE、GL_SHORT、 GL_UNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_FLOAT或GL_BITMAP。  参数pixels包含了纹理图像数据,这个数据描述了纹理图像本身和它的边界。  12.2 一维纹理定义的函数 
void glTexImage1D(GLenum target,GLint level,GLint components,GLsizei width,GLint border,GLenum format,GLenum type,const GLvoid *pixels);
  定义一个一维纹理映射。除了第一个参数target应设置为GL_TEXTURE_1D外,其余所有的参数与函数TexImage2D()的一致,不过纹理图像是一维纹素数组,其宽度值必须是2的幂,若有边界则为2m+2。12.3、纹理控制  OpenGL中的纹理控制函数是 
void glTexParameter{if}[v](GLenum target,GLenum pname,TYPE param);
  控制纹素映射到片元(fragment)时怎样对待纹理。第一个参数target可以是GL_TEXTURE_1D或GL_TEXTURE_2D,它指出是为一维或二维纹理说明参数;后两个参数的可能值见表12-1所示。 
GL_TEXTURE_WRAP_S
GL_CLAMPGL_REPEAT
GL_TEXTURE_WRAP_T
GL_CLAMPGL_REPEAT
GL_TEXTURE_MAG_FILTER
GL_NEARESTGL_LINEAR
GL_TEXTURE_MIN_FILTER
GL_NEARESTGL_LINEARGL_NEAREST_MIPMAP_NEARESTGL_NEAREST_MIPMAP_LINEARGL_LINEAR_MIPMAP_NEARESTGL_LINEAR_MIPMAP_LINEAR
表12-1 放大和缩小滤波方式
  12.3.1 滤波  一般来说,纹理图像为正方形或长方形。但当它映射到一个多边形或曲面上并变换到屏幕坐标时,纹理的单个纹素很少对应于屏幕图像上的象素。根据所用变换和所用纹理映射,屏幕上单个象素可以对应于一个纹素的一小部分(即放大)或一大批纹素(即缩小)。下面用函数glTexParameter*()说明放大和缩小的方法:
glTexParameter*(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);glTexParameter*(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
  实际上,第一个参数可以是GL_TEXTURE_1D或GL_TEXTURE_2D,即表明所用的纹理是一维的还是二维的;第二个参数指定滤波方法,其中参数值GL_TEXTURE_MAG_FILTER指定为放大滤波方法,GL_TEXTURE_MIN_FILTER指定为缩小滤波方法;第三个参数说明滤波方式,其值见表12-1所示。  若选择GL_NEAREST则采用坐标最靠近象素中心的纹素,这有可能使图像走样;若选择GL_LINEAR则采用最靠近象素中心的四个象素的加权平均值。GL_NEAREST所需计算比GL_LINEAR要少,因而执行得更快,但GL_LINEAR提供了比较光滑的效果。  12.3.2 重复与约简  纹理坐标可以超出(0, 1)范围,并且在纹理映射过程中可以重复映射或约简映射。在重复映射的情况下,纹理可以在s,t方向上重复,即:
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  若将参数GL_REPEAT改为GL_CLAMP,则所有大于1的纹素值都置为1,所有小于0的值都置为0。参数设置参见表12-1。12.4、映射方式  在本章的第一个例程中,纹理图像是直接作为画到多边形上的颜色。实际上,可以用纹理中的值来调整多边形(曲面)原来的颜色,或用纹理图像中的颜色与多边形(曲面)原来的颜色进行混合。因此,OpenGL提供了三种纹理映射的方式,这个函数是: 
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是包含四个浮点数(分别是R、G、B、A分量)的数组,这些值只在采用GL_BLEND纹理函数时才有用。12.5、纹理坐标  12.5.1 坐标定义  在绘制纹理映射场景时,不仅要给每个顶点定义几何坐标,而且也要定义纹理坐标。经过多种变换后,几何坐标决定顶点在屏幕上绘制的位置,而纹理坐标决定纹理图像中的哪一个纹素赋予该顶点。并且顶点之间的纹理坐标插值与基础篇中所讲的平滑着色插值方法相同。  纹理图像是方形数组,纹理坐标通常可定义成一、二、三或四维形式,称为s,t,r和q坐标,以区别于物体坐标(x, y, z, w)和其他坐标。一维纹理常用s坐标表示,二维纹理常用(s, t)坐标表示,目前忽略r坐标,q坐标象w一样,一半值为1,主要用于建立齐次坐标。OpenGL坐标定义的函数是: 
void gltexCoord{1234}{sifd}[v](TYPE coords);
  设置当前纹理坐标,此后调用glVertex*()所产生的顶点都赋予当前的纹理坐标。对于gltexCoord1*(),s坐标被设置成给定值,t和r设置为0,q设置为1;用gltexCoord2*()可以设置s和t坐标值,r设置为0,q设置为1;对于gltexCoord3*(),q设置为1,其它坐标按给定值设置;用gltexCoord4*()可以给定所有的坐标。使用适当的后缀(s,i,f或d)和TYPE的相应值(GLshort、GLint、glfloat或GLdouble)来说明坐标的类型。注意:整型纹理坐标可以直接应用,而不是象普通坐标那样被映射到[-1, 1]之间。  12.5.2 坐标自动产生  在某些场合(环境映射等)下,为获得特殊效果需要自动产生纹理坐标,并不要求为用函数gltexCoord*()为每个物体顶点赋予纹理坐标值。OpenGL提供了自动产生纹理坐标的函数,其如下: 
void glTexGen{if}[v](GLenum coord,GLenum pname,TYPE param);
  自动产生纹理坐标。第一个参数必须是GL_S、GL_T、GL_R或GL_Q,它指出纹理坐标s,t,r,q中的哪一个要自动产生;第二个参数值为GL_TEXTURE_GEN_MODE、GL_OBJECT_PLANE或 GL_EYE_PLANE;第三个参数param是一个定义纹理产生参数的指针,其值取决于第二个参数pname的设置,当pname为GL_TEXTURE_GEN_MODE时,param是一个常量,即GL_OBJECT_LINEAR、GL_EYE_LINEAR或GL_SPHERE_MAP,它们决定用哪一个函数来产生纹理坐标。对于pname的其它可能值,param是一个指向参数数组的指针。下面是一个运用自动产生纹理坐标函数的实例:  例12-1 纹理坐标自动产生例程(texpot.c) 
#include "glos.h"
#include &GL/gl.h&
#include &GL/glu.h&
#include &GL/glaux.h&&
void myinit(void);
void makeStripeImage(void);
void CALLBACK display(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);&
#define stripeImageWidth 64GLubyte stripeImage[3*stripeImageWidth];&
void makeStripeImage(void)
  for (j = 0; j & stripeImageW j++)
    stripeImage[3*j] = 255;
    stripeImage[3*j+1] =255-2*j;
    stripeImage[3*j+2] =255;
&/* 参数设置 */&GLfloat sgenparams[] = {1.0, 1.0, 1.0, 0.0};&
void myinit(void){
  glClearColor (0.0, 0.0, 0.0, 0.0);&
  makeStripeImage();
  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, stripeImageWidth, 0, GL_RGB, GL_UNSIGNED_BYTE, stripeImage);&
  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  glTexGenfv(GL_S, GL_OBJECT_PLANE, sgenparams);&
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LESS);
  glEnable(GL_TEXTURE_GEN_S);
  glEnable(GL_TEXTURE_1D);
  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);
void CALLBACK display(void)
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glPushMatrix ();
  glRotatef(25.0, 1.0, 0.0, 0.0);
  auxSolidTeapot(1.5);
  glPopMatrix ();
  glFlush();
void CALLBACK myReshape(GLsizei w, GLsizei h)
  float a=3.5;&
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  if (w &= h)
    glOrtho (-a, a, -a*(GLfloat)h/(GLfloat)w, a*(GLfloat)h/(GLfloat)w, -a, a);
    glOrtho (-a*(GLfloat)w/(GLfloat)h, a*(GLfloat)w/(GLfloat)h, -a, a, -a, a);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
void main(void)
  auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);
  auxInitPosition (0, 0, 500, 500);
  auxInitWindow (" Teapot TextureMapping");
  myinit();
  auxReshapeFunc (myReshape);
  auxMainLoop(display);
  以上程序运行结果是在屏幕上显示一个带条状纹理的茶壶。其中用到了前面所讲的一维纹理映射定义,以及本节的纹理坐标自动产生。
阅读(...) 评论()

我要回帖

更多关于 opengl 纹理坐标 的文章

 

随机推荐