Browse Source

Merge pull request #1531 from vkbsb/h5_canvas_polygon_fix

H5 canvas polygon fix
Juan Linietsky 10 years ago
parent
commit
b135cdbf05

+ 3 - 0
.gitignore

@@ -23,6 +23,9 @@ tools/editor/editor_icons.cpp
 make.bat
 log.txt
 
+# Javascript specific
+*.bc
+
 # Android specific
 platform/android/java/local.properties
 platform/android/java/project.properties

+ 3 - 0
SConstruct

@@ -111,6 +111,7 @@ opts.Add('jpg','JPG Image loader support (yes/no)','yes')
 opts.Add('webp','WEBP Image loader support (yes/no)','yes')
 opts.Add('dds','DDS Texture loader support (yes/no)','yes')
 opts.Add('pvr','PVR (PowerVR) Texture loader support (yes/no)','yes')
+opts.Add('etc1','etc1 Texture compression support (yes/no)','yes')
 opts.Add('builtin_zlib','Use built-in zlib (yes/no)','yes')
 opts.Add('openssl','Use OpenSSL (yes/no/builtin)','no')
 opts.Add('musepack','Musepack Audio (yes/no)','yes')
@@ -311,6 +312,8 @@ if selected_platform in platform_list:
 	if (env['colored']=='yes'):
 		methods.colored(sys,env)
 		
+	if (env['etc1']=='yes'):
+		env.Append(CPPFLAGS=['-DETC1_ENABLED'])
 
 	Export('env')
 

+ 2 - 1
drivers/etc1/SCsub

@@ -6,7 +6,8 @@ etc_sources = [
 	"etc1/rg_etc1.cpp"
 ]
 
-env.drivers_sources+=etc_sources
+if (env["etc1"] != "no"):
+    env.drivers_sources+=etc_sources
 
 #env.add_source_files(env.drivers_sources, etc_sources)
 

+ 4 - 1
drivers/etc1/rg_etc1.cpp

@@ -24,6 +24,9 @@
 namespace rg_etc1
 {
 
+   inline long labs(long val) {
+        return val < 0 ? -val : val;
+   }
 
    inline int intabs(int val) {
 
@@ -1913,7 +1916,7 @@ done:
                   for (uint packed_c = 0; packed_c < limit; packed_c++)
                   {
                      int v = etc1_decode_value(diff, inten, selector, packed_c);
-             uint err = intabs(v - color);
+                     uint err = labs(v - static_cast<int>(color));
 		     //printf("err: %d - %u = %u\n",v,color,err);
                      if (err < best_error)
                      {

+ 98 - 14
drivers/gles2/rasterizer_gles2.cpp

@@ -91,6 +91,10 @@
 
 static RasterizerGLES2* _singleton = NULL;
 
+#ifdef GLES_NO_CLIENT_ARRAYS
+static float GlobalVertexBuffer[MAX_POLYGON_VERTICES * 8] = {0};
+#endif
+
 static const GLenum prim_type[]={GL_POINTS,GL_LINES,GL_TRIANGLES,GL_TRIANGLE_FAN};
 
 _FORCE_INLINE_ static void _set_color_attrib(const Color& p_color) {
@@ -8341,20 +8345,22 @@ void RasterizerGLES2::canvas_draw_primitive(const Vector<Point2>& p_points, cons
 
 void RasterizerGLES2::canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor) {
 
-	bool do_colors=false;
+    bool do_colors=false;
+    Color m;
+    if (p_singlecolor) {
+        m = *p_colors;
+        m.a*=canvas_opacity;
+        _set_color_attrib(m);
+    } else if (!p_colors) {
+        m = Color(1, 1, 1, canvas_opacity);
+        _set_color_attrib(m);
+    } else
+        do_colors=true;
 
-	if (p_singlecolor) {
-		Color m = *p_colors;
-		m.a*=canvas_opacity;
-		_set_color_attrib(m);
-	} else if (!p_colors) {
-		_set_color_attrib( Color(1,1,1,canvas_opacity));
-	} else
-		do_colors=true;
-
-	Texture *texture = _bind_canvas_texture(p_texture);
+    Texture *texture = _bind_canvas_texture(p_texture);
 
-	glEnableVertexAttribArray(VS::ARRAY_VERTEX);
+#ifndef GLES_NO_CLIENT_ARRAYS
+    glEnableVertexAttribArray(VS::ARRAY_VERTEX);
 	glVertexAttribPointer( VS::ARRAY_VERTEX, 2 ,GL_FLOAT, false, sizeof(Vector2), p_vertices );
 	if (do_colors) {
 
@@ -8384,11 +8390,78 @@ void RasterizerGLES2::canvas_draw_polygon(int p_vertex_count, const int* p_indic
 		};
 		glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_SHORT, _draw_poly_indices );
 #endif
-		//glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_INT, p_indices );
 	} else {
 		glDrawArrays(GL_TRIANGLES,0,p_vertex_count);
 	}
 
+
+#else //WebGL specific impl.
+	glBindBuffer(GL_ARRAY_BUFFER, gui_quad_buffer);    
+    float *b = GlobalVertexBuffer;
+    int ofs = 0;
+    if(p_vertex_count > MAX_POLYGON_VERTICES){
+        print_line("Too many vertices to render");
+        return;
+    }
+    glEnableVertexAttribArray(VS::ARRAY_VERTEX);
+    glVertexAttribPointer( VS::ARRAY_VERTEX, 2 ,GL_FLOAT, false, sizeof(float)*2, ((float*)0)+ofs );
+    for(int i=0;i<p_vertex_count;i++) {
+        b[ofs++]=p_vertices[i].x;
+        b[ofs++]=p_vertices[i].y;
+    }
+
+    if (p_colors && do_colors) {
+
+        glEnableVertexAttribArray(VS::ARRAY_COLOR);
+        glVertexAttribPointer( VS::ARRAY_COLOR, 4 ,GL_FLOAT, false, sizeof(float)*4, ((float*)0)+ofs );
+        for(int i=0;i<p_vertex_count;i++) {
+            b[ofs++]=p_colors[i].r;
+            b[ofs++]=p_colors[i].g;
+            b[ofs++]=p_colors[i].b;
+            b[ofs++]=p_colors[i].a;
+        }
+
+    } else {
+        glDisableVertexAttribArray(VS::ARRAY_COLOR);
+    }
+
+
+    if (p_uvs) {
+
+        glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
+        glVertexAttribPointer( VS::ARRAY_TEX_UV, 2 ,GL_FLOAT, false, sizeof(float)*2, ((float*)0)+ofs );
+        for(int i=0;i<p_vertex_count;i++) {
+            b[ofs++]=p_uvs[i].x;
+            b[ofs++]=p_uvs[i].y;
+        }
+
+    } else {
+        glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
+    }
+
+    glBufferSubData(GL_ARRAY_BUFFER,0,ofs*4,&b[0]);
+
+    //bind the indices buffer.
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer);
+
+		static const int _max_draw_poly_indices = 16*1024; // change this size if needed!!!
+		ERR_FAIL_COND(p_vertex_count > _max_draw_poly_indices);
+		static uint16_t _draw_poly_indices[_max_draw_poly_indices];
+		for (int i=0; i<p_vertex_count; i++) {
+			_draw_poly_indices[i] = p_indices[i];
+             //OS::get_singleton()->print("ind: %d ", p_indices[i]);
+		};
+
+        //copy the data to GPU.
+        glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, p_vertex_count * sizeof(uint16_t), &_draw_poly_indices[0]);
+
+        //draw the triangles.
+        glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_SHORT, 0);
+
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+#endif
+
 	_rinfo.ci_draw_commands++;
 
 };
@@ -10673,10 +10746,21 @@ void RasterizerGLES2::init() {
 
 	glGenBuffers(1,&gui_quad_buffer);
 	glBindBuffer(GL_ARRAY_BUFFER,gui_quad_buffer);
-	glBufferData(GL_ARRAY_BUFFER,128,NULL,GL_DYNAMIC_DRAW);
+#ifdef GLES_NO_CLIENT_ARRAYS //WebGL specific implementation.
+    glBufferData(GL_ARRAY_BUFFER, 8 * MAX_POLYGON_VERTICES,NULL,GL_DYNAMIC_DRAW);
+#else
+    glBufferData(GL_ARRAY_BUFFER,128,NULL,GL_DYNAMIC_DRAW);
+#endif
 	glBindBuffer(GL_ARRAY_BUFFER,0); //unbind
 
 
+#ifdef GLES_NO_CLIENT_ARRAYS    //webgl indices buffer
+    glGenBuffers(1, &indices_buffer);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 16*1024, NULL, GL_DYNAMIC_DRAW);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);// unbind
+#endif
+
 	using_canvas_bg=false;
 	_update_framebuffer();
 	DEBUG_TEST_ERROR("Initializing");

+ 3 - 0
drivers/gles2/rasterizer_gles2.h

@@ -31,6 +31,8 @@
 
 #include "servers/visual/rasterizer.h"
 
+#define MAX_POLYGON_VERTICES 4096 //used for WebGL canvas_draw_polygon call.
+
 #ifdef GLES2_ENABLED
 
 #include "image.h"
@@ -828,6 +830,7 @@ class RasterizerGLES2 : public Rasterizer {
 	GLuint base_framebuffer;
 
 	GLuint gui_quad_buffer;
+	GLuint indices_buffer;
 
 
 

+ 3 - 0
drivers/register_driver_types.cpp

@@ -222,7 +222,10 @@ void register_driver_types() {
 #endif
 #endif
 
+#ifdef ETC1_ENABLED
 	_register_etc1_compress_func();
+#endif
+
 	initialize_chibi();
 }
 

+ 21 - 16
platform/javascript/detect.py

@@ -10,9 +10,9 @@ def get_name():
 
 def can_build():
 
-        import os
-        if (not os.environ.has_key("EMSCRIPTEN_ROOT")):
-        	return False
+	import os
+	if (not os.environ.has_key("EMSCRIPTEN_ROOT")):
+		return False
 	return True
 
 def get_opts():
@@ -36,6 +36,7 @@ def get_flags():
 		('squish', 'no'),
 		('speex', 'no'),
 		('old_scenes', 'no'),
+		('etc1', 'no'),
 #		('default_gui_theme', 'no'),
 
 		#('builtin_zlib', 'no'),
@@ -44,33 +45,36 @@ def get_flags():
 
 
 def configure(env):
-
-
 	env.Append(CPPPATH=['#platform/javascript'])
-	
+
 	em_path=os.environ["EMSCRIPTEN_ROOT"]
-	
+
 	env['ENV']['PATH'] = em_path+":"+env['ENV']['PATH']
 
 	env['CC'] = em_path+'/emcc'
 	env['CXX'] = em_path+'/emcc'
-	env['AR'] = em_path+"/emar"
-	env['RANLIB'] = em_path+"/emranlib"
+	#env['AR'] = em_path+"/emar"
+	env['AR'] = em_path+"/emcc"
+	env['ARFLAGS'] = "-o"
+
+#	env['RANLIB'] = em_path+"/emranlib"
+	env['RANLIB'] = em_path + "/emcc"
+	env['OBJSUFFIX'] = '.bc'
+	env['LIBSUFFIX'] = '.bc'
+	env['CCCOM'] = "$CC -o $TARGET $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES"
+	env['CXXCOM'] = "$CC -o $TARGET $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES"
 
 #	env.Append(LIBS=['c','m','stdc++','log','GLESv1_CM','GLESv2'])
 
 #	env["LINKFLAGS"]= string.split(" -g --sysroot="+ld_sysroot+" -Wl,--no-undefined -Wl,-z,noexecstack ")
 
 	if (env["target"]=="release"):
-
 		env.Append(CCFLAGS=['-O2'])
-
 	elif (env["target"]=="release_debug"):
-
 		env.Append(CCFLAGS=['-O2','-DDEBUG_ENABLED'])
-
 	elif (env["target"]=="debug"):
 		env.Append(CCFLAGS=['-D_DEBUG', '-Wall', '-O2', '-DDEBUG_ENABLED'])
+		#env.Append(CCFLAGS=['-D_DEBUG', '-Wall', '-g4', '-DDEBUG_ENABLED'])
 		env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC'])
 
 	env.Append(CPPFLAGS=["-fno-exceptions",'-DNO_SAFE_CAST','-fno-rtti'])
@@ -84,10 +88,11 @@ def configure(env):
 		lzma_binpath = em_path+"/third_party/lzma.js/lzma-native"
 		lzma_decoder = em_path+"/third_party/lzma.js/lzma-decoder.js"
 		lzma_dec = "LZMA.decompress"
-
 		env.Append(LINKFLAGS=['--compression',lzma_binpath+","+lzma_decoder+","+lzma_dec])
 
 	env.Append(LINKFLAGS=['-s','ASM_JS=1'])
 	env.Append(LINKFLAGS=['-O2'])
-
-
+	#env.Append(LINKFLAGS=['-g4'])
+	
+	#print "CCCOM is:", env.subst('$CCCOM')
+	#print "P: ", env['p'], " Platofrm: ", env['platform']