blob: c1fd9cfef7e474a3b0614cda9c216e735f843e12 [file] [log] [blame]
/*
* Copyright 2018 The Emscripten Authors. All rights reserved.
* Emscripten is available under two separate licenses, the MIT license and the
* University of Illinois/NCSA Open Source License. Both these licenses can be
* found in the LICENSE file.
*/
#include <GLFW/glfw3.h>
#include <GLES3/gl3.h>
#include <stdlib.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
void onDraw(void* arg)
{
GLFWwindow* window = *((GLFWwindow**)arg);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
void onResize(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
void onClose(GLFWwindow* window)
{
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
int main()
{
GLFWwindow* window;
if (!glfwInit()) {
return EXIT_FAILURE;
}
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
window = glfwCreateWindow(640, 480, "Client-side Vertex Arrays", NULL, NULL);
if (!window) {
glfwTerminate();
return EXIT_FAILURE;
}
glfwSetFramebufferSizeCallback(window, onResize);
glfwSetWindowCloseCallback(window, onClose);
glfwMakeContextCurrent(window);
GLuint vertex_shader;
GLuint fragment_shader;
GLuint program;
{
const GLchar* source = "#version 300 es \n"
" \n"
"in vec2 aPosition; \n"
"in uvec3 aColor; \n"
"out vec4 color; \n"
" \n"
"void main() \n"
"{ \n"
" gl_Position = vec4(aPosition, 0.f, 1.f); \n"
" color = vec4(vec3(aColor) / 255.f, 1.f); \n"
"} \n";
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &source, NULL);
glCompileShader(vertex_shader);
}
{
const GLchar* source = "#version 300 es \n"
" \n"
"precision mediump float; \n"
" \n"
"in vec4 color; \n"
"out vec4 FragColor; \n"
" \n"
"void main() \n"
"{ \n"
" FragColor = color; \n"
"} \n";
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &source, NULL);
glCompileShader(fragment_shader);
}
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glUseProgram(program);
{
static const float position[] = {
-1.f, -1.f,
1.f, -1.f,
0.f, 1.f,
};
GLint location;
location = glGetAttribLocation(program, "aPosition");
glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 0, position);
glEnableVertexAttribArray(location);
}
{
static const unsigned int color[] = {
255, 0, 0,
0, 255, 0,
0, 0, 255,
};
GLint location;
location = glGetAttribLocation(program, "aColor");
glVertexAttribIPointer(location, 3, GL_UNSIGNED_INT, 0, color);
glEnableVertexAttribArray(location);
}
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop_arg(onDraw, &window, 0, 1);
#else
while (1) {
onDraw(&window);
}
#endif
return EXIT_FAILURE; // not reached
}