File: webgl2_ubos.cpp

package info (click to toggle)
emscripten 3.1.69%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 121,872 kB
  • sloc: ansic: 636,110; cpp: 425,974; javascript: 78,401; python: 58,404; sh: 49,154; pascal: 5,237; makefile: 3,365; asm: 2,415; lisp: 1,869
file content (169 lines) | stat: -rw-r--r-- 5,514 bytes parent folder | download | duplicates (3)
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// 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>

#define GL_CALL( x ) \
    { \
        x; \
        GLenum error = glGetError(); \
        if( error != GL_NO_ERROR ) { \
            printf( "GL ERROR: %d,  %s\n", (int)error, #x ); \
            assert(false); \
        } \
    } \


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( "#canvas", &attrs );
  if (!context)
  {
    printf("Skipped: WebGL 2 is not supported.\n");
    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) param = -1; glGetActiveUniformBlockiv(program, i, stat, &param); printf("%s: %d\n", #stat, param); assert(param != -1);
    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(GLint i = 0; i < param; ++i)
      printf("offset for index %d: %d\n", i, indices[i]);
  }

  return 0;
}