diff options
Diffstat (limited to 'drivers/gles2/rasterizer_gles2.cpp')
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 144 |
1 files changed, 120 insertions, 24 deletions
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 39b448d6e0..e3a3e7def3 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-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 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 */ @@ -929,6 +929,7 @@ void RasterizerGLES2::texture_allocate(RID p_texture,int p_width, int p_height,I texture->compressed=compressed; texture->has_alpha=false; //by default it doesn't have alpha unless something with alpha is blitteds texture->data_size=0; + texture->mipmaps=0; glActiveTexture(GL_TEXTURE0); @@ -1086,6 +1087,7 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu glGenerateMipmap(texture->target); } + texture->mipmaps=mipmaps; @@ -1269,11 +1271,14 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) { p_flags&=VS::TEXTURE_FLAG_FILTER;//can change only filter } + bool had_mipmaps = texture->flags&VS::TEXTURE_FLAG_MIPMAPS; + glActiveTexture(GL_TEXTURE0); glBindTexture(texture->target, texture->tex_id); uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP; texture->flags=p_flags|cube; // can't remove a cube from being a cube + 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->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) { @@ -1304,9 +1309,13 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) { } } - if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) + if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) { + if (!had_mipmaps && texture->mipmaps==1) { + glGenerateMipmap(texture->target); + } glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,use_fast_texture_filter?GL_LINEAR_MIPMAP_NEAREST:GL_LINEAR_MIPMAP_LINEAR); - else{ + + } else{ if (texture->flags&VS::TEXTURE_FLAG_FILTER) { glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR); } else { @@ -6746,7 +6755,13 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans if (e->instance->billboard) { Vector3 scale = xf.basis.get_scale(); - xf.set_look_at(xf.origin,xf.origin+p_view_transform.get_basis().get_axis(2),p_view_transform.get_basis().get_axis(1)); + + if (current_rt && current_rt_vflip) { + xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), -p_view_transform.get_basis().get_axis(1)); + } else { + xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), p_view_transform.get_basis().get_axis(1)); + } + xf.basis.scale(scale); } material_shader.set_uniform(MaterialShaderGLES2::WORLD_TRANSFORM, xf); @@ -8330,6 +8345,14 @@ void RasterizerGLES2::canvas_draw_rect(const Rect2& p_rect, int p_flags, const R if ( texture ) { + bool untile=false; + + if (p_flags&CANVAS_RECT_TILE && !(texture->flags&VS::TEXTURE_FLAG_REPEAT)) { + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + untile=true; + } + if (!(p_flags&CANVAS_RECT_REGION)) { Rect2 region = Rect2(0,0,texture->width,texture->height); @@ -8340,6 +8363,12 @@ void RasterizerGLES2::canvas_draw_rect(const Rect2& p_rect, int p_flags, const R _draw_textured_quad(p_rect, p_source, Size2(texture->width,texture->height),p_flags&CANVAS_RECT_FLIP_H,p_flags&CANVAS_RECT_FLIP_V,p_flags&CANVAS_RECT_TRANSPOSE); } + + if (untile) { + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + } + } else { //glDisable(GL_TEXTURE_2D); @@ -9169,10 +9198,23 @@ void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem //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; + int x; + int y; + int w; + int h; + + if (current_rt) { + x = current_clip->final_clip_rect.pos.x; + y = current_clip->final_clip_rect.pos.y; + w = current_clip->final_clip_rect.size.x; + h = current_clip->final_clip_rect.size.y; + } + else { + x = current_clip->final_clip_rect.pos.x; + y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y); + w = current_clip->final_clip_rect.size.x; + h = current_clip->final_clip_rect.size.y; + } glScissor(x,y,w,h); @@ -9218,7 +9260,13 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *mater glReadBuffer(GL_BACK); } #endif - glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height); + if (current_rt) { + glCopyTexSubImage2D(GL_TEXTURE_2D,0,viewport.x,viewport.y,viewport.x,viewport.y,viewport.width,viewport.height); + canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(viewport.y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height)); + //window_size.height-(viewport.height+viewport.y) + } else { + glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height); + } // if (current_clip) { // // print_line(" a clip "); // } @@ -9362,10 +9410,23 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const 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; + int x; + int y; + int w; + int h; + + if (current_rt) { + x = current_clip->final_clip_rect.pos.x; + y = current_clip->final_clip_rect.pos.y; + w = current_clip->final_clip_rect.size.x; + h = current_clip->final_clip_rect.size.y; + } + else { + x = current_clip->final_clip_rect.pos.x; + y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y); + w = current_clip->final_clip_rect.size.x; + h = current_clip->final_clip_rect.size.y; + } glScissor(x,y,w,h); @@ -9402,7 +9463,12 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const glReadBuffer(GL_BACK); } #endif - glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,w,h); + if (current_rt) { + glCopyTexSubImage2D(GL_TEXTURE_2D,0,viewport.x,viewport.y,viewport.x,viewport.y,viewport.width,viewport.height); + //window_size.height-(viewport.height+viewport.y) + } else { + glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height); + } // if (current_clip) { // // print_line(" a clip "); // } @@ -9514,7 +9580,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_opacity = ci->final_opacity; - if (unshaded || (p_modulate.a>0.001 && (!material || material->shading_mode!=VS::CANVAS_ITEM_SHADING_ONLY_LIGHT))) + if (unshaded || (p_modulate.a>0.001 && (!material || material->shading_mode!=VS::CANVAS_ITEM_SHADING_ONLY_LIGHT) && !ci->light_masked )) _canvas_item_render_commands<false>(ci,current_clip,reclip); if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && !unshaded) { @@ -9546,7 +9612,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); glBlendFunc(GL_SRC_ALPHA,GL_ONE); } break; - case VS::CANVAS_LIGHT_MODE_MIX: { + case VS::CANVAS_LIGHT_MODE_MIX: + case VS::CANVAS_LIGHT_MODE_MASK: { glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -9594,6 +9661,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,Color(light->color.r*light->energy,light->color.g*light->energy,light->color.b*light->energy,light->color.a)); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT,light->height); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX,light->xform_cache.affine_inverse()); + canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_OUTSIDE_ALPHA,light->mode==VS::CANVAS_LIGHT_MODE_MASK?1.0:0.0); if (has_shadow) { @@ -9667,10 +9735,23 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const //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; + int x; + int y; + int w; + int h; + + if (current_rt) { + x = current_clip->final_clip_rect.pos.x; + y = current_clip->final_clip_rect.pos.y; + w = current_clip->final_clip_rect.size.x; + h = current_clip->final_clip_rect.size.y; + } + else { + x = current_clip->final_clip_rect.pos.x; + y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y); + w = current_clip->final_clip_rect.size.x; + h = current_clip->final_clip_rect.size.y; + } glScissor(x,y,w,h); @@ -10265,6 +10346,8 @@ void RasterizerGLES2::_update_framebuffer() { return; int scale = GLOBAL_DEF("rasterizer/framebuffer_shrink",1); + if (scale<1) + scale=1; int dwidth = OS::get_singleton()->get_video_mode().width/scale; int dheight = OS::get_singleton()->get_video_mode().height/scale; @@ -10353,6 +10436,13 @@ void RasterizerGLES2::_update_framebuffer() { GLuint format_rgba = GL_RGBA; GLuint format_rgb = use_fp16_fb?_GL_RGB16F_EXT:GL_RGB; GLuint format_type = use_fp16_fb?_GL_HALF_FLOAT_OES:GL_UNSIGNED_BYTE; + GLuint format_internal=GL_RGBA; + + if (use_16bits_fbo) { + format_type=GL_UNSIGNED_SHORT_5_6_5; + format_rgba=GL_RGB; + format_internal=GL_RGB; + } /*GLuint format_luminance = use_fp16_fb?GL_RGB16F:GL_RGBA; GLuint format_luminance_type = use_fp16_fb?(use_fu_GL_HALF_FLOAT_OES):GL_UNSIGNED_BYTE; GLuint format_luminance_components = use_fp16_fb?GL_RGB:GL_RGBA;*/ @@ -10366,7 +10456,7 @@ void RasterizerGLES2::_update_framebuffer() { glGenTextures(1, &framebuffer.color); glBindTexture(GL_TEXTURE_2D, framebuffer.color); - glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, framebuffer.width, framebuffer.height, 0, GL_RGBA, format_type, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, framebuffer.width, framebuffer.height, 0, format_internal, format_type, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -10391,7 +10481,7 @@ void RasterizerGLES2::_update_framebuffer() { framebuffer.fbo=0; framebuffer.active=false; //print_line("**************** NO FAMEBUFFEEEERRRR????"); - WARN_PRINT("Could not create framebuffer!!"); + WARN_PRINT(String("Could not create framebuffer!!, code: "+itos(status)).ascii().get_data()); } //sample @@ -10400,7 +10490,7 @@ void RasterizerGLES2::_update_framebuffer() { glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.sample_fbo); glGenTextures(1, &framebuffer.sample_color); glBindTexture(GL_TEXTURE_2D, framebuffer.sample_color); - glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, framebuffer.width, framebuffer.height, 0, GL_RGBA, format_type, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, framebuffer.width, framebuffer.height, 0, format_internal, format_type, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -10460,7 +10550,7 @@ void RasterizerGLES2::_update_framebuffer() { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, size, size, 0, - GL_RGBA, format_type, NULL); + format_internal, format_type, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebuffer.blur[i].color, 0); @@ -11189,6 +11279,11 @@ RasterizerGLES2* RasterizerGLES2::get_singleton() { int RasterizerGLES2::RenderList::max_elements=RenderList::DEFAULT_MAX_ELEMENTS; +void RasterizerGLES2::set_force_16_bits_fbo(bool p_force) { + + use_16bits_fbo=p_force; +} + RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,bool p_default_fragment_lighting,bool p_use_reload_hooks) { _singleton = this; @@ -11250,6 +11345,7 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo framebuffer.active=false; tc0_id_cache=0; tc0_idx=0; + use_16bits_fbo=false; }; void RasterizerGLES2::restore_framebuffer() { |