blob: c8f9b3226be2b130c20f38464b858d888ed4cd5c [file] [log] [blame]
// Copyright 2016 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.
#define GL_GLEXT_PROTOTYPES
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES3/gl3.h>
#include <stdio.h>
#include <stdlib.h>
#include <emscripten.h>
#include <emscripten/html5.h>
#include <assert.h>
int result = 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; \
} \
} \
int main()
{
EmscriptenWebGLContextAttributes attrs;
emscripten_webgl_init_context_attributes(&attrs);
attrs.enableExtensionsByDefault = 1;
attrs.majorVersion = 2;
attrs.minorVersion = 0;
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context( 0, &attrs );
if (!context)
{
printf("Skipped: WebGL 2 is not supported.\n");
#ifdef REPORT_RESULT
REPORT_RESULT(result);
#endif
return 0;
}
emscripten_webgl_make_context_current(context);
const char *vertexShader =
"#version 300 es\n"
"uniform mat4 a;\n"
"uniform Block1a {\n"
" uniform mat4 var1;\n"
" uniform vec4 variable2;\n"
"} block1bb;\n"
"uniform Block2ccc {\n"
" uniform mat4 var1;\n"
" uniform vec4 variable2;\n"
"} block2dddd;\n"
"void main() {\n"
" gl_Position = a * block1bb.var1*block1bb.variable2 + block2dddd.var1*block2dddd.variable2;\n"
"}\n";
const char *fragmentShader =
"#version 300 es\n"
"precision lowp float;\n"
" uniform Block3eeeee {\n"
" uniform vec4 var1;\n"
" uniform vec4 variable2;\n"
"} block3ffffff;\n" // Append characters of different lengths to test name string lengths.
"out vec4 outColor;\n"
"void main() {\n"
" outColor = block3ffffff.var1 + block3ffffff.variable2;\n"
"}\n";
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertexShader, NULL);
glCompileShader(vs);
int ok = 0;
glGetShaderiv(vs, GL_COMPILE_STATUS, &ok);
if (!ok) {
printf("Shader compilation error with vertex\n");
GLint infoLen = 0;
glGetShaderiv (vs, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1)
{
char* infoLog = (char *)malloc(sizeof(char) * infoLen+1);
glGetShaderInfoLog(vs, infoLen, NULL, infoLog);
printf("Error compiling shader:\n%s\n", infoLog);
}
}
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragmentShader, NULL);
glCompileShader(fs);
glGetShaderiv(fs, GL_COMPILE_STATUS, &ok);
if (!ok) {
printf("Shader compilation error with fragment\n");
GLint infoLen = 0;
glGetShaderiv (fs, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1)
{
char* infoLog = (char *)malloc(sizeof(char) * infoLen+1);
glGetShaderInfoLog(fs, infoLen, NULL, infoLog);
printf("Error compiling shader:\n%s\n", infoLog);
}
}
GLuint program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &ok);
assert(ok);
int maxLength = 0;
glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxLength);
printf("GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: %d\n", maxLength);
assert(maxLength == 12);
GLint numActiveUniforms = -1;
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numActiveUniforms);
printf("GL_ACTIVE_UNIFORMS: %d\n", numActiveUniforms);
assert(numActiveUniforms == 7);
for(int i = 0; i < numActiveUniforms; ++i)
{
char str[256] = {};
GLsizei length = -1;
GLint size = -1;
GLenum type = -1;
glGetActiveUniform(program, i, 255, &length, &size, &type, str);
GLint loc = glGetUniformLocation(program, str);
GLint indx = -1;
glGetActiveUniformsiv(program, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &indx);
printf("Active uniform at index %d: %s\n", i, str);
printf("glGetUniformLocation = %d \t GL_UNIFORM_BLOCK_INDEX = %d \t size = %d \t type = %d\n", loc, indx, size, type);
assert((loc == -1) != (indx == -1)); // one of them must be true
}
GLint numActiveUniformBlocks = -1;
glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &numActiveUniformBlocks);
assert(numActiveUniformBlocks == 3);
// Dump all active uniform buffer blocks of the current program.
for(int i = 0; i < numActiveUniformBlocks; ++i)
{
char str[256] = {};
GLsizei length = -1;
glGetActiveUniformBlockName(program, i, 255, &length, str);
assert(length > 0);
printf("Active uniform block at index %d: %s\n", i, str);
GLint param = -1;
#define DUMPUNIFORMBLOCKSTATUS(stat) glGetActiveUniformBlockiv(program, i, stat, &param); printf("%s: %d\n", #stat, param);
DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER);
DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER);
DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_BINDING);
DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_DATA_SIZE);
DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_NAME_LENGTH);
DUMPUNIFORMBLOCKSTATUS(GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS);
GLint indices[16] = {};
glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices);
for(size_t i = 0; i < param; ++i)
printf("offset for index %d: %d\n", i, indices[i]);
}
#ifdef REPORT_RESULT
REPORT_RESULT(result);
#endif
return 0;
}