OpenGLES---加载纹理

原创 2016年05月30日 15:29:43
{
	1:纹理介绍
	2:删除纹理
	3:两个概念
	4:添加代码
}



{1:纹理介绍
	把图像数据应用到几何图源时成为纹理或纹理贴图,纹理图像被加载后,具有和像素图像相同的排列和成分,但此时纹理单元和屏幕上的图像之间很少存在一对一的对应关系
	
	纹理(类型)
		一维纹理  sampler1D
		二维纹理  sampler2D(常用)
		三维纹理  sampler3D
		立体纹理  samplerCube
		阴影纹理
}

{2:删除纹理
	unsigned tId=0;
	glGenTextures(1,&tId);//生成纹理的索引
	...
	glDeleteTextures(1,&tId);
}

{3:两个概念
	一张纹理有10个层次[0,10] (512*512,256*256,128*128,...1*1 具体大小自己定) 可以全用也可以只用一个[0,10] 0最大,10最小
		glTexImage2D (GL_TEXTURE_2D,[0~10], format, width, height,0,format,GL_UNSIGNED_BYTE, pixels);

	一个面可以绑定32张纹理[GL_TEXTURE0~GL_TEXTURE031]
		unsigned t0=loadTexture("res/0.png");//加载纹理资源
		glActiveTexture(GL_TEXTURE0);//指定纹理级别(一张纹理不需要)
		glBindTexture(GL_TEXTURE_2D,t0);//绑定纹理
		glUniform1i(shader._tId0,0);//指定纹理阶段[0,31]

		unsigned t2=loadTexture("res/1.png");//加载纹理资源
		glActiveTexture(GL_TEXTURE1);//指定纹理级别(一张纹理不需要)
		glBindTexture(GL_TEXTURE_2D,t2);//绑定纹理
		glUniform1i(shader._tId1,1);//指定纹理阶段[0,31]
	...
}

4:添加代码

#include "freeImage/FreeImage.h"
	连接器->输入->附加依赖项 FreeImage.lib;

	{纹理加载步骤
		1:获取图片格式
		2:加载图片
		3:转化为rgb 24色或32色
		4:获取数据指针
		...插入OpenGL代码
		5:释放
	}

	GL_TEXTURE_MAG_FILTER  放大滤波(参数)
		GL_NEAREST
		GL_LINEAR

	GL_TEXTURE_MIN_FILTER  缩小滤波(参数)
		GL_NEAREST
		GL_LINEAR
		GL_NEAREST_MIPMAP_NEAREST
		GL_LINEAR_MIPMAP_NEAREST 
		GL_NEAREST_MIPMAP_LINEAR 
		GL_LINEAR_MIPMAP_LINEAR    最好级别


	virtual unsigned loadMinMap(char *fileName[],int fileSize){
		unsigned tId=0;

		//生成纹理的索引
		glGenTextures(1,&tId);
		//绑定纹理(把纹理句柄绑定成2d纹理)
		glBindTexture(GL_TEXTURE_2D,tId);

		//纹理的放大缩小滤波(场景远近图片大小)
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);

		for (int i=0;i<fileSize;i++){
			//1:获取图片格式
			FREE_IMAGE_FORMAT fifmt=FreeImage_GetFileType(fileName[i]);
			//2:加载图片
			FIBITMAP *dib=FreeImage_Load(fifmt,fileName[i],0);
			//3:转化为rgb
			int format=GL_RGB;
			if(fifmt==FIF_PNG) {
				dib=FreeImage_ConvertTo32Bits(dib);	//3:转化为rgb 32色
				format=GL_RGBA;
			}else{
				dib=FreeImage_ConvertTo24Bits(dib);//3:转化为rgb 24色
				format=GL_RGB;
			}
			//4:获取数据指针
			BYTE *pixels=(BYTE*)FreeImage_GetBits(dib);

			int width=FreeImage_GetWidth(dib);
			int height=FreeImage_GetHeight(dib);

			//得到的数据是BGR格式保存的(bgr -> rgb)
			if(fifmt==FIF_PNG){
				for (int j = 0 ;j < width * height * 4 ; j+=4 ){ //rgba
					BYTE temp       =   pixels[j];
					pixels[j]       =   pixels[j + 2];
					pixels[j + 2]   =   temp;
				}
			}else{
				for (int j = 0 ;j < width * height * 3 ; j+=3 ){//rgb颜色就
					BYTE temp       =   pixels[j];
					pixels[j]       =   pixels[j + 2];
					pixels[j + 2]   =   temp;
				}
			}
			glTexImage2D (GL_TEXTURE_2D,i, format, width, height,0,format,GL_UNSIGNED_BYTE, pixels);
			//5释放
			FreeImage_Unload(dib);
		}
		return tId;
	};

	virtual unsigned loadTexture(const char * fileName){
		unsigned tId=0;
		FREE_IMAGE_FORMAT fifmt=FreeImage_GetFileType(fileName);//1:获取图片格式
		FIBITMAP *dib=FreeImage_Load(fifmt,fileName,0);	//2:加载图片
		int format=GL_RGB;
		//3:转化为rgb 
		if(fifmt==FIF_PNG) {
			dib=FreeImage_ConvertTo32Bits(dib);	//3:转化为rgb 32色
			format=GL_RGBA;
		}else{
			dib=FreeImage_ConvertTo24Bits(dib);//3:转化为rgb 24色
			format=GL_RGB;
		}
		//4:获取数据指针
		BYTE *pixels=(BYTE*)FreeImage_GetBits(dib);

		int width=FreeImage_GetWidth(dib);
		int height=FreeImage_GetHeight(dib);

		//得到的数据是BGR格式保存的(bgr -> rgb)
		if(fifmt==FIF_PNG){
			for (int i = 0 ;i < width * height * 4 ; i+=4 ){ //rgba
				BYTE temp       =   pixels[i];
				pixels[i]       =   pixels[i + 2];
				pixels[i + 2]   =   temp;
			}
		}else{
			for (int i = 0 ;i < width * height * 3 ; i+=3 ){//rgb颜色就
				BYTE temp       =   pixels[i];
				pixels[i]       =   pixels[i + 2];
				pixels[i + 2]   =   temp;
			}
		}

		{//OpenGL加载Byte数据
			//生成纹理的索引
			glGenTextures(1,&tId);
			//绑定纹理(把纹理句柄绑定成2d纹理)
			glBindTexture(GL_TEXTURE_2D,tId);

			//纹理的放大缩小滤波(场景远近图片大小)
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

			/****** 将图片的rgb数据上传给opengl.
			* @param GLenum target  纹理是几维的
			* @param GLint level 制定纹理级别(0最大,9最小)
			* @param GLint internalformat 纹理存储格式(显冲用的纹理格式)
			* @param GLsizei width 宽度,老一点的显卡,不支持不规则的纹理,即宽度和高度不是2^n。
			* @param GLsizei height 高度,老一点的显卡,不支持不规则的纹理,即宽度和高度不是2^n。
			* @param GLint border 是否有边框
			* @param GLenum format 数据的格式(你的图片数据格式)
			* @param GLenum type 纹理数据类型
			* @param const GLvoid* pixels 纹理数据
			*/
			glTexImage2D (GL_TEXTURE_2D,0, format, width, height,0,format,GL_UNSIGNED_BYTE, pixels);

		}
		//5释放
		FreeImage_Unload(dib);
		return tId;
	}

	//加载纹理资源
	unsigned textureId=loadTexture("res/HelloWorld.png");//可以试试loadMinMap方法
	glActiveTexture(GL_TEXTURE0);//指定纹理级别(一张纹理不需要)
	glBindTexture(GL_TEXTURE_2D,textureId);//绑定纹理
	//指定纹理阶段[0,31]
	glUniform1i(shader._tId,0);


	//逆时针给坐标点,顺时针会出问题
	CELL::float2 pos[]={//坐标位置
		CELL::float2(x,y),
		CELL::float2(x+w,y),
		CELL::float2(x,y+h),
		CELL::float2(x+w,y+h)
	};
	CELL::float2 tpos[]={//纹理坐标
		CELL::float2(0,0),
		CELL::float2(1,0),
		CELL::float2(0,1),
		CELL::float2(1,1),
	};
	glVertexAttribPointer(shader._tpos,2,GL_FLOAT,false,sizeof(CELL::float2),tpos);
	注意:tpos和pos是对应写的

纹理位置和坐标位置对应


{Shader 
		uniform	     _tId; //纹理id
		attribute    _tpos; //纹理位置

		const char *vs={
			"precision lowp float;"
			"uniform   mat4 _MVP;"
			"attribute vec2 _position;"
			"attribute vec4 _color;"  //外边出入的颜色
			"varying   vec4 _outColor;" //共享颜色
			
			"attribute vec2	_tpos;" //纹理坐标
			"varying   vec2	_outTpos;"
			"void main(){"
			"	vec4 pos= vec4(_position,0,1);"
			"	_outColor = _color;"
			"	_outTpos = _tpos;"
			"	gl_Position=_MVP* pos;"
			"}"
		};
		const char *fs={
			"precision lowp float;"
			"varying	vec4	  _outColor;"
			"uniform   sampler2D  _tId;"     //纹理id
			"varying    vec2	  _outTpos;"
			"void main(){"
			"	vec4  tColor = texture2D(_tId,_outTpos);" //texture2D 给纹理坐标赋值
			"	gl_FragColor= tColor * _outColor;" //gl_FragColor 输出的颜色用于随后的像素操作
			"}"
		};

		_tpos   = glGetAttribLocation(shaderValue.pID,"_tpos");
		_tId    = glGetUniformLocation(shaderValue.pID,"_tId");


		//启用顶点数组(纹理坐标)
		glEnableVertexAttribArray(_tpos);
		//禁用顶点数组(纹理坐标)
		glDisableVertexAttribArray(_tpos);
	}

运行结果



图像是翻转的!目前还没有解决,谁知道也可有帮我解决一下


源码地址

http://pan.baidu.com/s/1geVargZ


相关文章推荐

从零开始学习OpenGL ES之六 – 纹理及纹理映射

在OpenGL ES中另一种为多边形定义颜色创建材质的方法是将纹理映射到多边形。这是一种很实用的方法,它可以产生很漂亮的外观并节省大量的处理器时间。比如说,你想在游戏中造一个砖墙。你当然可以创建一个具...

Android OpenGL es 纹理坐标设定与贴图规则

当opengl对一个四方形进行贴图时,会定义纹理贴图坐标,一串数组,相信初学openggl es者看到后会很头疼,不知道写得是什么东西。现在就将我的研究成果与大家分享下!当纹理映射启动后绘图时,你必须...
  • cjkwin
  • cjkwin
  • 2010年11月17日 21:17
  • 27859

Android OpenGL ES顶点坐标、纹理贴图坐标设置

做纹理贴图的时候具体的贴图坐标是如何设置纠结了很长时间,下面把关于顶点坐标和贴图坐标的设置xian...

OpenglES2.0 for Android:再谈纹理映射

OpenglES2.0 for Android:再谈纹理映射 上一节我们实现了一个简单的纹理映射的例子——一个简单的贴图,这节我们来做一些稍微复杂一点的例子,最后再使用我们前面实现的立方体来做一个...

OpenGL ES 2.0总结(2)-纹理

OpenGL ES 2.0 - 纹理1. 纹理初始化 1) glGenTextures() 生成纹理id,可以一次生成多个,后续操作纹理全靠这个id2) glBindTexture() 操作纹理,传入...
  • prahs
  • prahs
  • 2015年11月13日 15:10
  • 3700

opengles绘制纹理(一)

矩阵变换类 package test.com.opengles7_1; import android.opengl.Matrix; /** * Created by hbin on 2016/...

纹理(全解)

http://www.cnblogs.com/helinsen/archive/2012/08/01/2618539.html 纹理是增强计算机生成的三维图像的真实感的有力工具。Micros...

OpenGL9-(FreeImage)加载图片-作为纹理

/*** 这个例子展示如何使用FreeImage加载图片作为纹理* 初学者,在学习OpenGL的时候,往往因为OpenGL读图片没有那么方便* 而浪费了大量的时间在研究图片格式上,其实大可...

在OpenGL中使用FreeImage库生成纹理

在学习OpenGL纹理时,由于图片格式繁多,不能自己一一去实现图片解析,之前写了一个简单的Image库只支持bmp和tga,但现在很流行png图片,还有jpg图片等等,所以没办法一一去花时间写图片解析...

IOS OpenGLES2.0 入门04 加载纹理

如果我们要在OpenGLES2.0中显示纹理的话, 要依赖于Fragment Shader. OpenGL要有两个Shader, Vertex和Fragment Vertex用来管理顶点, 你要绘...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenGLES---加载纹理
举报原因:
原因补充:

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