diff options
Diffstat (limited to 'drivers/gles2')
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 255 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 9 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_instance_gles2.cpp | 2 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_instance_gles2.h | 2 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 70 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.h | 10 | ||||
-rw-r--r-- | drivers/gles2/shader_gles2.cpp | 2 | ||||
-rw-r--r-- | drivers/gles2/shader_gles2.h | 2 | ||||
-rw-r--r-- | drivers/gles2/shaders/canvas.glsl | 16 |
9 files changed, 307 insertions, 61 deletions
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 3660be20db..d3a5f3b5bc 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -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) { @@ -1009,10 +1013,16 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu bool force_clamp_to_edge = !(texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (nearest_power_of_2(texture->alloc_height)!=texture->alloc_height || nearest_power_of_2(texture->alloc_width)!=texture->alloc_width); - if (!force_clamp_to_edge && texture->flags&VS::TEXTURE_FLAG_REPEAT && texture->target != GL_TEXTURE_CUBE_MAP) { + if (!force_clamp_to_edge && (texture->flags&VS::TEXTURE_FLAG_REPEAT || texture->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) { - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + if (texture->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT){ + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT ); + } + else{ + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + } } else { //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); @@ -1042,6 +1052,8 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu int size,ofs; img.get_mipmap_offset_and_size(i,ofs,size); + //print_line("mipmap: "+itos(i)+" size: "+itos(size)+" w: "+itos(mm_w)+", h: "+itos(mm_h)); + if (texture->compressed) { glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glCompressedTexImage2D( blit_target, i, format,w,h,0,size,&read[ofs] ); @@ -1049,7 +1061,7 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu } else { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if (texture->flags&VS::TEXTURE_FLAG_VIDEO_SURFACE) { - glTexSubImage2D( blit_target, i, 0,0,w,h,format,GL_UNSIGNED_BYTE,&read[ofs] ); + glTexSubImage2D( blit_target, i, 0,0,w, h,format,GL_UNSIGNED_BYTE,&read[ofs] ); } else { glTexImage2D(blit_target, i, internal_format, w, h, 0, format, GL_UNSIGNED_BYTE,&read[ofs]); } @@ -1257,7 +1269,6 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) { p_flags&=VS::TEXTURE_FLAG_FILTER;//can change only filter } - glActiveTexture(GL_TEXTURE0); glBindTexture(texture->target, texture->tex_id); uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP; @@ -1265,10 +1276,16 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) { bool force_clamp_to_edge = !(p_flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (nearest_power_of_2(texture->alloc_height)!=texture->alloc_height || nearest_power_of_2(texture->alloc_width)!=texture->alloc_width); - if (!force_clamp_to_edge && texture->flags&VS::TEXTURE_FLAG_REPEAT && texture->target != GL_TEXTURE_CUBE_MAP) { + if (!force_clamp_to_edge && (texture->flags&VS::TEXTURE_FLAG_REPEAT || texture->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) { - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + if (texture->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT){ + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT ); + } + else { + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + } } else { //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); glTexParameterf( texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); @@ -1607,7 +1624,8 @@ Variant RasterizerGLES2::shader_get_default_param(RID p_shader, const StringName RID RasterizerGLES2::material_create() { - return material_owner.make_rid( memnew( Material ) ); + RID material = material_owner.make_rid( memnew( Material ) ); + return material; } void RasterizerGLES2::material_set_shader(RID p_material, RID p_shader) { @@ -1647,6 +1665,9 @@ void RasterizerGLES2::material_set_param(RID p_material, const StringName& p_par } } else { + if (p_value.get_type()==Variant::NIL) + return; + Material::UniformData ud; ud.index=-1; ud.value=p_value; @@ -4262,17 +4283,21 @@ void RasterizerGLES2::capture_viewport(Image* r_capture) { glReadPixels( viewport.x, window_size.height-(viewport.height+viewport.y), viewport.width,viewport.height,GL_RGBA,GL_UNSIGNED_BYTE,w.ptr()); } - uint32_t *imgptr = (uint32_t*)w.ptr(); - for(int y=0;y<(viewport.height/2);y++) { + bool flip = current_rt==NULL; + + if (flip) { + uint32_t *imgptr = (uint32_t*)w.ptr(); + for(int y=0;y<(viewport.height/2);y++) { - uint32_t *ptr1 = &imgptr[y*viewport.width]; - uint32_t *ptr2 = &imgptr[(viewport.height-y-1)*viewport.width]; + uint32_t *ptr1 = &imgptr[y*viewport.width]; + uint32_t *ptr2 = &imgptr[(viewport.height-y-1)*viewport.width]; - for(int x=0;x<viewport.width;x++) { + for(int x=0;x<viewport.width;x++) { - uint32_t tmp = ptr1[x]; - ptr1[x]=ptr2[x]; - ptr2[x]=tmp; + uint32_t tmp = ptr1[x]; + ptr1[x]=ptr2[x]; + ptr2[x]=tmp; + } } } @@ -4381,7 +4406,7 @@ void RasterizerGLES2::begin_shadow_map( RID p_light_instance, int p_shadow_pass } -void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_projection) { +void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint) { camera_transform=p_world; if (current_rt && current_rt_vflip) { @@ -4389,10 +4414,11 @@ void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_ } camera_transform_inverse=camera_transform.inverse(); camera_projection=p_projection; - camera_plane = Plane( camera_transform.origin, camera_transform.basis.get_axis(2) ); + camera_plane = Plane( camera_transform.origin, -camera_transform.basis.get_axis(2) ); camera_z_near=camera_projection.get_z_near(); camera_z_far=camera_projection.get_z_far(); camera_projection.get_viewport_size(camera_vp_size.x,camera_vp_size.y); + camera_ortho=p_ortho_hint; } void RasterizerGLES2::add_light( RID p_light_instance ) { @@ -4595,6 +4621,10 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { if (fragment_flags.uses_normal) { enablers.push_back("#define NORMAL_USED\n"); } + if (fragment_flags.uses_normalmap) { + enablers.push_back("#define USE_NORMALMAP\n"); + } + if (light_flags.uses_light) { enablers.push_back("#define USE_LIGHT_SHADER_CODE\n"); } @@ -4751,8 +4781,11 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD e->geometry_cmp=p_geometry_cmp; e->material=m; e->instance=p_instance; - //e->depth=camera_plane.distance_to(p_world->origin); - e->depth=camera_transform.origin.distance_to(p_instance->transform.origin); + if (camera_ortho) { + e->depth=camera_plane.distance_to(p_instance->transform.origin); + } else { + e->depth=camera_transform.origin.distance_to(p_instance->transform.origin); + } e->owner=p_owner; e->light_type=0; e->additive=false; @@ -5197,7 +5230,7 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material DEBUG_TEST_ERROR("Material arameters"); if (p_material->shader_cache->uses_time) { - material_shader.set_uniform(MaterialShaderGLES2::TIME,Math::fmod(last_time,300.0)); + material_shader.set_uniform(MaterialShaderGLES2::TIME,Math::fmod(last_time,shader_time_rollback)); draw_next_frame=true; } //if uses TIME - draw_next_frame=true @@ -7980,8 +8013,16 @@ void RasterizerGLES2::canvas_set_clip(bool p_clip, const Rect2& p_rect) { if (p_clip) { glEnable(GL_SCISSOR_TEST); - glScissor(viewport.x+p_rect.pos.x,viewport.y+ (viewport.height-(p_rect.pos.y+p_rect.size.height)), - p_rect.size.width,p_rect.size.height); + //glScissor(viewport.x+p_rect.pos.x,viewport.y+ (viewport.height-(p_rect.pos.y+p_rect.size.height)), + + int x = p_rect.pos.x; + int y = window_size.height-(p_rect.pos.y+p_rect.size.y); + int w = p_rect.size.x; + int h = p_rect.size.y; + + glScissor(x,y,w,h); + + } else { glDisable(GL_SCISSOR_TEST); @@ -8340,20 +8381,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) { @@ -8383,11 +8426,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++; }; @@ -9005,8 +9115,17 @@ void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem } else { glEnable(GL_SCISSOR_TEST); - glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), - current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); + //glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), + //current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); + + int x = current_clip->final_clip_rect.pos.x; + int y = window_size.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y); + int w = current_clip->final_clip_rect.size.x; + int h = current_clip->final_clip_rect.size.y; + + glScissor(x,y,w,h); + + reclip=false; } } @@ -9116,7 +9235,7 @@ void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItemMaterial *mat } if (shader->uses_time) { - canvas_shader.set_uniform(CanvasShaderGLES2::TIME,Math::fmod(last_time,300.0)); + canvas_shader.set_uniform(CanvasShaderGLES2::TIME,Math::fmod(last_time,shader_time_rollback)); draw_next_frame=true; } //if uses TIME - draw_next_frame=true @@ -9180,8 +9299,21 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const if (current_clip) { glEnable(GL_SCISSOR_TEST); - glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), - current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); + //glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), + //current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); + +/* int x = viewport.x+current_clip->final_clip_rect.pos.x; + int y = window_size.height-(viewport.y+current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y); + int w = current_clip->final_clip_rect.size.x; + int h = current_clip->final_clip_rect.size.y; +*/ + int x = current_clip->final_clip_rect.pos.x; + int y = window_size.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y); + int w = current_clip->final_clip_rect.size.x; + int h = current_clip->final_clip_rect.size.y; + + glScissor(x,y,w,h); + } else { glDisable(GL_SCISSOR_TEST); @@ -9263,7 +9395,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const _canvas_item_setup_shader_uniforms(material,shader_cache); } - bool unshaded = material && material->shading_mode==VS::CANVAS_ITEM_SHADING_UNSHADED; + bool unshaded = (material && material->shading_mode==VS::CANVAS_ITEM_SHADING_UNSHADED) || ci->blend_mode!=VS::MATERIAL_BLEND_MODE_MIX; if (unshaded) { canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,Color(1,1,1,1)); @@ -9335,6 +9467,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const while(light) { + if (ci->light_mask&light->item_mask && p_z>=light->z_min && p_z<=light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache,light->rect_cache)) { //intersects this light @@ -9372,6 +9505,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const } + bool has_shadow = light->shadow_buffer.is_valid() && ci->light_mask&light->item_shadow_mask; canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS,has_shadow); @@ -9414,6 +9548,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_TEXTURE,max_texture_units-3); canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX,light->shadow_matrix_cache); canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_ESM_MULTIPLIER,light->shadow_esm_mult); + canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_SHADOW_COLOR,light->shadow_color); } @@ -9470,8 +9605,17 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const if (reclip) { glEnable(GL_SCISSOR_TEST); - glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), - current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); + //glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), + //current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); + + int x = current_clip->final_clip_rect.pos.x; + int y = window_size.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y); + int w = current_clip->final_clip_rect.size.x; + int h = current_clip->final_clip_rect.size.y; + + glScissor(x,y,w,h); + + } @@ -10669,13 +10813,27 @@ void RasterizerGLES2::init() { current_rt=NULL; current_vd=NULL; current_debug=VS::SCENARIO_DEBUG_DISABLED; + camera_ortho=false; 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 + + shader_time_rollback = GLOBAL_DEF("rasterizer/shader_time_rollback",300); + using_canvas_bg=false; _update_framebuffer(); DEBUG_TEST_ERROR("Initializing"); @@ -10683,7 +10841,10 @@ void RasterizerGLES2::init() { void RasterizerGLES2::finish() { + free(default_material); + free(shadow_material); free(canvas_shadow_blur); + free( overdraw_material ); } int RasterizerGLES2::get_render_info(VS::RenderInfo p_info) { diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index ad18c8e7a1..d337ecfb64 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -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; @@ -1049,6 +1052,7 @@ class RasterizerGLES2 : public Rasterizer { float camera_z_near; float camera_z_far; Size2 camera_vp_size; + bool camera_ortho; Set<String> extensions; bool texscreen_copied; bool texscreen_used; @@ -1270,6 +1274,7 @@ class RasterizerGLES2 : public Rasterizer { Environment *current_env; VS::ScenarioDebugMode current_debug; RID overdraw_material; + float shader_time_rollback; mutable MaterialShaderGLES2 material_shader; @@ -1585,7 +1590,7 @@ public: virtual void begin_shadow_map( RID p_light_instance, int p_shadow_pass ); - virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection); + virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint); virtual void add_light( RID p_light_instance ); ///< all "add_light" calls happen before add_geometry calls diff --git a/drivers/gles2/rasterizer_instance_gles2.cpp b/drivers/gles2/rasterizer_instance_gles2.cpp index eec9431f36..a8d478c6e0 100644 --- a/drivers/gles2/rasterizer_instance_gles2.cpp +++ b/drivers/gles2/rasterizer_instance_gles2.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/gles2/rasterizer_instance_gles2.h b/drivers/gles2/rasterizer_instance_gles2.h index 97dcb7bc73..f5ac5f1fe2 100644 --- a/drivers/gles2/rasterizer_instance_gles2.h +++ b/drivers/gles2/rasterizer_instance_gles2.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 69bd269948..157f2e398b 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -243,6 +243,10 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a if (vnode->name==vname_normal) { uses_normal=true; } + if (vnode->name==vname_normalmap || vnode->name==vname_normalmap_depth) { + uses_normalmap=true; + uses_normal=true; + } if (vnode->name==vname_screen_uv) { uses_screen_uv=true; @@ -427,6 +431,42 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a // code="get_texpos(gl_ProjectionMatrixInverse * texture2D( depth_texture, clamp(("+dump_node_code(onode->arguments[1],p_level)+").xy,vec2(0.0),vec2(1.0))*gl_LightSource[5].specular.zw+gl_LightSource[5].specular.xy)"; //code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb"; break; + } else if (custom_h && callfunc=="cosh_custom") { + + if (!cosh_used) { + global_code= "float cosh_custom(float val)\n"\ + "{\n"\ + " float tmp = exp(val);\n"\ + " float cosH = (tmp + 1.0 / tmp) / 2.0;\n"\ + " return cosH;\n"\ + "}\n"+global_code; + cosh_used=true; + } + code="cosh_custom("+dump_node_code(onode->arguments[1],p_level)+""; + } else if (custom_h && callfunc=="sinh_custom") { + + if (!sinh_used) { + global_code= "float sinh_custom(float val)\n"\ + "{\n"\ + " float tmp = exp(val);\n"\ + " float sinH = (tmp - 1.0 / tmp) / 2.0;\n"\ + " return sinH;\n"\ + "}\n"+global_code; + sinh_used=true; + } + code="sinh_custom("+dump_node_code(onode->arguments[1],p_level)+""; + } else if (custom_h && callfunc=="tanh_custom") { + + if (!tanh_used) { + global_code= "float tanh_custom(float val)\n"\ + "{\n"\ + " float tmp = exp(val);\n"\ + " float tanH = (tmp - 1.0 / tmp) / (tmp + 1.0 / tmp);\n"\ + " return tanH;\n"\ + "}\n"+global_code; + tanh_used=true; + } + code="tanh_custom("+dump_node_code(onode->arguments[1],p_level)+""; } else { @@ -630,6 +670,9 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.use_var2_interp=false; r_flags.uses_normalmap=false; r_flags.uses_normal=false; + sinh_used=false; + tanh_used=false; + cosh_used=false; String error; int errline,errcol; @@ -658,12 +701,18 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.uses_shadow_color=uses_shadow_color; r_code_line=code; r_globals_line=global_code; - return OK; } ShaderCompilerGLES2::ShaderCompilerGLES2() { +#ifdef GLEW_ENABLED + //use custom functions because they are not supported in GLSL120 + custom_h=true; +#else + custom_h=false; +#endif + replace_table["bool"]= "bool"; replace_table["float" ]= "float"; replace_table["vec2" ]= "vec2"; @@ -682,9 +731,17 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { replace_table["acos" ]= "acos"; replace_table["atan" ]= "atan"; replace_table["atan2"]= "atan"; - replace_table["sinh" ]= "sinh"; - replace_table["cosh" ]= "cosh"; - replace_table["tanh" ]= "tanh"; + + if (custom_h) { + replace_table["sinh" ]= "sinh_custom"; + replace_table["cosh" ]= "cosh_custom"; + replace_table["tanh" ]= "tanh_custom"; + } else { + replace_table["sinh" ]= "sinh"; + replace_table["cosh" ]= "cosh"; + replace_table["tanh" ]= "tanh"; + } + replace_table["pow" ]= "pow"; replace_table["exp" ]= "exp"; replace_table["log" ]= "log"; @@ -810,6 +867,8 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { mode_replace_table[4]["POSITION"]="gl_Position"; mode_replace_table[4]["NORMAL"]="normal"; + mode_replace_table[4]["NORMALMAP"]="normal_map"; + mode_replace_table[4]["NORMALMAP_DEPTH"]="normal_depth"; mode_replace_table[4]["UV"]="uv_interp"; mode_replace_table[4]["SRC_COLOR"]="color_interp"; mode_replace_table[4]["COLOR"]="color"; @@ -861,6 +920,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { vname_light="LIGHT"; vname_time="TIME"; vname_normalmap="NORMALMAP"; + vname_normalmap_depth="NORMALMAP_DEPTH"; vname_normal="NORMAL"; vname_texpixel_size="TEXTURE_PIXEL_SIZE"; vname_world_vec="WORLD_VERTEX"; diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index 87016fd968..43902a7536 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -56,6 +56,13 @@ private: bool uses_worldvec; bool vertex_code_writes_vertex; bool uses_shadow_color; + + bool sinh_used; + bool tanh_used; + bool cosh_used; + + bool custom_h; + Flags *flags; StringName vname_discard; @@ -72,6 +79,7 @@ private: StringName vname_light; StringName vname_time; StringName vname_normalmap; + StringName vname_normalmap_depth; StringName vname_normal; StringName vname_texpixel_size; StringName vname_world_vec; diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index 6a4596cb1e..e94930fffb 100644 --- a/drivers/gles2/shader_gles2.cpp +++ b/drivers/gles2/shader_gles2.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h index 9cd6142eb0..4604fd5501 100644 --- a/drivers/gles2/shader_gles2.h +++ b/drivers/gles2/shader_gles2.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index c4f0847870..e297b328cd 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -152,6 +152,7 @@ uniform vec4 modulate; uniform sampler2D light_texture; uniform vec4 light_color; +uniform vec4 light_shadow_color; uniform float light_height; varying vec4 light_uv_interp; @@ -207,7 +208,17 @@ void main() { { +#if defined(USE_NORMALMAP) + vec3 normal_map=vec3(0.0,0.0,1.0); + float normal_depth=1.0; +#endif + FRAGMENT_SHADER_CODE + +#if defined(USE_NORMALMAP) + normal = mix(vec3(0.0,0.0,1.0), normal_map * vec3(2.0,-2.0,1.0) - vec3( 1.0, -1.0, 0.0 ), normal_depth ); +#endif + } #ifdef DEBUG_ENCODED_32 highp float enc32 = dot( color,highp vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) ); @@ -296,7 +307,7 @@ LIGHT_SHADER_CODE } - highp vec4 s = shadow_matrix * highp vec4(point,0.0,1.0); + highp vec4 s = shadow_matrix * vec4(point,0.0,1.0); s.xyz/=s.w; su=s.x*0.5+0.5; sz=s.z*0.5+0.5; @@ -369,7 +380,8 @@ LIGHT_SHADER_CODE #if defined(USE_LIGHT_SHADOW_COLOR) color=mix(shadow_color,color,shadow_attenuation); #else - color*=shadow_attenuation; + //color*=shadow_attenuation; + color=mix(light_shadow_color,color,shadow_attenuation); #endif //use shadows #endif |