File: webgl_with_closure.cpp

package info (click to toggle)
emscripten 3.1.6~dfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 114,112 kB
  • sloc: ansic: 583,052; cpp: 391,943; javascript: 79,361; python: 54,180; sh: 49,997; pascal: 4,658; makefile: 3,426; asm: 2,191; lisp: 1,869; ruby: 488; cs: 142
file content (185 lines) | stat: -rw-r--r-- 6,800 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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// 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 <assert.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES3/gl3.h>
#include <stdio.h>
#include <emscripten.h>
#include <emscripten/html5.h>

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


    bool IsFramebufferValid( GLenum target )
    {
        // get framebuffer status from opengl
        GLenum status = glCheckFramebufferStatus( target );
        
        // debug output of the framebuffer status
        switch( status )
        {
            case GL_FRAMEBUFFER_COMPLETE:
                printf("****  Framebuffer COMPLETE\n");
                break;
            case GL_FRAMEBUFFER_UNDEFINED:
                printf("****  Target is the default framebuffer, but the default framebuffer does not exist.\n");
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
                printf("****  Any of the framebuffer attachment points are framebuffer incomplete.\n");
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
                printf("****  The framebuffer does not have at least one image attached to it.\n");
                break;
            case GL_FRAMEBUFFER_UNSUPPORTED:
                printf("****  the combination of internal formats of the attached images violates an "
                                "implementation-dependent set of restrictions.\n");
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
                printf("****  The value of GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers; "
                                "if the value of GL_TEXTURE_SAMPLES is the not same for all attached textures; or, if "
                                "the attached images are a mix of renderbuffers and textures, the value of "
                                "GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES."
                                "Or the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not the same for all attached "
                                "textures; or, if the attached images are a mix of renderbuffers and textures, the "
                                "value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached textures.\n");
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
                printf("****  GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS.\n");
                break;
            default:
                printf("****  IsFramebufferValid()  Unknown validation error: %#08x\n", (uint32_t)status );
                break;
        }
        
        return status == GL_FRAMEBUFFER_COMPLETE;
    }


int main()
{
    emscripten_set_canvas_element_size( "#canvas", 100, 100 );

    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)
    {
        attrs.majorVersion = 1;
        context = emscripten_webgl_create_context( "#canvas", &attrs );
        assert(context);
        // We did not have WebGL 2, but were able to init WebGL 1? In that case,
        // gracefully skip this test with the current browser not supporting
        // this one.
        printf("Skipping test: WebGL 2.0 is not available.\n");
        return 0;
    }
    emscripten_webgl_make_context_current(context);


    // Textures
    //
    int mips = 10;
    int sizeO = 512;

    unsigned short* data = new unsigned short[ 512 * 512 * 4 ];
    //memset( data, 0, 512 * 512 * 4 );

    // Create texture 1
    GLuint tex1;
    GL_CALL( glGenTextures( 1, &tex1 ) );
    GL_CALL( glBindTexture( GL_TEXTURE_CUBE_MAP, tex1 ) );
    for( int i=0; i<6; ++i )
    {
        GL_CALL( glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGBA16F, sizeO, sizeO, 0, GL_RGBA, GL_HALF_FLOAT, NULL ) );
    }
    GL_CALL( glGenerateMipmap( GL_TEXTURE_CUBE_MAP ) );

    for( int i=0; i<6; ++i )
        GL_CALL( glTexSubImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, 0, 0, sizeO, sizeO, GL_RGBA, GL_HALF_FLOAT, data ) );

    delete [] data;

    // Create texture 2
    GLuint tex2;
    GL_CALL( glGenTextures( 1, &tex2 ) );
    GL_CALL( glBindTexture( GL_TEXTURE_CUBE_MAP, tex2 ) );
    for( int i=0; i<6; ++i )
    {
        GL_CALL( glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGBA16F, sizeO, sizeO, 0, GL_RGBA, GL_HALF_FLOAT, NULL ) );
    }
    GL_CALL( glGenerateMipmap( GL_TEXTURE_CUBE_MAP ) );



    // FBOs
    //

    // Create FBO 1
    GLuint fbo1;
    GL_CALL( glGenFramebuffers( 1, &fbo1 ) );
    GL_CALL( glBindFramebuffer( GL_FRAMEBUFFER, fbo1 ) );
    for( int level=0; level<mips; ++level )
    {
        for( int i=0; i<6; ++i )
        {
            GL_CALL( glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, tex1, level ) );
        }
    }
    IsFramebufferValid( GL_FRAMEBUFFER );

    // Create FBO 2
    GLuint fbo2;
    GL_CALL( glGenFramebuffers( 1, &fbo2 ) );
    GL_CALL( glBindFramebuffer( GL_FRAMEBUFFER, fbo2 ) );
    for( int level=0; level<mips; ++level )
    {
        for( int i=0; i<6; ++i )
        {
            GL_CALL( glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, tex2, level ) );

            glViewport( 0, 0, sizeO, sizeO );
        }
    }
    IsFramebufferValid( GL_FRAMEBUFFER );


    // Copy FBO 1 to 2
    int nw = sizeO;
    GL_CALL( glBindFramebuffer( GL_READ_FRAMEBUFFER, fbo1 ) );
    GL_CALL( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, fbo2 ) );
    for( int level=0; level<mips; ++level )
    {
        for( int i=0; i<6; ++i )
        {
            GL_CALL( glFramebufferTexture2D( GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, tex1, level ) );
            GL_CALL( glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, tex2, level ) );

            glViewport( 0, 0, nw, nw );

            GL_CALL( glBlitFramebuffer( 0, 0, nw, nw, 0, 0, nw, nw, GL_COLOR_BUFFER_BIT, GL_NEAREST ) );
        }

        nw /= 2;
    }

    GL_CALL( glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 ) );
    GL_CALL( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ) );  

  return 0;
}