1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cube.h"
17 #include "Vector3.h"
18 #include "camera.h"
19 #include "log.h"
20
21 namespace {
22 float g_vertices[] = {
23 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
24 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
25 -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
26
27 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
28 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
29 -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
30
31 -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
32 -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
33 -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
34
35 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
36 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
37 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
38
39 -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
40 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
41 -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
42
43 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
44 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
45 -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f};
46
47 // 阴影着色
48 char g_shaderfs[] = "#version 300 es\n"
49 "precision mediump float;\n"
50 "out vec4 FragColor; \n"
51 "struct Material { \n"
52 "vec3 ambient; \n"
53 "vec3 diffuse; \n"
54 "vec3 specular; \n"
55 "float shininess; \n"
56 "}; \n"
57
58 "struct Light { \n"
59 "vec3 position; \n"
60 "vec3 ambient; \n"
61 "vec3 diffuse; \n"
62 "vec3 specular; \n"
63 "}; \n"
64
65 "in vec3 Normal;\n"
66 "in vec3 FragPos;\n"
67
68 "uniform vec3 viewPos;\n"
69 "uniform Material material;\n"
70 "uniform Light light; \n"
71
72 "void main() \n"
73 "{\n"
74 "vec3 ambient = light.ambient * material.ambient; \n"
75
76 "vec3 norm = normalize(Normal); \n"
77 "vec3 lightDir = normalize(light.position - FragPos); \n"
78 "float diff = max(dot(norm, lightDir), 0.0); \n"
79 "vec3 diffuse = light.diffuse * (diff * material.diffuse);\n"
80 "vec3 viewDir = normalize(viewPos - FragPos); \n"
81 "vec3 reflectDir = reflect(-lightDir, norm); \n"
82 "float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); \n"
83 "vec3 specular = light.specular * (spec * material.specular); \n"
84 "vec3 result = ambient + diffuse + specular; \n"
85 "FragColor = vec4(result, 1.0); \n"
86 "}\n";
87
88 // 遮光板
89 char g_lightshaderfs[] = "#version 300 es\n"
90 "precision mediump float;\n"
91 "out vec4 FragColor;\n"
92 "void main()\n"
93 "{\n"
94 " FragColor = vec4(1.0);\n"
95 "}\n";
96
97 // VS着色
98 char g_shadervs[] = "#version 300 es\n"
99 "layout (location = 0) in vec3 aPos;\n"
100 "layout (location = 1) in vec3 aNormal;\n"
101 "layout (location = 2) in vec2 aTexCoords;\n"
102
103 "out vec3 Normal;\n"
104 "out vec3 FragPos;\n"
105 "out vec2 TexCoords;\n"
106
107 "uniform mat4 model;\n"
108 "uniform mat4 view; \n"
109 "uniform mat4 projection; \n"
110
111 "void main()\n"
112 "{\n"
113 " TexCoords = aTexCoords;\n"
114 " FragPos = vec3(model * vec4(aPos, 1.0));\n"
115 " Normal = mat3(transpose(inverse(model))) * aNormal; \n"
116 " gl_Position = projection*view*model*vec4(aPos, 1.0);\n"
117 "}\n";
118 } // namespace
119
Init()120 int32_t Cube::Init()
121 {
122 camera = new Camera(Vector3(0, 0, 3.0f));
123 ourShader = new Shader(false, g_shadervs, g_shaderfs);
124 lightShader = new Shader(false, g_shadervs, g_lightshaderfs);
125 lightPos = new Vector3(1.2f, 1.0f, 2.0f);
126 return 0;
127 }
128
129 // 绘图转换
Update()130 void Cube::Update()
131 {
132 glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
133 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
134 glGenVertexArrays(1, &vao);
135 glGenBuffers(1, &vbo);
136 glBindVertexArray(vao);
137 glBindBuffer(GL_ARRAY_BUFFER, vbo);
138 glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW);
139 // 位置属性
140 glVertexAttribPointer(0, kThree, GL_FLOAT, GL_FALSE, kEight * sizeof(float), (void *)0);
141 glEnableVertexAttribArray(0);
142 // 法线
143 glVertexAttribPointer(1, kThree, GL_FLOAT, GL_FALSE, kEight * sizeof(float), (void *)(kThree * sizeof(float)));
144 glEnableVertexAttribArray(1);
145 // ST
146 glVertexAttribPointer(kTwo, kTwo, GL_FLOAT, GL_FALSE, kEight * sizeof(float), (void *)(kSix * sizeof(float)));
147 glEnableVertexAttribArray(kTwo);
148 ourShader->use();
149 ourShader->SetInt("material.diffuse", 0);
150 ourShader->SetInt("material.specular", 1);
151 Update1();
152 }
153
154 // 绘图转换
Update1()155 void Cube::Update1()
156 {
157 const unsigned int scrWidth = 800;
158 const unsigned int scrHeight = 600;
159 // 将投影矩阵传递给着色器(请注意,在这种情况下,它可能会更改每一帧)
160 Matrix4x4 projection =
161 Algorithm::Perspective(Algorithm::Radians(camera->Zoom), (float)scrWidth / (float)scrHeight, 0.1f, 100.0f);
162 ourShader->SetMatrix4x4("projection", projection);
163 // 摄影机/视图变换
164 Matrix4x4 view = camera->GetViewMatrix();
165 ourShader->SetMatrix4x4("view", view);
166 // 渲染框
167 glBindVertexArray(vao);
168 // 计算每个对象的模型矩阵,并在绘制之前将其传递给着色器
169 // 确保先将矩阵初始化为单位矩阵
170 Matrix4x4 model = Matrix4x4::Identity();
171 // 光源属性
172 ourShader->SetVec3("light.ambient", 1.0f, 1.0f, 1.0f);
173 ourShader->SetVec3("light.diffuse", 1.0f, 1.0f, 1.0f);
174 ourShader->SetVec3("light.specular", 1.0f, 1.0f, 1.0f);
175 // 材料属性
176 ourShader->SetVec3("material.ambient", 0.0f, 0.1f, 0.06f);
177 ourShader->SetVec3("material.diffuse", 0.0f, 0.50980392f, 0.50980392f);
178 ourShader->SetVec3("material.specular", 0.50196078f, 0.50196078f, 0.50196078f);
179 ourShader->SetFloat("material.shininess", 32.0f);
180 lightPos->SetDataX(sin(position) * 3.0f);
181 lightPos->SetDataZ(cos(position) * 3.0f);
182 ourShader->SetVector3("light.position", *lightPos);
183
184 model.MakeRoate(1, Vector3(0, 1, 0));
185 ourShader->SetMatrix4x4("model", model);
186
187 ourShader->SetVector3("viewPos", camera->Position);
188 glDrawArrays(GL_TRIANGLES, 0, 36); // K36
189
190 model = Matrix4x4::Identity();
191 Matrix4x4 translate = Matrix4x4::Identity();
192 translate.MakeTranslation(*lightPos);
193 Matrix4x4 scale = Matrix4x4::Identity();
194 scale.MakeScale(Vector3(0.2f, 0.2f, 0.2f));
195 Matrix4x4::Multiply(translate, scale, model);
196
197 lightShader->use();
198 lightShader->SetMatrix4x4("model", model);
199 lightShader->SetMatrix4x4("projection", projection);
200 lightShader->SetMatrix4x4("view", view);
201 glDrawArrays(GL_TRIANGLES, 0, 36); // K36
202 }
203
Quit(void)204 int32_t Cube::Quit(void)
205 {
206 glDeleteVertexArrays(1, &vao);
207 glDeleteBuffers(1, &vbo);
208
209 glDeleteProgram(ourShader->ID);
210 glDeleteProgram(lightShader->ID);
211
212 delete ourShader;
213 ourShader = nullptr;
214 delete lightShader;
215 lightShader = nullptr;
216 delete camera;
217 camera = nullptr;
218 delete lightPos;
219 lightPos = nullptr;
220 LOGE("Cube Quit success.");
221 return 0;
222 }
223
Animate()224 void Cube::Animate()
225 {
226 if (position >= 10.5) { // max = 10.5
227 positive = -1;
228 }
229 if (position <= 8.5) { // min 8.5
230 positive = 1;
231 }
232 position = position + 0.005 * positive; // K0.005
233 }
234