2 // Created by adam.b on 15/03/2022.
4 #include "native-renderer.h"
7 * Set of math helper functions
12 constexpr GLfloat CUBE_VERTICES[] = {-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f};
14 constexpr GLfloat CUBE_COLOURS[] = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
16 constexpr GLushort CUBE_INDICES[] = {0, 2, 3, 0, 1, 3, 4, 6, 7, 4, 5, 7, 8, 9, 10, 11, 8, 10, 12, 13, 14, 15, 12, 14, 16, 17, 18, 16, 19, 18, 20, 21, 22, 20, 23, 22};
18 float matrixDegreesToRadians(float degrees)
20 return M_PI * degrees / 180.0f;
23 [[maybe_unused]] void matrixIdentityFunction(float* matrix)
47 [[maybe_unused]] void matrixMultiply(float* destination, float* operand1, float* operand2)
51 for(i = 0; i < 4; i++)
53 for(j = 0; j < 4; j++)
55 theResult[4 * i + j] = operand1[j] * operand2[4 * i] + operand1[4 + j] * operand2[4 * i + 1] +
56 operand1[8 + j] * operand2[4 * i + 2] + operand1[12 + j] * operand2[4 * i + 3];
59 for(int i = 0; i < 16; i++)
61 destination[i] = theResult[i];
65 [[maybe_unused]] void matrixTranslate(float* matrix, float x, float y, float z)
67 float temporaryMatrix[16];
68 matrixIdentityFunction(temporaryMatrix);
69 temporaryMatrix[12] = x;
70 temporaryMatrix[13] = y;
71 temporaryMatrix[14] = z;
72 matrixMultiply(matrix, temporaryMatrix, matrix);
75 [[maybe_unused]] void matrixScale(float* matrix, float x, float y, float z)
78 matrixIdentityFunction(tempMatrix);
82 matrixMultiply(matrix, tempMatrix, matrix);
85 [[maybe_unused]] void matrixRotateX(float* matrix, float angle)
88 matrixIdentityFunction(tempMatrix);
89 tempMatrix[5] = cos(matrixDegreesToRadians(angle));
90 tempMatrix[9] = -sin(matrixDegreesToRadians(angle));
91 tempMatrix[6] = sin(matrixDegreesToRadians(angle));
92 tempMatrix[10] = cos(matrixDegreesToRadians(angle));
93 matrixMultiply(matrix, tempMatrix, matrix);
95 [[maybe_unused]] void matrixRotateY(float* matrix, float angle)
98 matrixIdentityFunction(tempMatrix);
99 tempMatrix[0] = cos(matrixDegreesToRadians(angle));
100 tempMatrix[8] = sin(matrixDegreesToRadians(angle));
101 tempMatrix[2] = -sin(matrixDegreesToRadians(angle));
102 tempMatrix[10] = cos(matrixDegreesToRadians(angle));
103 matrixMultiply(matrix, tempMatrix, matrix);
105 [[maybe_unused]] void matrixRotateZ(float* matrix, float angle)
107 float tempMatrix[16];
108 matrixIdentityFunction(tempMatrix);
109 tempMatrix[0] = cos(matrixDegreesToRadians(angle));
110 tempMatrix[4] = -sin(matrixDegreesToRadians(angle));
111 tempMatrix[1] = sin(matrixDegreesToRadians(angle));
112 tempMatrix[5] = cos(matrixDegreesToRadians(angle));
113 matrixMultiply(matrix, tempMatrix, matrix);
116 void matrixFrustum(float* matrix, float left, float right, float bottom, float top, float zNear, float zFar)
118 float temp, xDistance, yDistance, zDistance;
120 xDistance = right - left;
121 yDistance = top - bottom;
122 zDistance = zFar - zNear;
123 matrixIdentityFunction(matrix);
124 matrix[0] = temp / xDistance;
125 matrix[5] = temp / yDistance;
126 matrix[8] = (right + left) / xDistance;
127 matrix[9] = (top + bottom) / yDistance;
128 matrix[10] = (-zFar - zNear) / zDistance;
130 matrix[14] = (-temp * zFar) / zDistance;
134 [[maybe_unused]] void matrixPerspective(float* matrix, float fieldOfView, float aspectRatio, float zNear, float zFar)
137 ymax = zNear * tanf(fieldOfView * M_PI / 360.0);
138 xmax = ymax * aspectRatio;
139 matrixFrustum(matrix, -xmax, xmax, -ymax, ymax, zNear, zFar);
144 NativeRenderer::NativeRenderer(uint32_t width, uint32_t height)
150 bool NativeRenderer::OnRender(const Dali::RenderCallbackInput& input)
152 if(mState == State::INIT)
154 Setup(mWidth, mHeight);
155 mState = State::RENDER;
163 void NativeRenderer::PrepareShader()
165 static const char glVertexShader[] =
166 "attribute vec4 vertexPosition;\n"
167 "attribute vec3 vertexColour;\n"
168 "varying vec3 fragColour;\n"
169 "uniform mat4 projection;\n"
170 "uniform mat4 modelView;\n"
173 " gl_Position = projection * modelView * vertexPosition;\n"
174 " fragColour = vertexColour;\n"
177 static const char glFragmentShader[] =
178 "precision mediump float;\n"
179 "varying vec3 fragColour;\n"
182 " gl_FragColor = vec4(fragColour, 1.0);\n"
185 mProgramId = CreateProgram(glVertexShader, glFragmentShader);
188 void NativeRenderer::Setup(int width, int height)
192 mVertexLocation = glGetAttribLocation(mProgramId, "vertexPosition");
193 mVertexColourLocation = glGetAttribLocation(mProgramId, "vertexColour");
194 mProjectionLocation = glGetUniformLocation(mProgramId, "projection");
195 mModelViewLocation = glGetUniformLocation(mProgramId, "modelView");
197 glEnable(GL_DEPTH_TEST);
198 glViewport(0, 0, width, height);
201 GLuint NativeRenderer::CreateProgram(const char* vertexSource, const char* fragmentSource)
203 GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vertexSource);
208 GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragmentSource);
213 GLuint program = glCreateProgram();
216 glAttachShader(program, vertexShader);
217 glAttachShader(program, fragmentShader);
218 glLinkProgram(program);
219 GLint linkStatus = GL_FALSE;
220 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
221 if(linkStatus != GL_TRUE)
224 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
227 char* buf = (char*)malloc(bufLength);
230 glGetProgramInfoLog(program, bufLength, NULL, buf);
234 glDeleteProgram(program);
241 GLuint NativeRenderer::LoadShader(GLenum shaderType, const char* shaderSource)
243 GLuint shader = glCreateShader(shaderType);
246 glShaderSource(shader, 1, &shaderSource, NULL);
247 glCompileShader(shader);
249 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
250 if(compiled != GL_TRUE)
253 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
257 char* logBuffer = (char*)malloc(infoLen);
259 if(logBuffer != NULL)
261 glGetShaderInfoLog(shader, infoLen, NULL, logBuffer);
266 glDeleteShader(shader);
275 void NativeRenderer::RenderCube(const Dali::RenderCallbackInput& input)
277 static float angle = 0.0f;
279 auto x = float(mWidth - input.size.width) * 0.5f;
280 auto y = float(mHeight - input.size.height) * 0.5f;
281 auto w = input.size.width;
282 auto h = input.size.height;
284 matrixPerspective(mProjectionMatrix, 45, (float)w / (float)h, 0.1f, 100);
286 glEnable(GL_SCISSOR_TEST);
287 glScissor(x, y, w, h);
288 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
289 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
290 matrixIdentityFunction(mModelViewMatrix);
291 matrixScale(mModelViewMatrix, 0.5f, 0.5f, 0.5f);
292 matrixRotateX(mModelViewMatrix, angle);
293 matrixRotateY(mModelViewMatrix, angle);
294 matrixTranslate(mModelViewMatrix, 0.0f, 0.0f, -10.0f);
295 glUseProgram(mProgramId);
296 glVertexAttribPointer(mVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_VERTICES);
297 glEnableVertexAttribArray(mVertexLocation);
298 glVertexAttribPointer(mVertexColourLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_COLOURS);
299 glEnableVertexAttribArray(mVertexColourLocation);
300 glUniformMatrix4fv(mProjectionLocation, 1, GL_FALSE, mProjectionMatrix);
301 glUniformMatrix4fv(mModelViewLocation, 1, GL_FALSE, mModelViewMatrix);
302 glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, CUBE_INDICES);