204 строки
6.4 KiB
C++
204 строки
6.4 KiB
C++
// Copyright 2014 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 <GLES2/gl2.h>
|
|
#include <GLES2/gl2ext.h>
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <vector>
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <emscripten.h>
|
|
#include <emscripten/html5.h>
|
|
|
|
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
|
|
std::stringstream ss(s);
|
|
std::string item;
|
|
while (std::getline(ss, item, delim)) {
|
|
elems.push_back(item);
|
|
}
|
|
return elems;
|
|
}
|
|
std::vector<std::string> split(const std::string &s, char delim) {
|
|
std::vector<std::string> elems;
|
|
split(s, delim, elems);
|
|
return elems;
|
|
}
|
|
|
|
GLint GetInt(GLenum param)
|
|
{
|
|
GLint value;
|
|
glGetIntegerv(param, &value);
|
|
return value;
|
|
}
|
|
|
|
void final(void*) {
|
|
#ifdef REPORT_RESULT
|
|
REPORT_RESULT(0);
|
|
#endif
|
|
}
|
|
|
|
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context;
|
|
|
|
void loop()
|
|
{
|
|
EMSCRIPTEN_RESULT res;
|
|
if (!context) {
|
|
// new rendering frame started without a context
|
|
EmscriptenWebGLContextAttributes attrs;
|
|
emscripten_webgl_init_context_attributes(&attrs);
|
|
EM_ASM(
|
|
var canvas2 = Module['canvas'].cloneNode(true);
|
|
Module['canvas'].parentElement.appendChild(canvas2);
|
|
Module['canvas'] = canvas2;
|
|
);
|
|
assert(emscripten_webgl_get_current_context() == 0);
|
|
context = emscripten_webgl_create_context("#canvas", &attrs);
|
|
|
|
assert(context > 0); // Must have received a valid context.
|
|
res = emscripten_webgl_make_context_current(context);
|
|
assert(res == EMSCRIPTEN_RESULT_SUCCESS);
|
|
assert(emscripten_webgl_get_current_context() == context);
|
|
} else {
|
|
res = emscripten_webgl_destroy_context(context);
|
|
assert(res == EMSCRIPTEN_RESULT_SUCCESS);
|
|
assert(emscripten_webgl_get_current_context() == 0);
|
|
|
|
emscripten_cancel_main_loop();
|
|
emscripten_async_call(final, (void*)0, 10);
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
bool first = true;
|
|
EmscriptenWebGLContextAttributes attrs;
|
|
int depth = 0;
|
|
int stencil = 0;
|
|
int antialias = 0;
|
|
#ifndef NO_DEPTH
|
|
for(depth = 0; depth <= 1; ++depth)
|
|
#endif
|
|
#ifndef NO_STENCIL
|
|
for(stencil = 0; stencil <= 1; ++stencil)
|
|
#endif
|
|
#ifndef NO_ANTIALIAS
|
|
for(antialias = 0; antialias <= 1; ++antialias)
|
|
#endif
|
|
{
|
|
emscripten_webgl_init_context_attributes(&attrs);
|
|
attrs.depth = depth;
|
|
attrs.stencil = stencil;
|
|
attrs.antialias = antialias;
|
|
printf("Requesting depth: %d, stencil: %d, antialias: %d\n", depth, stencil, antialias);
|
|
|
|
EM_ASM(
|
|
var canvas2 = document.createElement('canvas');
|
|
Module['canvas'].parentElement.appendChild(canvas2);
|
|
canvas2.id = 'customCanvas';
|
|
);
|
|
|
|
assert(emscripten_webgl_get_current_context() == 0);
|
|
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context("#customCanvas", &attrs);
|
|
assert(context > 0); // Must have received a valid context.
|
|
EMSCRIPTEN_RESULT res = emscripten_webgl_make_context_current(context);
|
|
assert(res == EMSCRIPTEN_RESULT_SUCCESS);
|
|
assert(emscripten_webgl_get_current_context() == context);
|
|
|
|
// Let's try enabling all extensions.
|
|
const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
|
|
std::vector<std::string> exts = split(extensions, ' ');
|
|
for(size_t i = 0; i < exts.size(); ++i)
|
|
{
|
|
EM_BOOL supported = emscripten_webgl_enable_extension(context, exts[i].c_str());
|
|
assert(supported);
|
|
}
|
|
|
|
int drawingBufferWidth = -1;
|
|
int drawingBufferHeight = -1;
|
|
res = emscripten_webgl_get_drawing_buffer_size(context, &drawingBufferWidth, &drawingBufferHeight);
|
|
assert(res == EMSCRIPTEN_RESULT_SUCCESS);
|
|
printf("drawingBufferWidth x Height: %dx%d\n", drawingBufferWidth, drawingBufferHeight);
|
|
assert(drawingBufferWidth == 300);
|
|
assert(drawingBufferHeight == 150);
|
|
|
|
// Try with a simple glClear() that we got a context.
|
|
glClearColor(1.f, 0.f, 0.f, 1.f);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
unsigned char pixels[4];
|
|
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
assert(pixels[0] == 0xFF);
|
|
assert(pixels[1] == 0);
|
|
assert(pixels[2] == 0);
|
|
assert(pixels[3] == 0xFF);
|
|
|
|
int numDepthBits = GetInt(GL_DEPTH_BITS);
|
|
int numStencilBits = GetInt(GL_STENCIL_BITS);
|
|
int numSamples = GetInt(GL_SAMPLES);
|
|
printf("RGBA: %d%d%d%d, Depth: %d, Stencil: %d, Samples: %d\n",
|
|
GetInt(GL_RED_BITS), GetInt(GL_GREEN_BITS), GetInt(GL_BLUE_BITS), GetInt(GL_ALPHA_BITS),
|
|
numDepthBits, numStencilBits, numSamples);
|
|
|
|
if (!depth && stencil && numDepthBits && numStencilBits && EM_ASM_INT(navigator.userAgent.toLowerCase().indexOf('firefox')) > -1)
|
|
{
|
|
numDepthBits = 0;
|
|
printf("Applying workaround to ignore Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=982477\n");
|
|
}
|
|
assert(!!numDepthBits == !!depth);
|
|
assert(!!numStencilBits == !!stencil);
|
|
assert(!!numSamples == !!antialias);
|
|
printf("\n");
|
|
|
|
// Test bug https://github.com/emscripten-core/emscripten/issues/1330:
|
|
unsigned vb;
|
|
glGenBuffers(1, &vb);
|
|
glBindBuffer(GL_ARRAY_BUFFER, vb);
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
|
|
|
unsigned vb2;
|
|
glGenBuffers(1, &vb2);
|
|
glBindBuffer(GL_ARRAY_BUFFER, vb2);
|
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
|
|
|
int vb3;
|
|
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &vb3);
|
|
if (vb != vb3) printf("Index 0: Generated VB: %d, read back VB: %d\n", vb, vb3);
|
|
assert(vb == vb3);
|
|
|
|
int vb4;
|
|
glGetVertexAttribiv(1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &vb4);
|
|
if (vb2 != vb4) printf("Index 1: Generated VB: %d, read back VB: %d\n", vb2, vb4);
|
|
assert(vb2 == vb4);
|
|
|
|
// Test bug https://github.com/emscripten-core/emscripten/issues/7472:
|
|
GLint enabled = 0;
|
|
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
|
|
assert(enabled == 0);
|
|
|
|
// Test that deleting the context works.
|
|
res = emscripten_webgl_destroy_context(context);
|
|
assert(res == 0);
|
|
assert(emscripten_webgl_get_current_context() == 0);
|
|
|
|
EM_ASM(
|
|
var canvas2 = document.getElementById('customCanvas');
|
|
canvas2.parentElement.removeChild(canvas2);
|
|
);
|
|
}
|
|
|
|
// result will be reported when mainLoop completes
|
|
emscripten_set_main_loop(loop, 0, 0);
|
|
|
|
#ifndef REPORT_RESULT
|
|
return 0;
|
|
#endif
|
|
}
|