-
Notifications
You must be signed in to change notification settings - Fork 451
/
texture01.cpp
170 lines (152 loc) · 5 KB
/
texture01.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// 引入GLEW库 定义静态链接
#define GLEW_STATIC
#include <GLEW/glew.h>
// 引入GLFW库
#include <GLFW/glfw3.h>
// 引入SOIL库
#include <SOIL/SOIL.h>
#include <iostream>
#include <vector>
// 包含着色器加载库
#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); // 关闭窗口
}
}