关闭

OpenGLES---加载纹理

标签: OpenGL-ES 2.0OpenGLESopengl esShader
921人阅读 评论(1) 收藏 举报
分类:
{
	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


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:36429次
    • 积分:727
    • 等级:
    • 排名:千里之外
    • 原创:36篇
    • 转载:0篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论