1 /*
2 * Copyright (c) 2024-2025 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 // Created on 2024/12/2.
17 // Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
18 // please include "napi/native_api.h".
19
20 #include "EGLRender.h"
21 #include "EGLConst.h"
22 #include <EGL/egl.h>
23 #include <EGL/eglext.h>
24 #include <GLES3/gl3.h>
25 #include <cmath>
26 #include <cstdio>
27 #include <algorithm>
28 #include <hilog/log.h>
29 #include <iostream>
30
LoadShader(GLenum type,const char * shaderSrc)31 GLuint LoadShader(GLenum type, const char* shaderSrc)
32 {
33 GLuint shader = glCreateShader(type);
34 glShaderSource(shader, 1, &shaderSrc, nullptr);
35 glCompileShader(shader);
36 return shader;
37 }
38
createShaderProgram(const char * vertexShader,const char * fragShader)39 GLuint createShaderProgram(const char* vertexShader, const char* fragShader)
40 {
41 if ((vertexShader == nullptr) || (fragShader == nullptr)) {
42 return 0;
43 }
44 GLuint vertex = LoadShader(GL_VERTEX_SHADER, vertexShader);
45 GLuint fragment = LoadShader(GL_FRAGMENT_SHADER, fragShader);
46 GLuint program = glCreateProgram();
47
48 // The gl function has no return value.
49 glAttachShader(program, vertex);
50 glAttachShader(program, fragment);
51 glLinkProgram(program);
52
53 return program;
54 }
55
createStar()56 void EGLRender::createStar()
57 {
58 starVertices.clear();
59 float ratio = 1.f * height_ / width_;
60 float inner = 0.3;
61 constexpr float outer = 0.95f;
62 constexpr GLfloat CenterX = 0.f;
63 constexpr GLfloat CenterY = 0.f;
64 constexpr float pentaAngle = 2. * PI / 5.f;
65 for (int i = 0; i < 5; ++i) {
66 starVertices.push_back(CenterX);
67 starVertices.push_back(CenterY);
68 starVertices.push_back(inner * cosf(-PI * 0.5f - pentaAngle * 2.f - pentaAngle * i) * ratio);
69 starVertices.push_back(inner * sinf(-PI * 0.5f - pentaAngle * 2.f - pentaAngle * i));
70 starVertices.push_back(outer * cosf(PI * 0.5f - pentaAngle * i) * ratio);
71 starVertices.push_back(outer * sinf(PI * 0.5f - pentaAngle * i));
72 starVertices.push_back(inner * cosf(-PI * 0.5f - pentaAngle * 3.f - pentaAngle * i) * ratio);
73 starVertices.push_back(inner * sinf(-PI * 0.5f - pentaAngle * 3.f - pentaAngle * i));
74 }
75 }
76
createStarColor()77 void EGLRender::createStarColor()
78 {
79 starColors.clear();
80 constexpr float inner = 0.5f;
81 constexpr float outer = 2.f;
82 constexpr GLfloat CenterX = 0.f;
83 constexpr GLfloat CenterY = 0.f;
84 constexpr float pentaAngle = 2. * PI / 5.f;
85 for (int i = 0; i < 5; ++i) {
86 starColors.push_back(251.0f / 255);
87 starColors.push_back(126.0f / 255);
88 starColors.push_back(126.0f / 255);
89 starColors.push_back(88.0f / 255);
90 starColors.push_back(50.0f / 255);
91 starColors.push_back(50.0f / 255);
92 starColors.push_back(251.0f / 255);
93 starColors.push_back(126.0f / 255);
94 starColors.push_back(126.0f / 255);
95 starColors.push_back(88.0f / 255);
96 starColors.push_back(50.0f / 255);
97 starColors.push_back(50.0f / 255);
98 }
99 }
100
SetUpEGLContext(void * window,int64_t surface_id)101 void EGLRender::SetUpEGLContext(void* window, int64_t surface_id)
102 {
103 this->surface_id = surface_id;
104 eglWindow_ = (EGLNativeWindowType)(window);
105 eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
106 EGLint majorVersion;
107 EGLint minorVersion;
108 eglInitialize(eglDisplay_, &majorVersion, &minorVersion);
109 const EGLint maxConfigSize = 1;
110 EGLint numConfigs;
111 eglChooseConfig(eglDisplay_, ATTRIB_LIST, &eglConfig_, maxConfigSize, &numConfigs);
112 eglSurface_ = eglCreateWindowSurface(eglDisplay_, eglConfig_, eglWindow_, NULL);
113 eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, EGL_NO_CONTEXT, CONTEXT_ATTRIBS);
114 eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_);
115 program_ = createShaderProgram(VERTEX_SHADER, FRAGMENT_SHADER);
116 glUseProgram(program_);
117 shader_vertex_position = glGetAttribLocation(program_, "a_position");
118 createStarColor();
119 }
120
SetEGLWindowSize(int width,int height)121 void EGLRender::SetEGLWindowSize(int width, int height)
122 {
123 width_ = width;
124 height_ = height;
125 createStar();
126 }
127
drawTriangleFan(const GLfloat shapeVertices[],uint32_t length)128 void EGLRender::drawTriangleFan(const GLfloat shapeVertices[], uint32_t length)
129 {
130 glVertexAttribPointer(shader_vertex_position, 2, GL_FLOAT, GL_FALSE, 0, shapeVertices);
131 glEnableVertexAttribArray(shader_vertex_position);
132 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, starColors.data());
133 glEnableVertexAttribArray(1);
134 glDrawArrays(GL_TRIANGLE_FAN, 0, length / 2);
135 glDisableVertexAttribArray(shader_vertex_position);
136 glDisableVertexAttribArray(1);
137 }
138
drawTriangleFanColor(const GLfloat * color,const GLfloat shapeVertices[],uint32_t length)139 void EGLRender::drawTriangleFanColor(const GLfloat* color, const GLfloat shapeVertices[], uint32_t length)
140 {
141 glVertexAttribPointer(shader_vertex_position, 2, GL_FLOAT, GL_FALSE, 0, shapeVertices);
142 glEnableVertexAttribArray(shader_vertex_position);
143 glVertexAttrib4fv(1, color);
144 glDrawArrays(GL_TRIANGLE_FAN, 0, length / 2);
145 glDisableVertexAttribArray(shader_vertex_position);
146 }
147
drawTriangles(const GLfloat * color,const GLfloat shapeVertices[],uint32_t length)148 void EGLRender::drawTriangles(const GLfloat* color, const GLfloat shapeVertices[], uint32_t length)
149 {
150 glVertexAttribPointer(shader_vertex_position, 2, GL_FLOAT, GL_FALSE, 0, shapeVertices);
151 glEnableVertexAttribArray(shader_vertex_position);
152 glVertexAttrib4fv(1, color);
153 glDrawArrays(GL_TRIANGLES, 0, length / 2);
154 glDisableVertexAttribArray(shader_vertex_position);
155 }
156
DrawBackground(const GLfloat * color)157 void EGLRender::DrawBackground(const GLfloat* color)
158 {
159 eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_);
160 glViewport(0, 0, width_, height_);
161 glClearColor(0.9, 0.9, 0.9, 1);
162 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
163 glUseProgram(program_);
164 drawTriangles(color, screenTriangle, 12);
165 glFlush();
166 glFinish();
167 eglSwapBuffers(eglDisplay_, eglSurface_);
168 }
169
drawLine(const GLfloat * color,const GLfloat lneVertices[],uint32_t length)170 void EGLRender::drawLine(const GLfloat* color, const GLfloat lneVertices[], uint32_t length)
171 {
172 glVertexAttribPointer(shader_vertex_position, 2, GL_FLOAT, GL_FALSE, 0, lneVertices);
173 glEnableVertexAttribArray(shader_vertex_position);
174 glVertexAttrib4fv(1, color);
175 glLineWidth(20);
176 glDrawArrays(GL_LINES, 0, length / 2);
177 glDisableVertexAttribArray(shader_vertex_position);
178 }
179
DrawOnFrame()180 void EGLRender::DrawOnFrame()
181 {
182 frameCnt += 1;
183 frameCnt %= 100;
184 eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_);
185 glViewport(frameCnt * 10, 0, width_, height_);
186 glClearColor(0.9, 0.9, 0.9, 1);
187 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
188 glUseProgram(program_);
189 const GLfloat red[] = {1, 0, 0, 1.0f};
190 GLfloat linePoint[] = {
191 -1.0f , -1.0, -1.0f, 1.0f
192 };
193 drawLine(red, linePoint, 4);
194 glFlush();
195 glFinish();
196 eglSwapBuffers(eglDisplay_, eglSurface_);
197 }
198
DrawStar()199 void EGLRender::DrawStar()
200 {
201 eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_);
202 glViewport(0, 0, width_, height_);
203 glClearColor(0.9, 0.9, 0.9, 1);
204 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
205 glUseProgram(program_);
206 const GLfloat color[] = {126.0f / 255, 143.0f / 255, 251.0f / 255, 1.0f};
207 drawTriangleFan(starVertices.data(), starVertices.size());
208 glFlush();
209 glFinish();
210 float ratio = 0.5 * height_ / width_ ;
211 GLfloat corners[24] = {
212 1.0, -1.0, 1.f - ratio, -1.0, 1.0, -0.5,
213 -1., 1., -1.f + ratio, 1., -1., 0.5,
214 1., 1., 1., 0.5, 1.f - ratio, 1.,
215 -1., -1., -1.f + ratio, -1., -1., -0.5
216 };
217 drawTriangles(color, corners, 24);
218 glFlush();
219 glFinish();
220 auto ret = eglSwapBuffers(eglDisplay_, eglSurface_);
221 }
222
~EGLRender()223 EGLRender::~EGLRender()
224 {
225 if ((eglDisplay_ == nullptr) || (eglSurface_ == nullptr) || (!eglDestroySurface(eglDisplay_, eglSurface_))) {
226 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "EGLCore", "Release eglDestroySurface failed");
227 }
228
229 if ((eglDisplay_ == nullptr) || (eglContext_ == nullptr) || (!eglDestroyContext(eglDisplay_, eglContext_))) {
230 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "EGLCore", "Release eglDestroySurface failed");
231 }
232
233 if ((eglDisplay_ == nullptr) || (!eglTerminate(eglDisplay_))) {
234 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "EGLCore", "Release eglDestroySurface failed");
235 }
236 }