1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
// Copyright 2021 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 <stdlib.h>
#include <cassert>
#include <cstdio>
#include <emscripten.h>
#include <emscripten/html5.h>
#define GL_GLEXT_PROTOTYPES
#include <GLES3/gl3.h>
int result = 0;
GLuint sampleQuery = 0;
#define GL_CALL( x ) \
{ \
x; \
GLenum error = glGetError(); \
if( error != GL_NO_ERROR ) { \
printf( "GL ERROR: %d, %s\n", (int)error, #x ); \
result = 1; \
} \
} \
void getQueryResult()
{
/* Get the result. It should be nonzero. */
GLuint any;
GL_CALL(glGetQueryObjectuiv(sampleQuery, GL_QUERY_RESULT, &any));
if (!any) return;
printf("queried any samples passed: %u\n", any);
emscripten_cancel_main_loop();
GL_CALL(glDeleteQueries(1, &sampleQuery));
// result == 0 signals success
exit(result);
}
GLuint compile_shader(GLenum shaderType, const char *src)
{
GLuint shader = glCreateShader(shaderType);
GL_CALL(glShaderSource(shader, 1, &src, NULL));
GL_CALL(glCompileShader(shader));
GLint isCompiled = 0;
GL_CALL(glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled));
assert(isCompiled);
return shader;
}
GLuint create_program(GLuint vert, GLuint frag)
{
GLuint program = glCreateProgram();
GL_CALL(glAttachShader(program, vert));
GL_CALL(glAttachShader(program, frag));
GL_CALL(glBindAttribLocation(program, 0, "position"));
GL_CALL(glLinkProgram(program));
return program;
}
int main() {
EmscriptenWebGLContextAttributes attrs;
emscripten_webgl_init_context_attributes(&attrs);
attrs.enableExtensionsByDefault = 1;
attrs.majorVersion = 2;
attrs.minorVersion = 0;
/* Skip WebGL 2 tests if not supported */
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context("#canvas", &attrs);
if (!context) {
printf("Skipped: WebGL 2 is not supported.\n");
return 0;
}
emscripten_webgl_make_context_current(context);
/* Generate a query */
GL_CALL(glGenQueries(2, &sampleQuery));
assert(sampleQuery);
/* Begin it */
GL_CALL(glBeginQuery(GL_ANY_SAMPLES_PASSED, sampleQuery));
/* Now, `sampleQuery` should be a query */
bool isQuery = false;
GL_CALL(isQuery = glIsQuery(sampleQuery));
assert(isQuery);
/* Do a draw to actually have something in the queue */
GLuint vert = compile_shader(GL_VERTEX_SHADER,
"#version 300 es\n"
"in vec4 position;\n"
"void main() {\n"
" gl_Position = position;\n"
"}\n");
GLuint frag = compile_shader(GL_FRAGMENT_SHADER,
"#version 300 es\n"
"precision lowp float;\n"
"out vec4 color;\n"
"void main() {\n"
" color = vec4(1.0, 0.3, 0.1, 1.0);\n"
"}\n");
GLuint program = create_program(vert, frag);
GL_CALL(glUseProgram(program));
const float positions[]{
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
GLuint vertices;
GL_CALL(glGenBuffers(1, &vertices));
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vertices));
GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW));
GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, 0));
GL_CALL(glEnableVertexAttribArray(0));
GL_CALL(glClearColor(0.5f, 0.7f, 0.9f, 1.0f));
GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
/* End the query after the draw */
GL_CALL(glEndQuery(GL_ANY_SAMPLES_PASSED));
/* In WebGL, query results are available only in the next event loop
iteration, so this should return false */
GLuint isAvailable;
GL_CALL(glGetQueryObjectuiv(sampleQuery, GL_QUERY_RESULT_AVAILABLE, &isAvailable));
assert(!isAvailable);
/* Run the main loop to get the result */
emscripten_set_main_loop(getQueryResult, 0, 0);
return 99;
}
|