diff options
Diffstat (limited to 'drivers/gles2/rasterizer_gles2.cpp')
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 500 |
1 files changed, 451 insertions, 49 deletions
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index f876b1acd3..bb0fd2e593 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -403,19 +403,55 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For if (!image.empty()) image.convert(Image::FORMAT_RGBA); r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; } break; case Image::FORMAT_RGB: { r_gl_components=3; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_EXT:GL_RGB; + + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_EXT; + } else { + r_gl_format=GL_RGB; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGB; + } } break; case Image::FORMAT_RGBA: { r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } + r_has_alpha_cache=true; } break; case Image::FORMAT_BC1: { @@ -426,7 +462,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For image.decompress(); } r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; } else { @@ -445,7 +492,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For image.decompress(); } r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; } else { @@ -465,7 +523,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For image.decompress(); } r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; } else { @@ -484,7 +553,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For image.decompress(); } r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; } else { @@ -503,7 +583,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For image.decompress(); } r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; } else { @@ -520,7 +611,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For image.decompress(); } r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; @@ -540,7 +642,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For if (!image.empty()) image.decompress(); r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; @@ -561,7 +674,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For if (!image.empty()) image.decompress(); r_gl_components=4; - r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; } else { @@ -578,7 +702,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For if (!image.empty()) image.decompress(); r_gl_components=4; - r_gl_format=GL_RGBA; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_ALPHA_EXT; + } else { + r_gl_format=GL_RGBA; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGBA; + } r_has_alpha_cache=true; } else { @@ -590,12 +725,24 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For } break; case Image::FORMAT_ETC: { - if (!etc_supported) { + if (!etc_supported || p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { if (!image.empty()) { image.decompress(); } r_gl_components=3; + if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + + if (srgb_supported) { + r_gl_format=_GL_SRGB_EXT; + } else { + r_gl_format=GL_RGB; + if (!image.empty()) + image.srgb_to_linear(); + } + } else { + r_gl_format=GL_RGB; + } r_gl_format=GL_RGB; @@ -1458,6 +1605,7 @@ void RasterizerGLES2::material_set_flag(RID p_material, VS::MaterialFlag p_flag, Material *material = material_owner.get(p_material); ERR_FAIL_COND(!material); ERR_FAIL_INDEX(p_flag,VS::MATERIAL_FLAG_MAX); + material->flags[p_flag]=p_enabled; } @@ -4271,7 +4419,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { enablers.push_back("#define ENABLE_UV_INTERP\n"); if (fragment_flags.use_uv2_interp || vertex_flags.use_uv2_interp) enablers.push_back("#define ENABLE_UV2_INTERP\n"); - if (fragment_flags.use_tangent_interp || vertex_flags.use_tangent_interp) + if (fragment_flags.use_tangent_interp || vertex_flags.use_tangent_interp || fragment_flags.uses_normalmap) enablers.push_back("#define ENABLE_TANGENT_INTERP\n"); if (fragment_flags.use_var1_interp || vertex_flags.use_var1_interp) enablers.push_back("#define ENABLE_VAR1_INTERP\n"); @@ -4286,6 +4434,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { if (fragment_flags.uses_discard) { enablers.push_back("#define ENABLE_DISCARD\n"); } + if (fragment_flags.uses_normalmap) { + enablers.push_back("#define ENABLE_NORMALMAP\n"); + } if (light_flags.uses_light) { enablers.push_back("#define USE_LIGHT_SHADER_CODE\n"); } @@ -4715,6 +4866,7 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF_HQ,shadow_filter==SHADOW_FILTER_PCF13); material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_ESM,shadow_filter==SHADOW_FILTER_ESM); material_shader.set_conditional(MaterialShaderGLES2::USE_LIGHTMAP_ON_UV2,p_material->flags[VS::MATERIAL_FLAG_LIGHTMAP_ON_UV2]); + material_shader.set_conditional(MaterialShaderGLES2::USE_COLOR_ATTRIB_SRGB_TO_LINEAR,p_material->flags[VS::MATERIAL_FLAG_COLOR_ARRAY_SRGB] && current_env && current_env->fx_enabled[VS::ENV_FX_SRGB]); if (p_opaque_pass && p_material->depth_draw_mode==VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA && p_material->shader_cache && p_material->shader_cache->has_alpha) { @@ -4956,7 +5108,7 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) { if (li->near_shadow_buffer) { - glActiveTexture(GL_TEXTURE7); + glActiveTexture(GL_TEXTURE0+max_texture_units-1); //if (read_depth_supported) { glBindTexture(GL_TEXTURE_2D,li->near_shadow_buffer->depth); @@ -4967,7 +5119,7 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) { material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX,li->shadow_projection[0]); material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXEL_SIZE,Vector2(1.0,1.0)/li->near_shadow_buffer->size); - material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXTURE,7); + material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXTURE,max_texture_units-1); if (shadow_filter==SHADOW_FILTER_ESM) material_shader.set_uniform(MaterialShaderGLES2::ESM_MULTIPLIER,float(li->base->vars[VS::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER])); @@ -5011,7 +5163,7 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) { } -template<bool USE_NORMAL, bool USE_TANGENT> +template<bool USE_NORMAL, bool USE_TANGENT,bool INPLACE> void RasterizerGLES2::_skeleton_xform(const uint8_t * p_src_array, int p_src_stride, uint8_t * p_dst_array, int p_dst_stride, int p_elements,const uint8_t *p_src_bones, const uint8_t *p_src_weights, const Skeleton::Bone *p_bone_xforms) { uint32_t basesize = 3; @@ -5021,6 +5173,8 @@ void RasterizerGLES2::_skeleton_xform(const uint8_t * p_src_array, int p_src_str basesize+=4; uint32_t extra=(p_dst_stride-basesize*4); + const int dstvec_size=3+(USE_NORMAL?3:0)+(USE_TANGENT?4:0); + float dstcopy[dstvec_size]; for(int i=0;i<p_elements;i++) { @@ -5029,7 +5183,11 @@ void RasterizerGLES2::_skeleton_xform(const uint8_t * p_src_array, int p_src_str const uint16_t *bi = (const uint16_t*)&p_src_bones[ss]; const float *bw = (const float *)&p_src_weights[ss]; const float *src_vec=(const float *)&p_src_array[ss]; - float *dst_vec=(float*)&p_dst_array[ds]; + float *dst_vec; + if (INPLACE) + dst_vec=dstcopy; + else + dst_vec=(float*)&p_dst_array[ds]; dst_vec[0]=0.0; dst_vec[1]=0.0; @@ -5082,16 +5240,28 @@ void RasterizerGLES2::_skeleton_xform(const uint8_t * p_src_array, int p_src_str end: - //copy extra stuff - const uint8_t *esp =(const uint8_t*) &src_vec[basesize]; - uint8_t *edp =(uint8_t*) &dst_vec[basesize]; + if (INPLACE) { + const uint8_t *esp =(const uint8_t*) dstcopy; + uint8_t *edp =(uint8_t*)&p_dst_array[ds]; - for(uint32_t j=0;j<extra;j++) { - edp[j]=esp[j]; - } + for(uint32_t j=0;j<dstvec_size*4;j++) { + + edp[j]=esp[j]; + } + } else { + //copy extra stuff + const uint8_t *esp =(const uint8_t*) &src_vec[basesize]; + uint8_t *edp =(uint8_t*) &dst_vec[basesize]; + + + for(uint32_t j=0;j<extra;j++) { + + edp[j]=esp[j]; + } + } } } @@ -5166,6 +5336,8 @@ Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Materia } + int16_t coeffp = CLAMP(coef*255,0,255); + for(int i=0;i<VS::ARRAY_MAX-1;i++) { @@ -5175,9 +5347,13 @@ Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Materia int ofs = ad.ofs; int src_stride=surf->stride; - int dst_stride=surf->local_stride; + int dst_stride=skeleton_valid?surf->stride:surf->local_stride; int count = surf->array_len; + if (!skeleton_valid && i>=VS::ARRAY_MAX-3) + break; + + switch(i) { case VS::ARRAY_VERTEX: @@ -5193,7 +5369,21 @@ Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Materia dst[0]= src[0]*coef; dst[1]= src[1]*coef; dst[2]= src[2]*coef; - } break; + }; + + } break; + case VS::ARRAY_COLOR: { + + for(int k=0;k<count;k++) { + + const uint8_t *src = (const uint8_t*)&surf->array_local[ofs+k*src_stride]; + uint8_t *dst = (uint8_t*)&base[ofs+k*dst_stride]; + + dst[0]= (src[0]*coeffp)>>8; + dst[1]= (src[1]*coeffp)>>8; + dst[2]= (src[2]*coeffp)>>8; + dst[3]= (src[3]*coeffp)>>8; + } } break; case VS::ARRAY_TEX_UV: @@ -5206,16 +5396,32 @@ Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Materia dst[0]= src[0]*coef; dst[1]= src[1]*coef; - } break; + } } break; + case VS::ARRAY_BONES: + case VS::ARRAY_WEIGHTS: { + + for(int k=0;k<count;k++) { + + const float *src = (const float*)&surf->array_local[ofs+k*src_stride]; + float *dst = (float*)&base[ofs+k*dst_stride]; + + dst[0]= src[0]; + dst[1]= src[1]; + dst[2]= src[2]; + dst[3]= src[3]; + } + + } break; + } } for(int j=0;j<surf->morph_target_count;j++) { - for(int i=0;i<VS::ARRAY_MAX-1;i++) { + for(int i=0;i<VS::ARRAY_MAX-3;i++) { const Surface::ArrayData& ad=surf->array[i]; if (ad.size==0) @@ -5223,10 +5429,12 @@ Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Materia int ofs = ad.ofs; - int dst_stride=surf->local_stride; + int src_stride=surf->local_stride; + int dst_stride=skeleton_valid?surf->stride:surf->local_stride; int count = surf->array_len; const uint8_t *morph=surf->morph_targets_local[j].array; float w = p_morphs[j]; + int16_t wfp = CLAMP(w*255,0,255); switch(i) { @@ -5237,13 +5445,26 @@ Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Materia for(int k=0;k<count;k++) { - const float *src_morph = (const float*)&morph[ofs+k*dst_stride]; + const float *src_morph = (const float*)&morph[ofs+k*src_stride]; float *dst = (float*)&base[ofs+k*dst_stride]; dst[0]+= src_morph[0]*w; dst[1]+= src_morph[1]*w; dst[2]+= src_morph[2]*w; - } break; + } + + } break; + case VS::ARRAY_COLOR: { + for(int k=0;k<count;k++) { + + const uint8_t *src = (const uint8_t*)&morph[ofs+k*src_stride]; + uint8_t *dst = (uint8_t*)&base[ofs+k*dst_stride]; + + dst[0]= (src[0]*wfp)>>8; + dst[1]= (src[1]*wfp)>>8; + dst[2]= (src[2]*wfp)>>8; + dst[3]= (src[3]*wfp)>>8; + } } break; case VS::ARRAY_TEX_UV: @@ -5251,18 +5472,43 @@ Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Materia for(int k=0;k<count;k++) { - const float *src_morph = (const float*)&morph[ofs+k*dst_stride]; + const float *src_morph = (const float*)&morph[ofs+k*src_stride]; float *dst = (float*)&base[ofs+k*dst_stride]; dst[0]+= src_morph[0]*w; dst[1]+= src_morph[1]*w; - } break; + } } break; } } } + + + if (skeleton_valid) { + + + + const uint8_t *src_weights=&surf->array_local[surf->array[VS::ARRAY_WEIGHTS].ofs]; + const uint8_t *src_bones=&surf->array_local[surf->array[VS::ARRAY_BONES].ofs]; + const Skeleton::Bone *skeleton = &p_skeleton->bones[0]; + + + if (surf->format&VS::ARRAY_FORMAT_NORMAL && surf->format&VS::ARRAY_FORMAT_TANGENT) + _skeleton_xform<true,true,true>(base,surf->stride,base,surf->stride,surf->array_len,src_bones,src_weights,skeleton); + else if (surf->format&(VS::ARRAY_FORMAT_NORMAL)) + _skeleton_xform<true,false,true>(base,surf->stride,base,surf->stride,surf->array_len,src_bones,src_weights,skeleton); + else if (surf->format&(VS::ARRAY_FORMAT_TANGENT)) + _skeleton_xform<false,true,true>(base,surf->stride,base,surf->stride,surf->array_len,src_bones,src_weights,skeleton); + else + _skeleton_xform<false,false,true>(base,surf->stride,base,surf->stride,surf->array_len,src_bones,src_weights,skeleton); + + } + + stride=skeleton_valid?surf->stride:surf->local_stride; + + #if 0 { //in-place skeleton tansformation, only used for morphs, slow. @@ -5356,14 +5602,14 @@ Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Materia const uint8_t *src_bones=&surf->array_local[surf->array[VS::ARRAY_BONES].ofs]; const Skeleton::Bone *skeleton = &p_skeleton->bones[0]; - if (surf->format&VS::ARRAY_FORMAT_NORMAL && surf->format&VS::ARRAY_FORMAT_TANGENT) - _skeleton_xform<true,true>(surf->array_local,surf->stride,base,dst_stride,surf->array_len,src_bones,src_weights,skeleton); + if (surf->format&VS::ARRAY_FORMAT_NORMAL && surf->format&VS::ARRAY_FORMAT_TANGENT) + _skeleton_xform<true,true,false>(surf->array_local,surf->stride,base,dst_stride,surf->array_len,src_bones,src_weights,skeleton); else if (surf->format&(VS::ARRAY_FORMAT_NORMAL)) - _skeleton_xform<true,false>(surf->array_local,surf->stride,base,dst_stride,surf->array_len,src_bones,src_weights,skeleton); + _skeleton_xform<true,false,false>(surf->array_local,surf->stride,base,dst_stride,surf->array_len,src_bones,src_weights,skeleton); else if (surf->format&(VS::ARRAY_FORMAT_TANGENT)) - _skeleton_xform<false,true>(surf->array_local,surf->stride,base,dst_stride,surf->array_len,src_bones,src_weights,skeleton); + _skeleton_xform<false,true,false>(surf->array_local,surf->stride,base,dst_stride,surf->array_len,src_bones,src_weights,skeleton); else - _skeleton_xform<false,false>(surf->array_local,surf->stride,base,dst_stride,surf->array_len,src_bones,src_weights,skeleton); + _skeleton_xform<false,false,false>(surf->array_local,surf->stride,base,dst_stride,surf->array_len,src_bones,src_weights,skeleton); stride=dst_stride; @@ -5493,9 +5739,10 @@ void RasterizerGLES2::_render(const Geometry *p_geometry,const Material *p_mater float twd=(1.0/mm->tw)*4.0; float thd=1.0/mm->th; float parm[3]={0.0,01.0,(1.0f/mm->tw)}; - glActiveTexture(GL_TEXTURE6); + glActiveTexture(GL_TEXTURE0+max_texture_units-2); glDisableVertexAttribArray(6); glBindTexture(GL_TEXTURE_2D,mm->tex_id); + material_shader.set_uniform(MaterialShaderGLES2::INSTANCE_MATRICES,GL_TEXTURE0+max_texture_units-2); if (s->index_array_len>0) { @@ -5796,7 +6043,7 @@ void RasterizerGLES2::_setup_skeleton(const Skeleton *p_skeleton) { material_shader.set_conditional(MaterialShaderGLES2::USE_SKELETON,p_skeleton!=NULL); if (p_skeleton && p_skeleton->tex_id) { - glActiveTexture(GL_TEXTURE6); + glActiveTexture(GL_TEXTURE0+max_texture_units-2); glBindTexture(GL_TEXTURE_2D,p_skeleton->tex_id); } @@ -5845,7 +6092,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans bool stores_glow = !shadow && (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) && !p_alpha_pass; - + float sampled_light_dp_multiplier=1.0; bool prev_blend=false; glDisable(GL_BLEND); @@ -5864,6 +6111,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans bool bind_baked_light_octree=false; bool bind_baked_lightmap=false; bool additive=false; + bool bind_dp_sampler=false; if (!shadow) { @@ -5985,6 +6233,22 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE,false); material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP,false); + material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_DP_SAMPLER,false); + + if (e->instance->sampled_light.is_valid()) { + + SampledLight *sl = sampled_light_owner.get(e->instance->sampled_light); + if (sl) { + + baked_light=NULL; //can't mix + material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_DP_SAMPLER,true); + glActiveTexture(GL_TEXTURE0+max_texture_units-3); + glBindTexture(GL_TEXTURE_2D,sl->texture); //bind the texture + sampled_light_dp_multiplier=sl->multiplier; + bind_dp_sampler=true; + } + } + if (!additive && baked_light) { @@ -5995,9 +6259,16 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans Texture *tex=texture_owner.get(baked_light->octree_texture); if (tex) { - glActiveTexture(GL_TEXTURE5); + glActiveTexture(GL_TEXTURE0+max_texture_units-3); glBindTexture(tex->target,tex->tex_id); //bind the texture } + if (baked_light->light_texture.is_valid()) { + Texture *texl=texture_owner.get(baked_light->light_texture); + if (texl) { + glActiveTexture(GL_TEXTURE0+max_texture_units-4); + glBindTexture(texl->target,texl->tex_id); //bind the light texture + } + } } } else if (baked_light->mode==VS::BAKED_LIGHT_LIGHTMAPS) { @@ -6020,7 +6291,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans Texture *tex = texture_owner.get(texid); if (tex) { - glActiveTexture(GL_TEXTURE5); + glActiveTexture(GL_TEXTURE0+max_texture_units-3); glBindTexture(tex->target,tex->tex_id); //bind the texture } @@ -6096,7 +6367,15 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LATTICE_SIZE, baked_light->octree_lattice_size); material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LATTICE_DIVIDE, baked_light->octree_lattice_divide); material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_STEPS, baked_light->octree_steps); - material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_TEX,5); + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_TEX,max_texture_units-3); + if (baked_light->light_texture.is_valid()) { + + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_TEX,max_texture_units-4); + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_PIX_SIZE,baked_light->light_tex_pixel_size); + } else { + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_TEX,max_texture_units-3); + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_PIX_SIZE,baked_light->octree_tex_pixel_size); + } material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_MULTIPLIER,baked_light->texture_multiplier); material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_PIX_SIZE,baked_light->octree_tex_pixel_size); @@ -6105,11 +6384,16 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans if (bind_baked_lightmap && (baked_light!=prev_baked_light || rebind)) { - material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHTMAP, 5); + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHTMAP, max_texture_units-3); material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHTMAP_MULTIPLIER, baked_light->lightmap_multiplier); } + if (bind_dp_sampler) { + + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_DP_SAMPLER_MULTIPLIER,sampled_light_dp_multiplier); + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_DP_SAMPLER,max_texture_units-3); + } _set_cull(e->mirror,p_reverse_cull); @@ -6118,13 +6402,13 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans material_shader.set_uniform(MaterialShaderGLES2::CAMERA_INVERSE_TRANSFORM, p_view_transform_inverse); material_shader.set_uniform(MaterialShaderGLES2::PROJECTION_TRANSFORM, p_projection); if (skeleton && use_hw_skeleton_xform) { - //material_shader.set_uniform(MaterialShaderGLES2::SKELETON_MATRICES,6); + material_shader.set_uniform(MaterialShaderGLES2::SKELETON_MATRICES,GL_TEXTURE0+max_texture_units-2); material_shader.set_uniform(MaterialShaderGLES2::SKELTEX_PIXEL_SIZE,skeleton->pixel_size); } if (!shadow) { if (!additive && current_env && current_env->fx_enabled[VS::ENV_FX_AMBIENT_LIGHT]) { - Color ambcolor = current_env->fx_param[VS::ENV_FX_PARAM_AMBIENT_LIGHT_COLOR]; + Color ambcolor = _convert_color(current_env->fx_param[VS::ENV_FX_PARAM_AMBIENT_LIGHT_COLOR]); float ambnrg = current_env->fx_param[VS::ENV_FX_PARAM_AMBIENT_LIGHT_ENERGY]; material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHT,Vector3(ambcolor.r*ambnrg,ambcolor.g*ambnrg,ambcolor.b*ambnrg)); } else { @@ -6852,6 +7136,7 @@ void RasterizerGLES2::end_scene() { _debug_shadows(); } // _debug_luminances(); + _debug_samplers(); } @@ -7252,6 +7537,38 @@ void RasterizerGLES2::_debug_luminances() { } +void RasterizerGLES2::_debug_samplers() { + canvas_shader.set_conditional(CanvasShaderGLES2::DEBUG_ENCODED_32,false); + canvas_begin(); + glDisable(GL_BLEND); + _set_color_attrib(Color(1,1,1,1)); + canvas_shader.bind(); + + + List<RID> samplers; + sampled_light_owner.get_owned_list(&samplers); + + Size2 debug_size(128,128); + Size2 ofs; + + + for (List<RID>::Element *E=samplers.front();E;E=E->next()) { + + SampledLight *sl=sampled_light_owner.get(E->get()); + + _debug_draw_shadow(sl->texture, Rect2( ofs, debug_size )); + + ofs.x+=debug_size.x/2; + if ( (ofs.x+debug_size.x) > viewport.width ) { + + ofs.x=0; + ofs.y+=debug_size.y; + } + } + + + +} void RasterizerGLES2::_debug_shadows() { canvas_begin(); @@ -7869,6 +8186,78 @@ Variant RasterizerGLES2::environment_fx_get_param(RID p_env,VS::EnvironmentFxPar } + + +RID RasterizerGLES2::sampled_light_dp_create(int p_width,int p_height) { + + SampledLight *slight = memnew(SampledLight); + slight->w=p_width; + slight->h=p_height; + slight->multiplier=1.0; + slight->is_float=float_linear_supported; + + glActiveTexture(GL_TEXTURE0); + glGenTextures(1,&slight->texture); + glBindTexture(GL_TEXTURE_2D, slight->texture); +// for debug, but glitchy +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // Remove artifact on the edges of the shadowmap + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + + if (slight->is_float) { +#ifdef GLEW_ENABLED + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_width, p_height, 0, GL_RGBA, GL_FLOAT,NULL); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_width, p_height, 0, GL_RGBA, GL_FLOAT,NULL); +#endif + } else { + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_width, p_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + } + + return sampled_light_owner.make_rid(slight); +} + +void RasterizerGLES2::sampled_light_dp_update(RID p_sampled_light, const Color *p_data, float p_multiplier) { + + SampledLight *slight = sampled_light_owner.get(p_sampled_light); + ERR_FAIL_COND(!slight); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, slight->texture); + + if (slight->is_float) { + +#ifdef GLEW_ENABLED + glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,slight->w, slight->h, GL_RGBA, GL_FLOAT,p_data); +#else + glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,slight->w, slight->h, GL_RGBA, GL_FLOAT,p_data); +#endif + + } else { + //convert to bytes + uint8_t *tex8 = (uint8_t*)alloca(slight->w*slight->h*4); + const float* src=(const float*)p_data; + + for(int i=0;i<slight->w*slight->h*4;i++) { + + tex8[i]=Math::fast_ftoi(CLAMP(src[i]*255.0,0.0,255.0)); + } + + glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,slight->w, slight->h, GL_RGBA, GL_UNSIGNED_BYTE,p_data); + } + + slight->multiplier=p_multiplier; + +} + /*MISC*/ bool RasterizerGLES2::is_texture(const RID& p_rid) const { @@ -8088,6 +8477,13 @@ void RasterizerGLES2::free(const RID& p_rid) { memdelete(render_target->texture_ptr); render_target_owner.free(p_rid); memdelete( render_target ); + } else if (sampled_light_owner.owns(p_rid)) { + + SampledLight *sampled_light = sampled_light_owner.get( p_rid ); + ERR_FAIL_COND(!sampled_light); + glDeleteTextures(1,&sampled_light->texture); + sampled_light_owner.free(p_rid); + memdelete( sampled_light ); }; } @@ -8680,6 +9076,9 @@ void RasterizerGLES2::init() { latc_supported=true; s3tc_srgb_supported=true; use_anisotropic_filter=true; + float_linear_supported=true; + float_supported=true; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&anisotropic_level); anisotropic_level=MIN(anisotropic_level,float(GLOBAL_DEF("rasterizer/anisotropic_filter_level",4.0))); #ifdef OSX_ENABLED @@ -8724,7 +9123,10 @@ void RasterizerGLES2::init() { GLint vtf; glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,&vtf); - use_hw_skeleton_xform=vtf>0 && extensions.has("GL_OES_texture_float"); + float_supported = extensions.has("GL_OES_texture_float"); + use_hw_skeleton_xform=vtf>0 && float_supported; + float_linear_supported = extensions.has("GL_OES_texture_float_linear"); + //if (extensions.has("GL_QCOM_tiled_rendering")) // use_hw_skeleton_xform=false; GLint mva; @@ -8762,7 +9164,7 @@ void RasterizerGLES2::init() { - + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_units); //read_depth_supported=false; { |