需要用的SOIL
SOIL:Simple OpenGL Image Library
http://www.lonesock.net/soil.html
在包含目录和库目录设置SOIL的目录
使用SOIL读取图片为opengl设置纹理
#include <iostream>
#include <Windows.h>
#define _USE_MATH_DEFINES
#include <math.h>
// GLEW
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// SOIL
#include <SOIL.h>
GLuint WIDTH = 400, HEIGHT = 400;
GLfloat xRot = 0.0f;
GLfloat yRot = 0.0f;
#define TEXTURE_CNT 2
GLuint textures[TEXTURE_CNT];//存储2个纹理
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
void windowResize_callback(GLFWwindow* window, int width, int height);
void loadTexture(const char* filePath, int index)
{
int picWidth, picHeight;
int channel = 0;
unsigned char* imgData = SOIL_load_image(filePath,
&picWidth, &picHeight, &channel, SOIL_LOAD_RGB);
if (NULL == imgData)
{
OutputDebugString(L"SOIL_load_image failed \r\n");
return;
}
glGenTextures(1, &textures[index]);
glBindTexture(GL_TEXTURE_2D, textures[index]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, picWidth, picHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, imgData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 线形滤波
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 线形滤波
SOIL_free_image_data(imgData);
}
void DrawCube(void) // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glEnable(GL_TEXTURE_2D);//启用纹理贴图
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//指定纹理贴图与材质的混合模式
glColor4f(1.0, 1.0, 1.0, 1.0);
glLoadIdentity(); // 重置当前的模型观察矩阵
//glTranslatef(0.0f, 0.0f, -5.0f); // 移入屏幕 5 个单位
glRotatef(xRot, 1.0f, 0.0f, 0.0f); // 绕X轴旋转
glRotatef(yRot, 0.0f, 1.0f, 0.0f); // 绕Y轴旋转
glBindTexture(GL_TEXTURE_2D, textures[1]); // 选择纹理
glBegin(GL_QUADS);
// 前面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.5f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(0.5f, -0.5f, 0.5f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(0.5f, 0.5f, 0.5f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, 0.5f); // 纹理和四边形的左上
// 后面
glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5f, -0.5f, -0.5f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.5f, 0.5f, -0.5f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.5f, -0.5f, -0.5f); // 纹理和四边形的左下
// 顶面
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, 0.5f, 0.5f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(0.5f, 0.5f, 0.5f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(0.5f, 0.5f, -0.5f); // 纹理和四边形的右上
glEnd();
glFlush();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//指定纹理贴图与材质的混合模式
glBindTexture(GL_TEXTURE_2D, textures[0]); // 选择纹理
glBegin(GL_QUADS);
// 底面
glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5f, -0.5f, -0.5f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.5f, -0.5f, -0.5f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.5f, -0.5f, 0.5f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.5f); // 纹理和四边形的右下
// 右面
glTexCoord2f(1.0f, 0.0f); glVertex3f(0.5f, -0.5f, -0.5f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(0.5f, 0.5f, -0.5f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.5f, 0.5f, 0.5f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.5f, -0.5f, 0.5f); // 纹理和四边形的左下
// 左面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, -0.5f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.5f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 0.5f); glVertex3f(-0.5f, 0.5f, 0.5f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f); // 纹理和四边形的左上
glEnd();
glFlush();
}
void render(GLFWwindow* window)
{
glClearColor(1.0f, 0.8f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//DrawLine();
//DrawBezier();
//Draw3d();
DrawCube();
}
void initWindow(GLFWwindow* window)
{
glfwMakeContextCurrent(window);
//设置按键回调
glfwSetKeyCallback(window, key_callback);
//设置窗口大小改变的回调,让绘画区域在窗口中间
glfwSetWindowSizeCallback(window, windowResize_callback);
}
void initParam()
{
//显示规则:窗口左下角坐标为0,0;所以下行代码表示在窗口左下角向右向上的400个像素单位作为画布
glViewport(0, 0, WIDTH, HEIGHT);//设置显示区域400*400,但是可以拖动改变窗口大小
glLineWidth(3.0);//设置线条宽度,3个像素
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);//设置点圆滑
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);//设置线光滑
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
//启用文字,不支持汉字、unicode
void initData()
{
loadTexture("D:\\2.jpg", 0);
loadTexture("D:\\222huojian.jpg", 1);
}
int main()
{
glfwInit();
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL", nullptr, nullptr);
if (window == nullptr)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
initWindow(window);
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
initParam();
initData();
// Game loop
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
render(window);
glfwSwapBuffers(window);
}
// Terminate GLFW, clearing any resources allocated by GLFW.
glfwTerminate();
return 0;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if (key == GLFW_KEY_UP)
xRot -= 5.0f;
else if (key == GLFW_KEY_DOWN)
xRot += 5.0f;
else if (key == GLFW_KEY_LEFT)
yRot -= 5.0f;
else if (key == GLFW_KEY_RIGHT)
yRot += 5.0f;
}
void windowResize_callback(GLFWwindow* window, int width, int height)
{
WIDTH = HEIGHT = width > height ? height : width;
//左下角是0, 0坐标, x,y说就是相对于左下角的像素距离
glViewport((width - WIDTH) / 2, (height - HEIGHT) / 2, WIDTH, HEIGHT);
}
原理:
SOIL读取图片信息,宽高都要是2的倍数,图片不行就换图片,中能找到一个用得上的
创建的关键代码:
glGenTextures(1, &textures[index]);
glBindTexture(GL_TEXTURE_2D, textures[index]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, picWidth, picHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, imgData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 线形滤波
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 线形滤波
生成一个name,这个name实际是个int
绑定,
绑定后生成的纹理就对应创建的name。
使用的关键代码:
glEnable(GL_TEXTURE_2D);//启用纹理贴图
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//指定纹理贴图与材质的混合模式
glColor4f(1.0, 1.0, 1.0, 1.0);
glBindTexture(GL_TEXTURE_2D, textures[1]); // 选择纹理
启用纹理
设置模式
设置颜色:其实也没那么重要,除非有其他需要设置颜色的地方,这里就要重置自己的颜色
选择纹理,指定name,接下来就是使用指定的name贴图
效果: