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();
}