opengl中怎样把二维的位图纹理贴到球面上

opengl中怎样把二维的位图纹理贴到球面上,第1张

大概步骤:

1.创建纹理对象,并为他指定一个纹理.

2.确定纹理如何应用到每个像素上.

3.启用纹理贴图

4.绘制场景,提供纹理和几何坐标

过滤:由于我们提供的纹理图像很少能和最终的屏幕坐标形成对应,大小不同,所以需要设置过滤项目.允许我们进行插值或者匀和,指定放大缩小的函数.glTexParameter*(),使用过滤模式GL_NEAREST那么纹理单位最邻近的将被使用,GL_LINEAR那么就用2*2的包含纹理数据的数组加权组作为纹理

命名纹理对象:glGenTexures(GLSize n,Gluint *textureNames)n为产生n个未使用的对象值,textureNames为纹理名字数组,你可能有几个纹理需要使用,这个数组来区分.

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;

源文档 <http://www.pinxue.net/OpenGL/credbook/chapter9_textuer.htm>

绑定纹理对象:glBindTexture(Glenum target,Gluint,glTexImage*),将把数据存储到这个纹理对象中,如果需要纹理图像的颜色和物体表面的颜色进行组合,不是直接贴图,那么就需要glTexEvn*()函数.

确定纹理坐标:glTexCoord2f(1.of,1.Of);glVertex3f(1.Of,1.Of,0.Of);比如这一句话.对于设置纹理贴图的坐标和绘图坐标的确定问题.一般的情况假设纹理和图片都是正方形的,那么我们希望纹理映射到整个物体上面,这个时候纹理坐标按照逆时针放心依次(0,0),(1,0),(1,1),(0,1),其中的四个坐标只是代表的向量,并不是真实的坐标,如果是要一半贴到物体上就应该是0.5的值了,假如你给的纹理坐标大于1,那么将会贴多个纹理,比如值为2的时候,会有4个纹理贴图.

1 概述

概括的说, 纹理映射机制允许你将一个图像关联到一个多边形上,从而呈现出真实视觉效果。例如, 你可以将书的封面图像应用到一个方形上, 这样这个方形看起来就像是一本书了。 你可以将地球的地图通过纹理映射应用到一个球体上, 那么这个球体就是一个3D的具真实感的地球了。纹理映射在当今的3D图形应用上处处皆是。游戏都是通过纹理映射来作为虚拟真实的第一个步骤。

纹理映射是一个二维的数组。数组中的每一项称之为纹理点( texel )。 虽然这个数组是二维的, 但是可以映射到非二维的对象上, 如球体或者其他的 3D 对象模型上。

比较常见的是, 开发者在他们的图形应用中运用二维纹理, 当然一维或者三维的纹理也并非未闻。二维纹理有宽度和高度决定二维。一维纹理也有宽度和高度, 只是高度被设为值 1(单位:像素 pixel). 而三维纹理不仅具有宽度和高度, 还有深度, 所以三维为纹理又称为立体纹理。我们讨论的主要是二维纹理。

2 预备知识: 纹理坐标

在 OpenGl 中是通过指定纹理坐标来将纹理映射到多边形上去的. 在纹理坐标系中, 左下角是 (0,0), 右上角是 (1,1). 2D 纹理的坐标中通过指定 (s,t) (s为x轴上,t为y轴上, 取值0~1). 1D, 3D, 4D纹理坐标系中对应的需要指定 (s), (s,t,r), (s,t, r,q).

纹理坐标需要通过函数 glTexCoord() 来设置, 此函数:

void glTexCoord{1234}{sifd}(TYPE coords)

void glTexCoord{1234}{sifd}v(TYPE coords)

如将 2D 纹理坐标设为 (0.2, 0.4):

1

glTexCoord2f(0.2f,0.4f)

每次通过 glVertex() 指定一个顶点时, 当前的纹理坐标会被应用到这个点上. 所以每指定一个新的顶点, 需要同时修改纹理坐标:

glBegin(GL_POLYGON)

glTexCoord2f(0.0f, 0.0f)glVertex3f(-0.5f, 0.5f, 0.5f)//左下角

glTexCoord2f(1.0f, 0.0f)glVertex3f(0.5f, 0.5f, 0.5f)// 右下角

glTexCoord2f(1.0f, 1.0f)glVertex3f(0.5f, 0.5f, -0.5f)// 右上角

glTexCoord2f(0.0f, 1.0f)glVertex3f(-0.5f, 0.5f, -0.5f)// 左上角

glEnd()

至此, 我们知道了纹理坐标如何赋值.且看如何创建纹理:

3 使用纹理映射

纹理就是应用到多边形上的图像. 这些图像可以从文件中加载, 或是在内存中生成. 一旦你将图像数据加载到了内存中, 你需要指定其为纹理映射来使用它. 指定其为纹理映射, 首先需要生成一个纹理对象, 其中存储着纹理的诸如图像数据, 如何应用等信息.

纹理是一个OpenGL状态, 因而通过 glEnable() 和 glDisable() 来开闭, 参数是 GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP.

/*

 * Copyright (c) 1993-1997, Silicon Graphics, Inc.

 * ALL RIGHTS RESERVED 

 * Permission to use, copy, modify, and distribute this software for 

 * any purpose and without fee is hereby granted, provided that the above

 * copyright notice appear in all copies and that both the copyright notice

 * and this permission notice appear in supporting documentation, and that 

 * the name of Silicon Graphics, Inc. not be used in advertising

 * or publicity pertaining to distribution of the software without specific,

 * written prior permission. 

 *

 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"

 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,

 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR

 * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON

 * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,

 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY

 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,

 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF

 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN

 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON

 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE

 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.

 * 

 * US Government Users Restricted Rights 

 * Use, duplication, or disclosure by the Government is subject to

 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph

 * (c)(1)(ii) of the Rights in Technical Data and Computer Software

 * clause at DFARS 252.227-7013 and/or in similar or successor

 * clauses in the FAR or the DOD or NASA FAR Supplement.

 * Unpublished-- rights reserved under the copyright laws of the

 * United States.  Contractor/manufacturer is Silicon Graphics,

 * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.

 *

 * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.

 */

#include <GL/glut.h>

#include <stdlib.h>

#include <stdio.h>

#define stripeImageWidth 32

GLubyte stripeImage[4*stripeImageWidth]

#ifdef GL_VERSION_1_1

static GLuint texName

#endif

void makeStripeImage(void)

{

   int j

    

   for (j = 0 j < stripeImageWidth j++) {

      stripeImage[4*j] = (GLubyte) ((j<=4) ? 255 : 0)

      stripeImage[4*j+1] = (GLubyte) ((j>4) ? 255 : 0)

      stripeImage[4*j+2] = (GLubyte) 0

      stripeImage[4*j+3] = (GLubyte) 255

   }

}

/*  planes for texture coordinate generation  */

static GLfloat xequalzero[] = {1.0, 0.0, 0.0, 0.0}

static GLfloat slanted[] = {1.0, 1.0, 1.0, 0.0}

static GLfloat *currentCoeff

static GLenum currentPlane

static GLint currentGenMode

static float roangles

void init(void)

{

   glClearColor (0.0, 0.0, 0.0, 0.0)

   glEnable(GL_DEPTH_TEST)

   glShadeModel(GL_SMOOTH)

   makeStripeImage()

   glPixelStorei(GL_UNPACK_ALIGNMENT, 1)

#ifdef GL_VERSION_1_1

   glGenTextures(1, &texName)

   glBindTexture(GL_TEXTURE_1D, texName)

#endif

   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT)

   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)

#ifdef GL_VERSION_1_1

   glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, stripeImageWidth, 0,

                GL_RGBA, GL_UNSIGNED_BYTE, stripeImage)

#else

   glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0,

                GL_RGBA, GL_UNSIGNED_BYTE, stripeImage)

#endif

   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)

   currentCoeff = xequalzero

   currentGenMode = GL_OBJECT_LINEAR

   currentPlane = GL_OBJECT_PLANE

   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode)

   glTexGenfv(GL_S, currentPlane, currentCoeff)

   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)

   roangles = 45.0f

}

void display(void)

{

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

   glPushMatrix ()

   glRotatef(roangles, 0.0, 0.0, 1.0)

#ifdef GL_VERSION_1_1

   glBindTexture(GL_TEXTURE_1D, texName)

#endif

   //glutSolidTeapot(2.0)

   glutSolidSphere( 2.0, 32, 32 )

   glPopMatrix ()

   glFlush()

}

void reshape(int w, int h)

{

   glViewport(0, 0, (GLsizei) w, (GLsizei) h)

   glMatrixMode(GL_PROJECTION)

   glLoadIdentity()

   if (w <= h)

      glOrtho (-3.5, 3.5, -3.5*(GLfloat)h/(GLfloat)w, 

               3.5*(GLfloat)h/(GLfloat)w, -3.5, 3.5)

   else

      glOrtho (-3.5*(GLfloat)w/(GLfloat)h, 

               3.5*(GLfloat)w/(GLfloat)h, -3.5, 3.5, -3.5, 3.5)

   glMatrixMode(GL_MODELVIEW)

   glLoadIdentity()

}

void idle()

{

roangles += 0.1f

glutPostRedisplay()

}

int main(int argc, char** argv)

{

   glutInit(&argc, argv)

   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH)

   glutInitWindowSize(256, 256)

   glutInitWindowPosition(100, 100)

   glutCreateWindow (argv[0])

   glutIdleFunc( idle )

   init ()

   glutDisplayFunc(display)

   glutReshapeFunc(reshape)

   glutMainLoop()

   return 0

}

这是OpenGL红宝书的例子,稍作改动,以显示球体转动时纹理是跟着动地。还有原来例子画的是Teapot.。。。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/bake/11630969.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存