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;
}
|