- 浏览: 362312 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
nglxl:
点赞啊,必须点赞!!深度好文,解决了困扰我多年的疑惑。
tcp 长连接与短连接 -
cofftech:
opengl源码http://www.eyesourcecod ...
OPenGL ES 关键API小结 -
mail_j:
不是很好用,很多情况都不能处理 1、没有区分关键字的大小写2、 ...
Java解析sql语句,分析出调用到的所有表 -
a455642158:
就算监听到变成了cmwap还不行,还得监听网络连接状态Stat ...
android APN切换cmwap实现 -
xuhl1022:
看了您的android 4篇 浏览器二次开发,感触颇深,写的很 ...
Android浏览器Browser二次开发(四)浏览器中的APN切换
http://hi.baidu.com/shirdrn/blog/item/047ed30f94bbbc2d6059f318.html
OpenGL可以把纹理映射到指定的图形的表面上。简单一点的,就是给平面映射纹理,比如一个四边形,一个长方体的6个面,都可以指定位图作为纹理映射到各个面上。
关于将一个位图作为纹理映射到某个或者多个面上,可以学习Jeff Molofee的OpenGL系列教程。
对于指定的多个纹理,要根据自己的需要映射到不同的面上,需要对位图创建一个数组,用来存储位图的名称,然后在初始化OpenGL的时候,可以读取这些位图,然后生成多个纹理存储到一个纹理数组中,接着就可以指定绘制的某个面,对该指定的面进行纹理映射。
下面,在的Jeff Molofee教程的第六课的基础上,实现对6个面分别进行不同的纹理映射。
准备工作就是制作6幅不同的位图,如图所示:
关键代码及其说明如下。
创建全局纹理数组
GLuint texture[6]; // 创建一个全局的纹理数组,用来存储将位图转换之后得到的纹理,对应于立方体的6个面
加载位图文件
加载位图,也就是把位图读取到内存空间,实现纹理的创建,加载位图的函数说明一下:
AUX_RGBImageRec *LoadBMP(char *Filename) // 根据位图文件的名称进行加载
{
FILE *File=NULL; // 文件指针
if (!Filename) // 如果没有指定位图文件名称就返回NULL
{
return NULL;
}
File=fopen(Filename,"r"); // 根据指定的位图文件名称,打开该位图文件
if (File) // 如果位图文件存在
{
fclose(File); // 因为只是需要判断问题是否存在,而不需要对位图文件进行写操作,所以关闭位图文件
return auxDIBImageLoad(Filename); // 其实,只需要一个真正存在的位图文件的名称,实现加载位图文件,并返回一个指针
}
return NULL; // 位图文件加载失败就返回NULL
}
上面实现加载位图的函数中,AUX_RGBImageRec是glaux.h中定义的类型,该类型的定义如下所示:
/*
** RGB Image Structure
*/
typedef struct _AUX_RGBImageRec {
GLint sizeX, sizeY;
unsigned char *data;
} AUX_RGBImageRec;
首先,AUX_RGBImageRec类型是一个RGB图像结构类型。该结构定义了三个成员:
sizeX —— 图像的宽度;
sizeY —— 图像的高度;
data; —— 图形所包含的数据,其实也就是该图形在内存中的像素数据的一个指针。
AUX_RGBImageRec类型的变量描述了一幅图像的特征。
上述函数中,调用了glaux.h库文件中的auxDIBImageLoad函数,其实它是一个宏,函数原型为auxRGBImageLoadW(LPCWSTR)或者auxRGBImageLoadA(LPCSTR),可以在该库文件中找到它的定义,如下所示:
/* AUX_RGBImageRec * APIENTRY auxRGBImageLoad(LPCTSTR); */
#ifdef UNICODE
#define auxRGBImageLoad auxRGBImageLoadW
#else
#define auxRGBImageLoad auxRGBImageLoadA
#endif
AUX_RGBImageRec * APIENTRY auxRGBImageLoadA(LPCSTR);
AUX_RGBImageRec * APIENTRY auxRGBImageLoadW(LPCWSTR);
#ifdef UNICODE
#define auxDIBImageLoad auxDIBImageLoadW
#else
#define auxDIBImageLoad auxDIBImageLoadA
#endif
AUX_RGBImageRec * APIENTRY auxDIBImageLoadA(LPCSTR);
AUX_RGBImageRec * APIENTRY auxDIBImageLoadW(LPCWSTR);
宏auxDIBImageLoad实现的功能就是:根据指定的位图名称,将该位图的信息加载到内存中,以便用来创建成为纹理。
创建纹理并加载纹理
用于创建并加载纹理的函数为LoadGLTextures,实现如下所示:
int LoadGLTextures() // 根据加载的位图创建纹理
{
int Status=FALSE; // 指示纹理创建是否成功的标志
AUX_RGBImageRec *TextureImage[6]; // 创建一个纹理图像数组,这里指定数组大小为6
memset(TextureImage,0,sizeof(void *)*6); // 初始化纹理图像数组,为其分配内存
char *pictures[] = { // 创建一个位图名称数组,对应6幅位图
"Data/No1.bmp",
"Data/No2.bmp",
"Data/No3.bmp",
"Data/No4.bmp",
"Data/No5.bmp",
"Data/No6.bmp"
};
for(int i=0; i<6; i++) // 遍历位图名称数组,根据位图名称分别生成
{
if (TextureImage[i]=LoadBMP(pictures[i])) // 加载位图i成功,修改状态标志变量Status为TRUE
{
Status=TRUE;
glGenTextures(1, &texture[i]); // 为第i个位图创建纹理
glBindTexture(GL_TEXTURE_2D, texture[i]); // 将生成的纹理的名称绑定到指定的纹理上
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
if (TextureImage[i]) // 释放位图数组占用的内存空间
{
if (TextureImage[i]->data)
{
free(TextureImage[i]->data);
}
free(TextureImage[i]);
}
}
return Status; // 创建纹理并加载,返回成功或者失败的标志Status
}
上述函数是创建和加载纹理的核心实现。
1、glGenTextures函数
其中,调用了glGenTextures函数,查看MSDN可以看到,声明如下所示:
void glGenTextures(
GLsizei n,
GLuint * textures
);
函数参数的含义:
n —— 生成的纹理的名称的个数;
textures —— 生成的纹理名称所存储位置的指针,也就是一个纹理数组的内存地址,或者说是数组首元素的内存地址。
函数被调用,会生成一系列纹理的名字,并存储到指定的数组中。
2、glBindTexture函数
glBindTexture函数实现了将调用glGenTextures函数生成的纹理的名字绑定到对应的目标纹理上。该函数的声明如下所示:
void glBindTexture(
GLenum target,
GLuint texture
);
函数参数的含义:
target —— 纹理被绑定的目标,它只能取值GL_TEXTURE_1D或者GL_TEXTURE_2D;
texture —— 纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用。
3、glTexImage2D函数
调用glTexImage2D函数,用来指定二维纹理图像。该函数的声明如下所示:
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 —— 指定图像级别的编号,0表示基本图像,其它可以参考MSDN;
components —— 纹理中颜色组件的编号,可是是1或2或3或4;
width —— 纹理图像的宽度;
height —— 纹理图像的高度;
border —— 纹理图像的边框宽度,必须是0或1;
format —— 指定像素数据的格式,一共有9个取值:GL_COLOR_INDEX、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_RGB、GL_RGBA、GL_BGR_EXT、GL_BGRA_EXT、GL_LUMINANCE、GL_LUMINANCE_ALPHA ,具体含义可以参考MSDN;
type —— 像素数据的数据类型,取值可以为GL_UNSIGNED_BYTE, GL_BYTE, GL_BITMAP, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, and GL_FLOAT;
pixels —— 内存中像素数据的指针。
4、glTexParameteri函数
glTexParameteri函数或者glTexParameterf函数用来设置纹理参数,声明如下所示:
void glTexParameterf(
GLenum target,
GLenum pname,
GLfloat param
);
void glTexParameteri(
GLenum target,
GLenum pname,
GLint param
);
函数参数的含义:
target —— 目标纹理,必须为GL_TEXTURE_1D或GL_TEXTURE_2D;
pname —— 用来设置纹理映射过程中像素映射的问题等,取值可以为:GL_TEXTURE_MIN_FILTER、GL_TEXTURE_MAG_FILTER、GL_TEXTURE_WRAP_S、GL_TEXTURE_WRAP_T,详细含义可以查看MSDN;
param —— 实际上就是pname的值,可以参考MSDN。
另外,该类函数还有两个:
void glTexParameterfv(
GLenum target,
GLenum pname,
const GLfloat *params
);
void glTexParameteriv(
GLenum target,
GLenum pname,
const GLint *params
);
上述程序中调用如下:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
功能就是实现线形滤波的功能,当纹理映射到图形表面以后,如果因为其它条件的设置导致纹理不能更好地显示的时候,进行过滤,按照指定的方式进行显示,可能会过滤掉显示不正常的纹理像素。
纹理映射过程
纹理映射的过程是在DrawGLScene函数中实现的,也就是在绘制图形的过程中,直接进行我呢里映射,或者称为,为指定的平面贴纹理,DrawGLScene函数实现如下所示:
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
// Front Face
glBindTexture(GL_TEXTURE_2D, texture[0]); // 选择第一个纹理texture[0],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
// Back Face
glBindTexture(GL_TEXTURE_2D, texture[1]); // 选择第二个纹理texture[1],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glEnd();
// Top Face
glBindTexture(GL_TEXTURE_2D, texture[2]); // 选择第三个纹理texture[2],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glEnd();
// Bottom Face
glBindTexture(GL_TEXTURE_2D, texture[3]); // 选择第四个纹理texture[3],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
// Right face
glBindTexture(GL_TEXTURE_2D, texture[4]); // 选择第五个纹理texture[4],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glEnd();
// Left Face
glBindTexture(GL_TEXTURE_2D, texture[5]); // 选择第六个纹理texture[5],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
return TRUE;
}
因为,通过前面的过程,已经将位图加载并创建和加载纹理成功,纹理数组已经存在于内存之中,调用上述函数实现纹理映射,即,从内存中取出指定的纹理,将其映射到立方体的指定的面上。
上述函数中调用了glTexCoord2f函数,设置纹理坐标,该函数的声明如下所示:
void glTexCoord2f(
GLfloat s,
GLfloat t
);
glTexCoord2f 的第一个参数是X坐标,当s=0.0f 时是纹理的左侧,s=0.5f 时是纹理的中点,s=1.0f 时是纹理的右侧。 glTexCoord2f 的第二个参数是Y坐标,t=0.0f 是纹理的底部,t=0.5f 是纹理的中点, t=1.0f 是纹理的顶部。
上述函数在为前面那个面映射纹理的时候调用如下:
// Front Face
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
其中:
glTexCoord2f(0.0f, 0.0f);表示将纹理texture[0]的左下角坐标(0.0f, 0.0f)映射到立方体前面那个面的顶点(-1.0f, -1.0f, 1.0)上;
glTexCoord2f(1.0f, 0.0f);表示将纹理texture[0]的右下角坐标(1.0f, 0.0f)映射到立方体前面那个面的顶点(1.0f, -1.0f, 1.0f)上;
glTexCoord2f(1.0f, 1.0f);表示将纹理texture[0]的右上角坐标(1.0f, 1.0f)映射到立方体前面那个面的顶点(1.0f, 1.0f, 1.0f)上;
glTexCoord2f(0.0f, 1.0f);表示将纹理texture[0]的左上角坐标(0.0f, 1.0f)映射到立方体前面那个面的顶点(-1.0f, 1.0f, 1.0f)上。
这样,纹理texture[0]就被映射到了立方体前面那个面上。
纹理映射结果
为了使立方体能够运动起来,对立方体进行累的旋转变换,而且,定义了三个全局变量:
GLfloat xrot; // 沿着x旋转的变量
GLfloat yrot; // 沿着y旋转的变量
GLfloat zrot; // 沿着z旋转的变量
初始化都为0,然后,在每次调用DrawGLScene函数的时候,改变x、y、z的分量值,在DrawGLScene函数中如下所示:
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
在DrawGLScene函数中还要执行旋转变换:
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
//////////////////////////////////////////////////////////////////////
今天纠结于怎么在一个图上画多个图形,分别贴上纹理,看完了上面的文章,恍然大悟。改改代码,总算成功了。
在android中的实现代码如下,
首先在onSurfaceCreate()的时候,要先把这些图像载入进来,读取到内存中,给它们分配textureID.
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
/*
* By default, OpenGL enables features that improve quality
* but reduce performance. One might want to tweak that
* especially on software renderer.
*/
glDisable(GL_DITHER);
/*
* Some one-time OpenGL initialization can be made here
* probably based on features of this particular context
*/
glHint(GL_PERSPECTIVE_CORRECTION_HINT,
GL_FASTEST);
glClearColor(.5f, .5f, .5f, 1);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
/*
* Create our texture. This has to be done each time the
* surface is created.
*/
int[] textures = new int[2];
//这里是给textures这个数组中的每一个id,创建一个对应的纹理。第一个参数是1.
glGenTextures(1, textures, 0);
mTextureID = textures[0];
textureID2 = textures[1];
for(int i=0;i<textures.length;i++){
//之前已经创建好了纹理,这一步可以想象为有一个隐藏的局部变量a,我们把这个变量a指向之前在内存中分配好的一个纹理textures[i].
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_REPLACE);
//读取图像文件
InputStream is;
if(i == 0){
is = mContext.getResources().openRawResource(R.drawable.robot);
}else{
is = mContext.getResources()
.openRawResource(R.drawable.yellow);
}
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
try {
is.close();
} catch(IOException e) {
// Ignore.
}
}
//这里就用到了之前所说的那个隐藏的变量a,
//把bitmap写到a所指向的那个texture里面。
GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
}
存好之后,要使用如下:
public void onDrawFrame(GL10 gl) {
/*
* By default, OpenGL enables features that improve quality
* but reduce performance. One might want to tweak that
* especially on software renderer.
*/
glDisable(GL_DITHER);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_MODULATE);
/*
* Usually, the first thing one might want to do is to clear
* the screen. The most efficient way of doing this is to use
* glClear().
*/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*
* Now we're ready to draw some 3D objects
*/
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glActiveTexture(GL_TEXTURE0);
//隐藏局部变量a,指向一个texture.之前是指到那块内存,然后写进去
//这里是拿出来用的。
glBindTexture(GL_TEXTURE_2D, mTextureID);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_REPEAT);
/*long time = SystemClock.uptimeMillis() % 4000L;
float angle = 0.090f * ((int) time);
glRotatef(angle, 0, 0, 1.0f);
*/
rectangle.draw(gl);//这里用texture1作为纹理。
//绑定texture2,作为纹理。
glBindTexture(GL_TEXTURE_2D, textureID2);
tri.draw(gl);
}
rectangle的draw()和trig的draw()方法是一样的:
public void draw(GL10 gl) {
glFrontFace(GL_CCW);
glVertexPointer(3, GL_FLOAT, 0, mFVertexBuffer);//指定轮廓
glEnable(GL_TEXTURE_2D);
glTexCoordPointer(2, GL_FLOAT, 0, mTexBuffer);//指定纹理位置
glDrawElements(GL_TRIANGLE_STRIP, VERTS,
GL_UNSIGNED_SHORT, mIndexBuffer);//画图
}
在使用GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);的时候,可以不调用glBindTexture(),把图像载入到当前默认的一个texture里面,后面draw()的时候也不必去glBindTexture()。但这只能载入一个图像,多个的话就不行了,必须指定texture,每个图像绑定到一个texture上面。
没有源码~
OpenGL可以把纹理映射到指定的图形的表面上。简单一点的,就是给平面映射纹理,比如一个四边形,一个长方体的6个面,都可以指定位图作为纹理映射到各个面上。
关于将一个位图作为纹理映射到某个或者多个面上,可以学习Jeff Molofee的OpenGL系列教程。
对于指定的多个纹理,要根据自己的需要映射到不同的面上,需要对位图创建一个数组,用来存储位图的名称,然后在初始化OpenGL的时候,可以读取这些位图,然后生成多个纹理存储到一个纹理数组中,接着就可以指定绘制的某个面,对该指定的面进行纹理映射。
下面,在的Jeff Molofee教程的第六课的基础上,实现对6个面分别进行不同的纹理映射。
准备工作就是制作6幅不同的位图,如图所示:
关键代码及其说明如下。
创建全局纹理数组
GLuint texture[6]; // 创建一个全局的纹理数组,用来存储将位图转换之后得到的纹理,对应于立方体的6个面
加载位图文件
加载位图,也就是把位图读取到内存空间,实现纹理的创建,加载位图的函数说明一下:
AUX_RGBImageRec *LoadBMP(char *Filename) // 根据位图文件的名称进行加载
{
FILE *File=NULL; // 文件指针
if (!Filename) // 如果没有指定位图文件名称就返回NULL
{
return NULL;
}
File=fopen(Filename,"r"); // 根据指定的位图文件名称,打开该位图文件
if (File) // 如果位图文件存在
{
fclose(File); // 因为只是需要判断问题是否存在,而不需要对位图文件进行写操作,所以关闭位图文件
return auxDIBImageLoad(Filename); // 其实,只需要一个真正存在的位图文件的名称,实现加载位图文件,并返回一个指针
}
return NULL; // 位图文件加载失败就返回NULL
}
上面实现加载位图的函数中,AUX_RGBImageRec是glaux.h中定义的类型,该类型的定义如下所示:
/*
** RGB Image Structure
*/
typedef struct _AUX_RGBImageRec {
GLint sizeX, sizeY;
unsigned char *data;
} AUX_RGBImageRec;
首先,AUX_RGBImageRec类型是一个RGB图像结构类型。该结构定义了三个成员:
sizeX —— 图像的宽度;
sizeY —— 图像的高度;
data; —— 图形所包含的数据,其实也就是该图形在内存中的像素数据的一个指针。
AUX_RGBImageRec类型的变量描述了一幅图像的特征。
上述函数中,调用了glaux.h库文件中的auxDIBImageLoad函数,其实它是一个宏,函数原型为auxRGBImageLoadW(LPCWSTR)或者auxRGBImageLoadA(LPCSTR),可以在该库文件中找到它的定义,如下所示:
/* AUX_RGBImageRec * APIENTRY auxRGBImageLoad(LPCTSTR); */
#ifdef UNICODE
#define auxRGBImageLoad auxRGBImageLoadW
#else
#define auxRGBImageLoad auxRGBImageLoadA
#endif
AUX_RGBImageRec * APIENTRY auxRGBImageLoadA(LPCSTR);
AUX_RGBImageRec * APIENTRY auxRGBImageLoadW(LPCWSTR);
#ifdef UNICODE
#define auxDIBImageLoad auxDIBImageLoadW
#else
#define auxDIBImageLoad auxDIBImageLoadA
#endif
AUX_RGBImageRec * APIENTRY auxDIBImageLoadA(LPCSTR);
AUX_RGBImageRec * APIENTRY auxDIBImageLoadW(LPCWSTR);
宏auxDIBImageLoad实现的功能就是:根据指定的位图名称,将该位图的信息加载到内存中,以便用来创建成为纹理。
创建纹理并加载纹理
用于创建并加载纹理的函数为LoadGLTextures,实现如下所示:
int LoadGLTextures() // 根据加载的位图创建纹理
{
int Status=FALSE; // 指示纹理创建是否成功的标志
AUX_RGBImageRec *TextureImage[6]; // 创建一个纹理图像数组,这里指定数组大小为6
memset(TextureImage,0,sizeof(void *)*6); // 初始化纹理图像数组,为其分配内存
char *pictures[] = { // 创建一个位图名称数组,对应6幅位图
"Data/No1.bmp",
"Data/No2.bmp",
"Data/No3.bmp",
"Data/No4.bmp",
"Data/No5.bmp",
"Data/No6.bmp"
};
for(int i=0; i<6; i++) // 遍历位图名称数组,根据位图名称分别生成
{
if (TextureImage[i]=LoadBMP(pictures[i])) // 加载位图i成功,修改状态标志变量Status为TRUE
{
Status=TRUE;
glGenTextures(1, &texture[i]); // 为第i个位图创建纹理
glBindTexture(GL_TEXTURE_2D, texture[i]); // 将生成的纹理的名称绑定到指定的纹理上
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
if (TextureImage[i]) // 释放位图数组占用的内存空间
{
if (TextureImage[i]->data)
{
free(TextureImage[i]->data);
}
free(TextureImage[i]);
}
}
return Status; // 创建纹理并加载,返回成功或者失败的标志Status
}
上述函数是创建和加载纹理的核心实现。
1、glGenTextures函数
其中,调用了glGenTextures函数,查看MSDN可以看到,声明如下所示:
void glGenTextures(
GLsizei n,
GLuint * textures
);
函数参数的含义:
n —— 生成的纹理的名称的个数;
textures —— 生成的纹理名称所存储位置的指针,也就是一个纹理数组的内存地址,或者说是数组首元素的内存地址。
函数被调用,会生成一系列纹理的名字,并存储到指定的数组中。
2、glBindTexture函数
glBindTexture函数实现了将调用glGenTextures函数生成的纹理的名字绑定到对应的目标纹理上。该函数的声明如下所示:
void glBindTexture(
GLenum target,
GLuint texture
);
函数参数的含义:
target —— 纹理被绑定的目标,它只能取值GL_TEXTURE_1D或者GL_TEXTURE_2D;
texture —— 纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用。
3、glTexImage2D函数
调用glTexImage2D函数,用来指定二维纹理图像。该函数的声明如下所示:
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 —— 指定图像级别的编号,0表示基本图像,其它可以参考MSDN;
components —— 纹理中颜色组件的编号,可是是1或2或3或4;
width —— 纹理图像的宽度;
height —— 纹理图像的高度;
border —— 纹理图像的边框宽度,必须是0或1;
format —— 指定像素数据的格式,一共有9个取值:GL_COLOR_INDEX、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_RGB、GL_RGBA、GL_BGR_EXT、GL_BGRA_EXT、GL_LUMINANCE、GL_LUMINANCE_ALPHA ,具体含义可以参考MSDN;
type —— 像素数据的数据类型,取值可以为GL_UNSIGNED_BYTE, GL_BYTE, GL_BITMAP, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, and GL_FLOAT;
pixels —— 内存中像素数据的指针。
4、glTexParameteri函数
glTexParameteri函数或者glTexParameterf函数用来设置纹理参数,声明如下所示:
void glTexParameterf(
GLenum target,
GLenum pname,
GLfloat param
);
void glTexParameteri(
GLenum target,
GLenum pname,
GLint param
);
函数参数的含义:
target —— 目标纹理,必须为GL_TEXTURE_1D或GL_TEXTURE_2D;
pname —— 用来设置纹理映射过程中像素映射的问题等,取值可以为:GL_TEXTURE_MIN_FILTER、GL_TEXTURE_MAG_FILTER、GL_TEXTURE_WRAP_S、GL_TEXTURE_WRAP_T,详细含义可以查看MSDN;
param —— 实际上就是pname的值,可以参考MSDN。
另外,该类函数还有两个:
void glTexParameterfv(
GLenum target,
GLenum pname,
const GLfloat *params
);
void glTexParameteriv(
GLenum target,
GLenum pname,
const GLint *params
);
上述程序中调用如下:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
功能就是实现线形滤波的功能,当纹理映射到图形表面以后,如果因为其它条件的设置导致纹理不能更好地显示的时候,进行过滤,按照指定的方式进行显示,可能会过滤掉显示不正常的纹理像素。
纹理映射过程
纹理映射的过程是在DrawGLScene函数中实现的,也就是在绘制图形的过程中,直接进行我呢里映射,或者称为,为指定的平面贴纹理,DrawGLScene函数实现如下所示:
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
// Front Face
glBindTexture(GL_TEXTURE_2D, texture[0]); // 选择第一个纹理texture[0],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
// Back Face
glBindTexture(GL_TEXTURE_2D, texture[1]); // 选择第二个纹理texture[1],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glEnd();
// Top Face
glBindTexture(GL_TEXTURE_2D, texture[2]); // 选择第三个纹理texture[2],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glEnd();
// Bottom Face
glBindTexture(GL_TEXTURE_2D, texture[3]); // 选择第四个纹理texture[3],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
// Right face
glBindTexture(GL_TEXTURE_2D, texture[4]); // 选择第五个纹理texture[4],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glEnd();
// Left Face
glBindTexture(GL_TEXTURE_2D, texture[5]); // 选择第六个纹理texture[5],进行贴纹理
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
return TRUE;
}
因为,通过前面的过程,已经将位图加载并创建和加载纹理成功,纹理数组已经存在于内存之中,调用上述函数实现纹理映射,即,从内存中取出指定的纹理,将其映射到立方体的指定的面上。
上述函数中调用了glTexCoord2f函数,设置纹理坐标,该函数的声明如下所示:
void glTexCoord2f(
GLfloat s,
GLfloat t
);
glTexCoord2f 的第一个参数是X坐标,当s=0.0f 时是纹理的左侧,s=0.5f 时是纹理的中点,s=1.0f 时是纹理的右侧。 glTexCoord2f 的第二个参数是Y坐标,t=0.0f 是纹理的底部,t=0.5f 是纹理的中点, t=1.0f 是纹理的顶部。
上述函数在为前面那个面映射纹理的时候调用如下:
// Front Face
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
其中:
glTexCoord2f(0.0f, 0.0f);表示将纹理texture[0]的左下角坐标(0.0f, 0.0f)映射到立方体前面那个面的顶点(-1.0f, -1.0f, 1.0)上;
glTexCoord2f(1.0f, 0.0f);表示将纹理texture[0]的右下角坐标(1.0f, 0.0f)映射到立方体前面那个面的顶点(1.0f, -1.0f, 1.0f)上;
glTexCoord2f(1.0f, 1.0f);表示将纹理texture[0]的右上角坐标(1.0f, 1.0f)映射到立方体前面那个面的顶点(1.0f, 1.0f, 1.0f)上;
glTexCoord2f(0.0f, 1.0f);表示将纹理texture[0]的左上角坐标(0.0f, 1.0f)映射到立方体前面那个面的顶点(-1.0f, 1.0f, 1.0f)上。
这样,纹理texture[0]就被映射到了立方体前面那个面上。
纹理映射结果
为了使立方体能够运动起来,对立方体进行累的旋转变换,而且,定义了三个全局变量:
GLfloat xrot; // 沿着x旋转的变量
GLfloat yrot; // 沿着y旋转的变量
GLfloat zrot; // 沿着z旋转的变量
初始化都为0,然后,在每次调用DrawGLScene函数的时候,改变x、y、z的分量值,在DrawGLScene函数中如下所示:
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
在DrawGLScene函数中还要执行旋转变换:
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
//////////////////////////////////////////////////////////////////////
今天纠结于怎么在一个图上画多个图形,分别贴上纹理,看完了上面的文章,恍然大悟。改改代码,总算成功了。
在android中的实现代码如下,
首先在onSurfaceCreate()的时候,要先把这些图像载入进来,读取到内存中,给它们分配textureID.
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
/*
* By default, OpenGL enables features that improve quality
* but reduce performance. One might want to tweak that
* especially on software renderer.
*/
glDisable(GL_DITHER);
/*
* Some one-time OpenGL initialization can be made here
* probably based on features of this particular context
*/
glHint(GL_PERSPECTIVE_CORRECTION_HINT,
GL_FASTEST);
glClearColor(.5f, .5f, .5f, 1);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
/*
* Create our texture. This has to be done each time the
* surface is created.
*/
int[] textures = new int[2];
//这里是给textures这个数组中的每一个id,创建一个对应的纹理。第一个参数是1.
glGenTextures(1, textures, 0);
mTextureID = textures[0];
textureID2 = textures[1];
for(int i=0;i<textures.length;i++){
//之前已经创建好了纹理,这一步可以想象为有一个隐藏的局部变量a,我们把这个变量a指向之前在内存中分配好的一个纹理textures[i].
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_REPLACE);
//读取图像文件
InputStream is;
if(i == 0){
is = mContext.getResources().openRawResource(R.drawable.robot);
}else{
is = mContext.getResources()
.openRawResource(R.drawable.yellow);
}
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
try {
is.close();
} catch(IOException e) {
// Ignore.
}
}
//这里就用到了之前所说的那个隐藏的变量a,
//把bitmap写到a所指向的那个texture里面。
GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
}
存好之后,要使用如下:
public void onDrawFrame(GL10 gl) {
/*
* By default, OpenGL enables features that improve quality
* but reduce performance. One might want to tweak that
* especially on software renderer.
*/
glDisable(GL_DITHER);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_MODULATE);
/*
* Usually, the first thing one might want to do is to clear
* the screen. The most efficient way of doing this is to use
* glClear().
*/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*
* Now we're ready to draw some 3D objects
*/
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glActiveTexture(GL_TEXTURE0);
//隐藏局部变量a,指向一个texture.之前是指到那块内存,然后写进去
//这里是拿出来用的。
glBindTexture(GL_TEXTURE_2D, mTextureID);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_REPEAT);
/*long time = SystemClock.uptimeMillis() % 4000L;
float angle = 0.090f * ((int) time);
glRotatef(angle, 0, 0, 1.0f);
*/
rectangle.draw(gl);//这里用texture1作为纹理。
//绑定texture2,作为纹理。
glBindTexture(GL_TEXTURE_2D, textureID2);
tri.draw(gl);
}
rectangle的draw()和trig的draw()方法是一样的:
public void draw(GL10 gl) {
glFrontFace(GL_CCW);
glVertexPointer(3, GL_FLOAT, 0, mFVertexBuffer);//指定轮廓
glEnable(GL_TEXTURE_2D);
glTexCoordPointer(2, GL_FLOAT, 0, mTexBuffer);//指定纹理位置
glDrawElements(GL_TRIANGLE_STRIP, VERTS,
GL_UNSIGNED_SHORT, mIndexBuffer);//画图
}
在使用GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);的时候,可以不调用glBindTexture(),把图像载入到当前默认的一个texture里面,后面draw()的时候也不必去glBindTexture()。但这只能载入一个图像,多个的话就不行了,必须指定texture,每个图像绑定到一个texture上面。
评论
3 楼
seya
2010-10-10
ynw520 写道
兄弟,能把你的这个的源码发给我吗?
251719087@qq.com
非常感谢!
251719087@qq.com
非常感谢!
没有源码~
2 楼
xnewer
2010-09-15
很好的示例
1 楼
ynw520
2009-12-28
兄弟,能把你的这个的源码发给我吗?
251719087@qq.com
非常感谢!
251719087@qq.com
非常感谢!
发表评论
-
基于Java NIO的手机答题游戏开发
2014-03-31 17:59 1796先上个游戏截图: 豌豆荚地址: http://apps.w ... -
enable android deviceconnection under linux
2013-04-24 15:45 1010开发环境搭建完毕,Eclipse,Java,ADT都已经折腾 ... -
set CCache for building android source code
2013-04-24 15:14 1195Setting up ccache You can opti ... -
android 源码下载403 forbidden, 406 not acceptable 错误
2013-04-24 08:46 2454解决方法 1. 浏览器登录https://android.g ... -
ubuntu11.10 编译android4.0 错处
2013-04-08 21:45 1230今天使用ubuntu11.10编译android4.0出现以下 ... -
常用WebService列表
2013-01-31 23:22 2642快递查询接口 http://webservice.36wu.c ... -
startActivityForResult 无响应问题
2013-01-24 13:57 3865今天开发遇到了个问题, 就是从一个Activity中使用sta ... -
Android中仿新浪微博刷新列表
2012-11-22 17:35 7346大家看到新浪微博中的列表往下拉的时候, 头部出现正在刷新,然后 ... -
Grid调整间距
2012-09-29 08:52 1750今天使用GridView, 发现点中某一Item时选中部分的背 ... -
android gallery和Animation组合使用, 看美女美图
2012-09-11 21:01 4456今天主要探究Gallery和Animation的使用。 制作一 ... -
Android执行 shell command
2012-03-24 17:00 7273Android执行shell命令 一、方法 1. /* ... -
BBBBBB111
2012-03-23 11:42 10陈波: 本周:代码review,解决findbugs中bug以 ... -
MonkeyTestError
2012-03-21 10:15 903-20 21:36:42.439 W/dalvikvm( ... -
INSTALL_FAILED_OLDER_SDK ERROR
2012-03-12 15:52 4476Install APK with adb: $ platfo ... -
4.0源码编译问题
2012-03-07 17:12 31601、fatal error: GL/glx.h: No suc ... -
4.0 编译apk中无classes.dex
2012-03-07 17:11 3974下载完android 4.0代码,模拟器里面的gallery不 ... -
Android 4.0源码编译错误
2012-03-05 10:19 2584UNEXPECTED TOP-LEVEL EXCEPTION: ... -
AndroidLockScreenDemo
2012-02-18 15:54 1000锁屏解锁的成功案例。 -
G14 root权限获取
2012-02-13 23:36 2871HTC G14 ROOT权限获取后就能删除系统自带的程序,相信 ... -
锁屏d ds
2011-12-15 00:49 911private final IDevicePolicyMana ...
相关推荐
在OpenGL中,纹理贴图是给3D模型增添细节和真实感的关键技术。本教程将深入探讨如何使用VA(Vertex Array)模式实现纹理贴图。 纹理贴图是指将2D图像(纹理)映射到3D模型表面,通过这种方式增加模型的视觉信息。在...
纹理贴图是OpenGL ES中的一个重要概念,它允许我们为几何体表面添加复杂的视觉效果,如图像或颜色图案。在本篇中,我们将深入探讨OpenGL ES 1.0中的纹理贴图技术。 首先,理解纹理的基本概念至关重要。纹理可以看作...
在“Opengl ES 1.x NDK实例开发之七:旋转的纹理立方体”这个实例中,我们将深入探讨如何通过OpenGL ES和NDK在Android上创建一个旋转的纹理立方体。 首先,理解基本概念是关键。纹理立方体是一种将六个不同图像分别...
本文将深入探讨如何在Android应用程序中使用OpenGL ES进行纹理贴图,这是构建复杂图形场景的关键技术。 纹理贴图是将图像数据(通常是一个二维数组)应用到3D模型表面的过程,使得模型表面具有丰富的视觉效果。在...
本教程将深入探讨如何在OpenGL ES环境中实现纹理贴图,特别是在Android平台上。 一、纹理贴图基础 纹理贴图是3D图形学中的一个重要概念,它允许我们在3D模型表面添加丰富的视觉细节。纹理就像真实物体表面的图案或...
圆锥纹理贴图是OpenGL ES中的一种技术,用于在三维模型上应用纹理,使得图像更具真实感。这个教程或代码示例可能是为了帮助开发者理解如何在Android平台上使用OpenGL ES为圆锥形几何体添加纹理。 在OpenGL ES中,...
在OpenGLES编程中,...总之,OpenGLES中的材质贴图是一个涉及资源加载、纹理坐标、纹理对象管理等多个环节的过程。通过本教程的学习,开发者将能更好地理解和实现这一核心图形技术,为iOS应用添加更丰富的视觉元素。
本主题将深入探讨如何在Android中利用OpenGL ES进行纹理贴图,特别是如何在一个正方体的六个面上应用不同的纹理图片。这个过程涉及到多个关键步骤和技术,包括纹理坐标、纹理单元、纹理对象的创建以及纹理映射等。 ...
在这个名为“Android应用源码OpenGL 3D立方体多纹理贴图”的项目中,开发者将展示如何在Android应用中利用OpenGL ES实现3D立方体,并进行多纹理贴图。 首先,理解OpenGL ES的基本概念至关重要。OpenGL ES提供了一组...
【OpenGL】二十四、OpenGL 纹理贴图 ( 读取文件内容 | 桌面程序添加控制台窗口 | ‘fopen‘: This function may be unsafe 错误处理 ) https://hanshuliang.blog.csdn.net/article/details/113001095 博客源码 ( 该...
在本主题“opengles绘制纹理”中,我们将深入探讨如何在OpenGL ES环境中加载和绘制纹理,以增强图形渲染的质量和表现力。 1. **纹理的概念** 在计算机图形学中,纹理是指附加到几何形状上的二维图像数据,用于给...
这个源码示例将帮助开发者理解如何在Android环境中使用OpenGL ES进行3D图形渲染,特别是如何实现多纹理贴图,为更复杂的游戏或应用开发打下基础。通过学习和分析这个项目,可以提升对3D图形编程的理解和实践能力。
在这个项目中,"android opengl-ES 魔方 纹理贴图"的主题涉及到在Android设备上使用OpenGL-ES来创建一个旋转的三维魔方,并且为每个面应用纹理贴图,同时实现手势识别功能来操控魔方的转动。 首先,我们来看一下...
OpenGL ES纹理贴图是移动设备和嵌入式系统中3D图形编程的重要组成部分。它允许开发者将复杂的图像数据应用到3D模型上,为场景增添真实感和视觉吸引力。在这个主题中,我们将深入探讨OpenGL ES纹理贴图以及如何实现...
这个"Android OpenGL 3D 立方体多纹理贴图源码"是一个很好的学习资源,它涵盖了多个关键的OpenGL ES编程概念。 首先,3D立方体的渲染是OpenGL ES的基本应用之一,它展示了如何构建基本的几何形状。在3D空间中,一个...
在压缩包文件"opengles7_4"中,可能包含了实现多重纹理和过程纹理的示例代码、纹理图像文件以及相关的教程文档。通过研究这些资源,你可以深入学习如何在OpenGL ES环境中实现这两种纹理技术,并应用于自己的项目中,...
本项目"Android应用源码OpenGL 3D立方体多纹理贴图"是一个示例,展示了如何在Android平台上利用OpenGL ES(OpenGL针对嵌入式系统的版本)进行3D图形渲染,并实现多纹理贴图。下面我们将深入探讨其中涉及的关键知识点...
在"opengles多重纹理动画"这个主题中,我们将深入探讨如何在OpenGL ES中实现多重纹理效果,以及如何将这些效果应用到动态动画中。 在OpenGL ES中,多重纹理是一种高级图形技术,它允许在一个像素着色过程中同时使用...
总的来说,实现OpenGL ES中的立方体贴图涉及多个步骤,包括创建和加载纹理,设置纹理参数,编写和使用着色器,以及正确地绘制3D几何体。这个过程需要对OpenGL ES的纹理管理和渲染管线有深入的理解,但一旦掌握,就能...
本教程将详细讲解如何在Android Studio中利用OpenGL ES绘制一个三棱锥,并对其表面进行纹理贴图,使三棱锥的各个面展示出不同的图像效果。 首先,我们需要在Android Studio项目中设置OpenGL ES环境。创建一个新的...