summaryrefslogtreecommitdiff
path: root/drivers/gles2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles2')
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp255
-rw-r--r--drivers/gles2/rasterizer_gles2.h9
-rw-r--r--drivers/gles2/rasterizer_instance_gles2.cpp2
-rw-r--r--drivers/gles2/rasterizer_instance_gles2.h2
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp70
-rw-r--r--drivers/gles2/shader_compiler_gles2.h10
-rw-r--r--drivers/gles2/shader_gles2.cpp2
-rw-r--r--drivers/gles2/shader_gles2.h2
-rw-r--r--drivers/gles2/shaders/canvas.glsl16
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