private void drawNonAlpha(ShellSurface surface, GLSL glsl) { var mats = surface.RenderLists; int max = mats.Count; // draw non-alpha material // GLES20.GlEnable(GLES20.GlCullFace); GLES20.GlEnable(2884); GLES20.GlCullFace(GLES20.GlBack); GLES20.GlDisable(GLES20.GlBlend); for (int r = 0; r < max; r++) { var mat = mats[r]; TexInfo tb = null; if (mat.material.texture != null) { tb = TextureFile.FetchTexInfo(mat.material.texture); } if (mat.material.diffuse_color[3] >= 1.0 && (tb == null || !tb.has_alpha)) { drawOneMaterial(glsl, surface, mat); } } }
private void drawOneMaterial(GLSL glsl, ShellSurface surface, RenderList mat) { // set motion if (surface.Animation) { if (mat.bone_inv_map == null) { for (int j = 0; j < surface.RenderBones.Count; j++) { var b = surface.RenderBones[j]; if (b != null) { Array.Copy(b.matrix, 0, mBoneMatrix, j * 16, 16); } } } else { for (int j = 0; j < mat.bone_inv_map.Length; j++) { int inv = mat.bone_inv_map[j]; if (inv >= 0) { var b = surface.RenderBones[inv]; Array.Copy(b.matrix, 0, mBoneMatrix, j * 16, 16); } } } GLES20.GlUniformMatrix4fv(glsl.muMBone, mat.bone_num, false, mBoneMatrix, 0); GLES20.GlEnableVertexAttribArray(glsl.maBlendHandle); GLES20.GlVertexAttribPointer(glsl.maBlendHandle, 3, GLES20.GlUnsignedByte, false, 0, mat.weight); } // initialize color for (int i = 0; i < mDifAmb.Count(); i++) { mDifAmb[i] = 1.0f; } // diffusion and ambient float wi = 0.6f; // light color = (0.6, 0.6, 0.6) for (int i = 0; i < 3; i++) { mDifAmb[i] *= mat.material.diffuse_color[i] * wi + mat.material.emmisive_color[i]; } mDifAmb[3] *= mat.material.diffuse_color[3]; Vector.min(mDifAmb, 1.0f); GLES20.GlUniform4fv(glsl.muDif, 1, mDifAmb, 0); // speculation if (glsl.muPow >= 0) { GLES20.GlUniform4f(glsl.muSpec, mat.material.specular_color[0], mat.material.specular_color[1], mat.material.specular_color[2], 0); GLES20.GlUniform1f(glsl.muPow, mat.material.power); } // toon GLES20.GlUniform1i(glsl.msToonSampler, 0); GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name[mat.material.toon_index]).tex); // texture GLES20.GlUniform1i(glsl.msTextureSampler, 1); GLES20.GlActiveTexture(GLES20.GlTexture1); if (mat.material.texture != null) { TexInfo tb = TextureFile.FetchTexInfo(mat.material.texture); if (tb != null) { GLES20.GlBindTexture(GLES20.GlTexture2d, tb.tex); } else // avoid crash { GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name[0]).tex); // white texture using toon0.bmp for (int i = 0; i < 3; i++) // for emulate premultiplied alpha { mDifAmb[i] *= mat.material.diffuse_color[3]; } } } else { GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name[0]).tex); // white texture using toon0.bmp for (int i = 0; i < 3; i++) // for emulate premultiplied alpha { mDifAmb[i] *= mat.material.diffuse_color[3]; } } // sphere(sph) GLES20.GlUniform1i(glsl.msSphSampler, 2); GLES20.GlActiveTexture(GLES20.GlTexture2); if (mat.material.sph != null) { TexInfo tb = TextureFile.FetchTexInfo(mat.material.sph); if (tb != null) { GLES20.GlBindTexture(GLES20.GlTexture2d, tb.tex); } else // avoid crash { GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name [0]).tex); // white texture using toon0.bmp } } else { GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name[0]).tex); // white texture using toon0.bmp } // sphere(spa) GLES20.GlUniform1i(glsl.msSpaSampler, 3); GLES20.GlActiveTexture(GLES20.GlTexture3); if (mat.material.spa != null) { TexInfo tb = TextureFile.FetchTexInfo(mat.material.spa); if (tb != null) { GLES20.GlBindTexture(GLES20.GlTexture2d, tb.tex); } } // draw surface.IndexBuffer.Position(mat.face_vert_offset); GLES20.GlDrawElements(GLES20.GlTriangles, mat.face_vert_count, GLES20.GlUnsignedShort, surface.IndexBuffer); checkGlError("glDrawElements"); }
private void drawAlpha(ShellSurface surface, GLSL glsl, bool alpha_test) { int max = surface.RenderLists.Count(); // draw alpha material GLES20.GlEnable(GLES20.GlBlend); for (int r = 0; r < max; r++) { var mat = surface.RenderLists[r]; TexInfo tb = null; if (mat.material.texture != null) { tb = TextureFile.FetchTexInfo(mat.material.texture); } if (alpha_test) { if (tb != null && tb.needs_alpha_test) { if (mat.material.diffuse_color[3] < 1.0) { // GLES20.GlDisable(GLES20.GL_CULL_FACE); GLES20.GlDisable(2884); } else { // GLES20.GlEnable(GLES20.GL_CULL_FACE); GLES20.GlEnable(2884); } drawOneMaterial(glsl, surface, mat); } } else { if (tb != null) // has texture { if (!tb.needs_alpha_test) { if (tb.has_alpha) { if (mat.material.diffuse_color[3] < 1.0) { // GLES20.GlDisable(GLES20.GL_CULL_FACE); GLES20.GlDisable(2884); } else { // GLES20.GlEnable(GLES20.GL_CULL_FACE); GLES20.GlEnable(2884); } drawOneMaterial(glsl, surface, mat); } else if (mat.material.diffuse_color[3] < 1.0) { // GLES20.GlDisable(GLES20.GL_CULL_FACE); GLES20.GlDisable(2884); drawOneMaterial(glsl, surface, mat); } } } else { if (mat.material.diffuse_color[3] < 1.0) { // GLES20.GlDisable(GLES20.GL_CULL_FACE); GLES20.GlDisable(2884); drawOneMaterial(glsl, surface, mat); } } } } }