1b877906bSopenharmony_ci//========================================================================
2b877906bSopenharmony_ci// OpenGL ES 2.0 triangle example
3b877906bSopenharmony_ci// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
4b877906bSopenharmony_ci//
5b877906bSopenharmony_ci// This software is provided 'as-is', without any express or implied
6b877906bSopenharmony_ci// warranty. In no event will the authors be held liable for any damages
7b877906bSopenharmony_ci// arising from the use of this software.
8b877906bSopenharmony_ci//
9b877906bSopenharmony_ci// Permission is granted to anyone to use this software for any purpose,
10b877906bSopenharmony_ci// including commercial applications, and to alter it and redistribute it
11b877906bSopenharmony_ci// freely, subject to the following restrictions:
12b877906bSopenharmony_ci//
13b877906bSopenharmony_ci// 1. The origin of this software must not be misrepresented; you must not
14b877906bSopenharmony_ci//    claim that you wrote the original software. If you use this software
15b877906bSopenharmony_ci//    in a product, an acknowledgment in the product documentation would
16b877906bSopenharmony_ci//    be appreciated but is not required.
17b877906bSopenharmony_ci//
18b877906bSopenharmony_ci// 2. Altered source versions must be plainly marked as such, and must not
19b877906bSopenharmony_ci//    be misrepresented as being the original software.
20b877906bSopenharmony_ci//
21b877906bSopenharmony_ci// 3. This notice may not be removed or altered from any source
22b877906bSopenharmony_ci//    distribution.
23b877906bSopenharmony_ci//
24b877906bSopenharmony_ci//========================================================================
25b877906bSopenharmony_ci
26b877906bSopenharmony_ci#define GLAD_GLES2_IMPLEMENTATION
27b877906bSopenharmony_ci#include <glad/gles2.h>
28b877906bSopenharmony_ci#define GLFW_INCLUDE_NONE
29b877906bSopenharmony_ci#include <GLFW/glfw3.h>
30b877906bSopenharmony_ci
31b877906bSopenharmony_ci#include "linmath.h"
32b877906bSopenharmony_ci
33b877906bSopenharmony_ci#include <stdlib.h>
34b877906bSopenharmony_ci#include <stddef.h>
35b877906bSopenharmony_ci#include <stdio.h>
36b877906bSopenharmony_ci
37b877906bSopenharmony_citypedef struct Vertex
38b877906bSopenharmony_ci{
39b877906bSopenharmony_ci    vec2 pos;
40b877906bSopenharmony_ci    vec3 col;
41b877906bSopenharmony_ci} Vertex;
42b877906bSopenharmony_ci
43b877906bSopenharmony_cistatic const Vertex vertices[3] =
44b877906bSopenharmony_ci{
45b877906bSopenharmony_ci    { { -0.6f, -0.4f }, { 1.f, 0.f, 0.f } },
46b877906bSopenharmony_ci    { {  0.6f, -0.4f }, { 0.f, 1.f, 0.f } },
47b877906bSopenharmony_ci    { {   0.f,  0.6f }, { 0.f, 0.f, 1.f } }
48b877906bSopenharmony_ci};
49b877906bSopenharmony_ci
50b877906bSopenharmony_cistatic const char* vertex_shader_text =
51b877906bSopenharmony_ci"#version 100\n"
52b877906bSopenharmony_ci"precision mediump float;\n"
53b877906bSopenharmony_ci"uniform mat4 MVP;\n"
54b877906bSopenharmony_ci"attribute vec3 vCol;\n"
55b877906bSopenharmony_ci"attribute vec2 vPos;\n"
56b877906bSopenharmony_ci"varying vec3 color;\n"
57b877906bSopenharmony_ci"void main()\n"
58b877906bSopenharmony_ci"{\n"
59b877906bSopenharmony_ci"    gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
60b877906bSopenharmony_ci"    color = vCol;\n"
61b877906bSopenharmony_ci"}\n";
62b877906bSopenharmony_ci
63b877906bSopenharmony_cistatic const char* fragment_shader_text =
64b877906bSopenharmony_ci"#version 100\n"
65b877906bSopenharmony_ci"precision mediump float;\n"
66b877906bSopenharmony_ci"varying vec3 color;\n"
67b877906bSopenharmony_ci"void main()\n"
68b877906bSopenharmony_ci"{\n"
69b877906bSopenharmony_ci"    gl_FragColor = vec4(color, 1.0);\n"
70b877906bSopenharmony_ci"}\n";
71b877906bSopenharmony_ci
72b877906bSopenharmony_cistatic void error_callback(int error, const char* description)
73b877906bSopenharmony_ci{
74b877906bSopenharmony_ci    fprintf(stderr, "GLFW Error: %s\n", description);
75b877906bSopenharmony_ci}
76b877906bSopenharmony_ci
77b877906bSopenharmony_cistatic void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
78b877906bSopenharmony_ci{
79b877906bSopenharmony_ci    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
80b877906bSopenharmony_ci        glfwSetWindowShouldClose(window, GLFW_TRUE);
81b877906bSopenharmony_ci}
82b877906bSopenharmony_ci
83b877906bSopenharmony_ciint main(void)
84b877906bSopenharmony_ci{
85b877906bSopenharmony_ci    glfwSetErrorCallback(error_callback);
86b877906bSopenharmony_ci
87b877906bSopenharmony_ci    if (!glfwInit())
88b877906bSopenharmony_ci        exit(EXIT_FAILURE);
89b877906bSopenharmony_ci
90b877906bSopenharmony_ci    glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
91b877906bSopenharmony_ci    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
92b877906bSopenharmony_ci    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
93b877906bSopenharmony_ci    glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
94b877906bSopenharmony_ci
95b877906bSopenharmony_ci    GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL ES 2.0 Triangle (EGL)", NULL, NULL);
96b877906bSopenharmony_ci    if (!window)
97b877906bSopenharmony_ci    {
98b877906bSopenharmony_ci        glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
99b877906bSopenharmony_ci        window = glfwCreateWindow(640, 480, "OpenGL ES 2.0 Triangle", NULL, NULL);
100b877906bSopenharmony_ci        if (!window)
101b877906bSopenharmony_ci        {
102b877906bSopenharmony_ci            glfwTerminate();
103b877906bSopenharmony_ci            exit(EXIT_FAILURE);
104b877906bSopenharmony_ci        }
105b877906bSopenharmony_ci    }
106b877906bSopenharmony_ci
107b877906bSopenharmony_ci    glfwSetKeyCallback(window, key_callback);
108b877906bSopenharmony_ci
109b877906bSopenharmony_ci    glfwMakeContextCurrent(window);
110b877906bSopenharmony_ci    gladLoadGLES2(glfwGetProcAddress);
111b877906bSopenharmony_ci    glfwSwapInterval(1);
112b877906bSopenharmony_ci
113b877906bSopenharmony_ci    GLuint vertex_buffer;
114b877906bSopenharmony_ci    glGenBuffers(1, &vertex_buffer);
115b877906bSopenharmony_ci    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
116b877906bSopenharmony_ci    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
117b877906bSopenharmony_ci
118b877906bSopenharmony_ci    const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
119b877906bSopenharmony_ci    glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
120b877906bSopenharmony_ci    glCompileShader(vertex_shader);
121b877906bSopenharmony_ci
122b877906bSopenharmony_ci    const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
123b877906bSopenharmony_ci    glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
124b877906bSopenharmony_ci    glCompileShader(fragment_shader);
125b877906bSopenharmony_ci
126b877906bSopenharmony_ci    const GLuint program = glCreateProgram();
127b877906bSopenharmony_ci    glAttachShader(program, vertex_shader);
128b877906bSopenharmony_ci    glAttachShader(program, fragment_shader);
129b877906bSopenharmony_ci    glLinkProgram(program);
130b877906bSopenharmony_ci
131b877906bSopenharmony_ci    const GLint mvp_location = glGetUniformLocation(program, "MVP");
132b877906bSopenharmony_ci    const GLint vpos_location = glGetAttribLocation(program, "vPos");
133b877906bSopenharmony_ci    const GLint vcol_location = glGetAttribLocation(program, "vCol");
134b877906bSopenharmony_ci
135b877906bSopenharmony_ci    glEnableVertexAttribArray(vpos_location);
136b877906bSopenharmony_ci    glEnableVertexAttribArray(vcol_location);
137b877906bSopenharmony_ci    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
138b877906bSopenharmony_ci                          sizeof(Vertex), (void*) offsetof(Vertex, pos));
139b877906bSopenharmony_ci    glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
140b877906bSopenharmony_ci                          sizeof(Vertex), (void*) offsetof(Vertex, col));
141b877906bSopenharmony_ci
142b877906bSopenharmony_ci    while (!glfwWindowShouldClose(window))
143b877906bSopenharmony_ci    {
144b877906bSopenharmony_ci        int width, height;
145b877906bSopenharmony_ci        glfwGetFramebufferSize(window, &width, &height);
146b877906bSopenharmony_ci        const float ratio = width / (float) height;
147b877906bSopenharmony_ci
148b877906bSopenharmony_ci        glViewport(0, 0, width, height);
149b877906bSopenharmony_ci        glClear(GL_COLOR_BUFFER_BIT);
150b877906bSopenharmony_ci
151b877906bSopenharmony_ci        mat4x4 m, p, mvp;
152b877906bSopenharmony_ci        mat4x4_identity(m);
153b877906bSopenharmony_ci        mat4x4_rotate_Z(m, m, (float) glfwGetTime());
154b877906bSopenharmony_ci        mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
155b877906bSopenharmony_ci        mat4x4_mul(mvp, p, m);
156b877906bSopenharmony_ci
157b877906bSopenharmony_ci        glUseProgram(program);
158b877906bSopenharmony_ci        glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) &mvp);
159b877906bSopenharmony_ci        glDrawArrays(GL_TRIANGLES, 0, 3);
160b877906bSopenharmony_ci
161b877906bSopenharmony_ci        glfwSwapBuffers(window);
162b877906bSopenharmony_ci        glfwPollEvents();
163b877906bSopenharmony_ci    }
164b877906bSopenharmony_ci
165b877906bSopenharmony_ci    glfwDestroyWindow(window);
166b877906bSopenharmony_ci
167b877906bSopenharmony_ci    glfwTerminate();
168b877906bSopenharmony_ci    exit(EXIT_SUCCESS);
169b877906bSopenharmony_ci}
170b877906bSopenharmony_ci
171