summaryrefslogtreecommitdiff
path: root/drivers/gles2/rasterizer_gles2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles2/rasterizer_gles2.cpp')
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp144
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() {