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 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 bindBuffer(ShellSurface surface, GLSL glsl) { GLES20.GlEnableVertexAttribArray(glsl.maPositionHandle); // GLES20.GlVertexAttribPointer (glsl.maPositionHandle, 3, GLES20.GlFloat, false, 0, surface.VertexBuffer); surface.VertNormUvBuffer.Position (0); GLES20.GlVertexAttribPointer (glsl.maPositionHandle, 3, GLES20.GlFloat, false, 8*sizeof(float), surface.VertNormUvBuffer); GLES20.GlEnableVertexAttribArray(glsl.maNormalHandle); surface.VertNormUvBuffer.Position (3); GLES20.GlVertexAttribPointer (glsl.maNormalHandle, 3, GLES20.GlFloat, false, 8*sizeof(float), surface.VertNormUvBuffer); // GLES20.GlVertexAttribPointer (glsl.maNormalHandle, 3, GLES20.GlFloat, false, 0, surface.NormalBuffer); GLES20.GlEnableVertexAttribArray(glsl.maUvHandle); surface.VertNormUvBuffer.Position (6); GLES20.GlVertexAttribPointer (glsl.maUvHandle, 2, GLES20.GlFloat, false, 8*sizeof(float), surface.VertNormUvBuffer); // GLES20.GlVertexAttribPointer (glsl.maUvHandle, 2, GLES20.GlFloat, false, 0, surface.UvBuffer); surface.VertNormUvBuffer.Position (0); checkGlError("drawGLES20 VertexAttribPointer vertex"); }
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); } } } } }
public void LoadPMD(string root, string dir, string name) { RenderSets.Add(new RenderSet("builtin:nomotion", "screen")); RenderSets.Add(new RenderSet("builtin:nomotion_alpha", "screen")); string path = root + dir + name; var surface = new PMD (path); surface.SetupShellSurface (); Surface = surface; AddTextures (root, dir); // Load ends Surface.Animation = false; Surface.Loaded = true; Log.Debug ("Shell", "PMD load ends."); }