OpenGL如何读取并使用两张纹理

OpenGL如何读取并使用两张纹理

1、读取一张纹理图片

		virtual unsigned    loadTexture(const char* fileName)
		{
			unsigned    textureId = 0;
			//1 获取图片格式
			FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);

			//2 加载图片
			FIBITMAP    *dib = FreeImage_Load(fifmt, fileName, 0);

			//3 转化为rgb 24色
			dib = FreeImage_ConvertTo32Bits(dib);


			//4 获取数据指针
			BYTE    *pixels = (BYTE*)FreeImage_GetBits(dib);

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

			for (size_t i = 0; i < width * height * 4; i += 4)
			{
				BYTE temp = pixels[i];
				pixels[i] = pixels[i + 2];
				pixels[i + 2] = temp;
			}

			/**
			*   产生一个纹理Id,可以认为是纹理句柄,后面的操作将书用这个纹理id
			GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures)
			n:用来生成纹理的数量;textures:存储纹理索引的第一个元素指针
			*/
			glGenTextures(1, &textureId);

			/**
			*   使用这个纹理id,或者叫绑定(关联)
			将纹理索引绑定到目标纹理
			*/
			glBindTexture(GL_TEXTURE_2D, textureId);
			/**
			*   指定纹理的放大,缩小滤波,使用线性方式,即当图片放大的时候插值方式
			*/
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			/**
			*   将图片的rgb数据上传给opengl.
			*/
			glTexImage2D(
				GL_TEXTURE_2D,      //! 指定是二维图片
				0,                  //! 指定为第一级别,纹理可以做mipmap,即lod,离近的就采用级别大的,远则使用较小的纹理
				GL_RGBA,             //! 纹理的使用的存储格式
				width,              //! 宽度,老一点的显卡,不支持不规则的纹理,即宽度和高度不是2^n。
				height,             //! 宽度,老一点的显卡,不支持不规则的纹理,即宽度和高度不是2^n。
				0,                  //! 是否有边框
				GL_RGBA,             //! 数据的格式,bmp中,windows,操作系统中存储的数据是bgr格式
				GL_UNSIGNED_BYTE,   //! 数据是8bit数据
				pixels
			);
			/**
			*   释放内存
			*/
			FreeImage_Unload(dib);

			return  textureId;
		}

2、使用它

		virtual void render()
		{
			struct Vertex
			{
				CELL::float2 pos;
				CELL::float2 uv;
				CELL::Rgba4Byte color;
			};
			//清空缓冲区
			glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
			//视口,在windows窗口指定的位置和大小上绘制OpenGL内容
			glViewport(0, 0, _width, _height);

			//创建一个投影矩阵
			CELL::matrix4 screenProj = CELL::ortho<float>(0, float(_width), 0, float(_height), -100.0f, 100);
			_shader.begin();
			{
				float x = 100;
				float y = 100;
				float w = 260;
				float h = 400;
				static float uvAnima = 0;
                //顶点坐标数组
				Vertex vertex[] =
				{
				CELL::float2(x,y),		  CELL::float2(0,0),	CELL::Rgba4Byte(255,255,255,255),
                    
				CELL::float2(x + w,y),    CELL::float2(1,0),	CELL::Rgba4Byte(255,255,255,255),
                    
				CELL::float2(x,y + h),    CELL::float2(0,1),	CELL::Rgba4Byte(255,255,255,255),
                    
				CELL::float2(x + w,y + h),CELL::float2(1,1),	CELL::Rgba4Byte(255,255,255,255)
				};
                
				CELL::matrix4 matMVP = screenProj;
				uvAnima +=0.01f;
				glActiveTexture(GL_TEXTURE0);//激活0号纹理单元
				glBindTexture(GL_TEXTURE_2D, _textureId);//绑定textureId,到目标纹理,将textureId设置为当前纹理单元的操作纹理

				glActiveTexture(GL_TEXTURE1);//激活1号纹理单元
				glBindTexture(GL_TEXTURE_2D, _textureId1);//绑定textureId1,到目标纹理
                
				glUniform1i(_shader._textureId, 0);//传递0进去,
				//shader的texture2D(_textureId,_outUV);调用0号纹理单元的纹理
				glUniform1i(_shader._textureId1, 1);
                
                 glUniformMatrix4fv(_shader._MVP, 1, false, matMVP.data());
				glUniform1f(_shader._uvAnima, uvAnima);
				glVertexAttribPointer(_shader._position, 2, GL_FLOAT, false, sizeof(Vertex), vertex);
				glVertexAttribPointer(_shader._uv, 2, GL_FLOAT, false, sizeof(Vertex), &vertex[0].uv);
				glVertexAttribPointer(_shader._color, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &vertex[0].color);
				glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
			}
			_shader.end();
		}
上一篇:基于三维GIS技术的矢量地图动态LOD渲染方法


下一篇:Jenkins Pipeline