试试二维纹理映射
转载https://github.com/wangdingqiao/noteForOpenGL/blob/master/textures/textures01/texture01.cpp
// 引入GLEW库 定义静态链接
#define GLEW_STATIC
#include <GLEW/glew.h>
// 引入GLFW库
#include <GLFW/glfw3.h>
// 引入SOIL库
#include <SOIL/SOIL.h>
#include
#include
// 包含着色器加载库
#include “shader.h”
// 键盘回调函数原型声明
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
// 定义程序常量
const int WINDOW_WIDTH = 800, WINDOW_HEIGHT = 600;
int main(int argc, char** argv)
{
if (!glfwInit()) // 初始化glfw库
{
std::cout << "Error::GLFW could not initialize GLFW!" << std::endl;
return -1;
}
// 开启OpenGL 3.3 core profile
std::cout << "Start OpenGL core profile version 3.3" << std::endl;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// 创建窗口
GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT,
"Demo of 2D texture", NULL, NULL);
if (!window)
{
std::cout << "Error::GLFW could not create winddow!" << std::endl;
glfwTerminate();
return -1;
}
// 创建的窗口的context指定为当前context
glfwMakeContextCurrent(window);
// 注册窗口键盘事件回调函数
glfwSetKeyCallback(window, key_callback);
// 初始化GLEW 获取OpenGL函数
glewExperimental = GL_TRUE; // 让glew获取所有拓展函数
GLenum status = glewInit();
if (status != GLEW_OK)
{
std::cout << "Error::GLEW glew version:" << glewGetString(GLEW_VERSION)
<< " error string:" << glewGetErrorString(status) << std::endl;
glfwTerminate();
return -1;
}
// 设置视口参数
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
// Section1 准备顶点数据
// 指定顶点属性数据 顶点位置 颜色 纹理
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f,0.0f, 0.0f, // 0
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,1.0f, 0.0f, // 1
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f,1.0f, 1.0f, // 2
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f,0.0f, 1.0f // 3
};
GLushort indices[] = {
0, 1, 2, // 第一个三角形
0, 2, 3 // 第二个三角形
};
// 创建缓存对象
GLuint VAOId, VBOId, EBOId;
// Step1: 创建并绑定VAO对象
glGenVertexArrays(1, &VAOId);
glBindVertexArray(VAOId);
// Step2: 创建并绑定VBO 对象 传送数据
glGenBuffers(1, &VBOId);
glBindBuffer(GL_ARRAY_BUFFER, VBOId);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Step3: 创建并绑定EBO 对象 传送数据
glGenBuffers(1, &EBOId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// Step4: 指定解析方式 并启用顶点属性
// 顶点位置属性
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
8 * sizeof(GL_FLOAT), (GLvoid*)0);
glEnableVertexAttribArray(0);
// 顶点颜色属性
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
8 * sizeof(GL_FLOAT), (GLvoid*)(3 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(1);
// 顶点纹理坐标
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE,
8 * sizeof(GL_FLOAT), (GLvoid*)(6 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(2);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // 注意不要解除EBO绑定
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Section2 准备着色器程序
Shader shader("triangle.vertex", "triangle.frag");
// Section3 准备纹理对象
// Step1 创建并绑定纹理对象
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
// Step2 设定wrap参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Step3 设定filter参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR); // 为MipMap设定filter方法
// Step4 加载纹理
GLubyte *imageData = NULL;
int picWidth, picHeight;
imageData = SOIL_load_image("../../resources/textures/wood.png",
&picWidth, &picHeight, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, picWidth, picHeight,
0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
glGenerateMipmap(GL_TEXTURE_2D);
// Step5 释放纹理图片资源
SOIL_free_image_data(imageData);
glBindTexture(GL_TEXTURE_2D, 0);
// 开始游戏主循环
while (!glfwWindowShouldClose(window))
{
glfwPollEvents(); // 处理例如鼠标 键盘等事件
// 清除颜色缓冲区 重置为指定颜色
glClearColor(0.18f, 0.04f, 0.14f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 这里填写场景绘制代码
glBindVertexArray(VAOId);
shader.use();
// 启用纹理单元 绑定纹理对象
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
glUniform1i(glGetUniformLocation(shader.programId, "tex"), 0); // 设置纹理单元为0号
// 使用索引绘制
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
glBindVertexArray(0);
glUseProgram(0);
glfwSwapBuffers(window); // 交换缓存
}
// 释放资源
glDeleteVertexArrays(1, &VAOId);
glDeleteBuffers(1, &VBOId);
glfwTerminate();
return 0;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE); // 关闭窗口
}
}