blob: 01423f2212d526c95cb1f5e3e4befc480e1602bb [file] [log] [blame]
// Copyright 2017 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 <stdio.h>
#include <string.h>
#include <assert.h>
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
#include <GLES2/gl2.h>
GLuint CompileShader(GLenum type, const char *src)
{
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
assert(glGetError() == GL_NO_ERROR && "Shader compilation failed!");
return shader;
}
int main(int argc, char *argv[])
{
emscripten_set_canvas_element_size("#canvas", 256, 256);
EmscriptenWebGLContextAttributes attr;
emscripten_webgl_init_context_attributes(&attr);
attr.alpha = attr.depth = attr.stencil = attr.antialias = attr.preserveDrawingBuffer = attr.failIfMajorPerformanceCaveat = 0;
attr.enableExtensionsByDefault = 1;
attr.premultipliedAlpha = 0;
#ifdef TEST_WEBGL2
attr.majorVersion = 2;
#else
attr.majorVersion = 1;
#endif
attr.minorVersion = 0;
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context("#canvas", &attr);
emscripten_webgl_make_context_current(ctx);
GLuint vs = CompileShader(GL_VERTEX_SHADER,
"#version 100\n"
"attribute vec4 pos; void main() { gl_Position = pos; }");
GLuint ps = CompileShader(GL_FRAGMENT_SHADER,
"#version 100\n"
"precision lowp float;\n"
"uniform vec3 color;\n"
"uniform vec3 colors[3];\n"
"void main() { gl_FragColor = vec4(color,1) + vec4(colors[0].r, colors[1].g, colors[2].b, 1); }");
GLuint program = 0;
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, ps);
glBindAttribLocation(program, 0, "pos");
glLinkProgram(program);
assert(glGetError() == GL_NO_ERROR && "Shader program link failed");
int color_loc = glGetUniformLocation(program, "color");
assert(color_loc != -1);
glUseProgram(program);
float col[3] = { 0.2f, 0.2f, 0.2f };
glUniform3fv(color_loc, 1, col);
int loc = glGetUniformLocation(program, "colors");
assert(glGetUniformLocation(program, "colors[2]") == loc+2);
assert(glGetUniformLocation(program, "colors[0]") == loc);
assert(glGetUniformLocation(program, "colors[3]") == -1);
assert(glGetUniformLocation(program, "colors[1]") == loc+1);
assert(glGetUniformLocation(program, "colors[]") == loc);
assert(glGetUniformLocation(program, "colors[-100]") == -1);
assert(glGetUniformLocation(program, "colors[bleh]") == -1);
float colors[4*3] = { 1,0,0, 0,0.5,0, 0,0,0.2, 1,1,1 };
glUniform3fv(loc+1, 3, colors+3); // Pass the actual colors (testing a nonzero location offset), but do a mistake by setting one index too many. Spec says this should be gracefully handled, and that excess elements are ignored.
assert(glGetError() == GL_NO_ERROR);
glUniform3fv(loc, 1, colors); // Set the first index as well.
assert(glGetError() == GL_NO_ERROR);
glUniform3fv(loc, 4, colors); // Just directly set the full array.
assert(glGetError() == GL_NO_ERROR);
GLuint vbo = 0;
const GLfloat v[] = { -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1 };
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 6);
unsigned char pixel[4];
glReadPixels(1,1,1,1,GL_RGBA,GL_UNSIGNED_BYTE, pixel);
printf("%d,%d,%d,%d\n", pixel[0], pixel[1], pixel[2], pixel[3]);
assert(pixel[0] == 255);
assert(pixel[1] == 178);
assert(pixel[2] == 102);
assert(pixel[3] == 255);
printf("Test passed!\n");
#ifdef REPORT_RESULT
REPORT_RESULT(1);
#endif
return 0;
}