UNPKG

mdx-m3-viewer

Version:

A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.

168 lines 9.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const handler_1 = require("./handler"); const batch_1 = require("./batch"); /** * A group of batches that are going to be rendered together. */ class BatchGroup { constructor(model, skinningType, isHd) { this.objects = []; this.model = model; this.skinningType = skinningType; this.isHd = isHd; } render(instance) { const scene = instance.scene; const camera = scene.camera; const textureOverrides = instance.textureOverrides; const layerAlphas = instance.layerAlphas; const model = this.model; const textures = model.textures; const batches = model.batches; const viewer = model.viewer; const mdxCache = viewer.sharedCache.get('mdx'); const gl = viewer.gl; const webgl = viewer.webgl; const skinningType = this.skinningType; const isHd = this.isHd; const teamColors = mdxCache.teamColors; const teamGlows = mdxCache.teamGlows; const shader = handler_1.default.getBatchShader(viewer, skinningType, isHd); shader.use(); const uniforms = shader.uniforms; gl.uniformMatrix4fv(uniforms['u_VP'], false, camera.viewProjectionMatrix); const boneTexture = instance.boneTexture; // Instances of models with no bones don't have a bone texture. if (boneTexture) { boneTexture.bind(15); gl.uniform1f(uniforms['u_hasBones'], 1); gl.uniform1i(uniforms['u_boneMap'], 15); gl.uniform1f(uniforms['u_vectorSize'], 1 / boneTexture.width); gl.uniform1f(uniforms['u_rowSize'], 1); } else { gl.uniform1f(uniforms['u_hasBones'], 0); } gl.uniform3fv(uniforms['u_lightPos'], scene.lightPosition); gl.bindBuffer(gl.ARRAY_BUFFER, model.arrayBuffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.elementBuffer); if (isHd) { gl.uniform1i(uniforms['u_diffuseMap'], 0); gl.uniform1i(uniforms['u_normalsMap'], 1); gl.uniform1i(uniforms['u_ormMap'], 2); gl.uniform1i(uniforms['u_emissiveMap'], 3); gl.uniform1i(uniforms['u_teamColorMap'], 4); gl.uniform1i(uniforms['u_environmentMap'], 5); // gl.uniform1i(uniforms['u_lutMap'], 6); // gl.uniform1i(uniforms['u_envDiffuseMap'], 7); // gl.uniform1i(uniforms['u_envSpecularMap'], 8); gl.disable(gl.BLEND); gl.enable(gl.DEPTH_TEST); gl.depthMask(true); gl.uniformMatrix4fv(uniforms['u_MV'], false, camera.viewMatrix); gl.uniform3fv(uniforms['u_eyePos'], camera.location); for (const index of this.objects) { const batch = batches[index]; const geoset = batch.geoset; const material = batch.material; const [diffuseLayer, normalsLayer, ormLayer, emissiveLayer, teamColorLayer, environmentMapLayer] = material.layers; const layerAlpha = layerAlphas[diffuseLayer.index]; if (layerAlpha > 0) { gl.uniform1f(uniforms['u_layerAlpha'], layerAlpha); gl.uniform1f(uniforms['u_filterMode'], diffuseLayer.filterMode); const diffuseId = diffuseLayer.textureId; const normalsId = normalsLayer.textureId; const ormId = ormLayer.textureId; const emissiveId = emissiveLayer.textureId; const teamColorId = teamColorLayer.textureId; const environmentMapId = environmentMapLayer.textureId; const diffuseTexture = textures[diffuseId]; const normalsTexture = textures[normalsId]; const ormTexture = textures[ormId]; const emissiveTexture = textures[emissiveId]; let teamColorTexture = textures[teamColorId]; const environmentMapTexture = textures[environmentMapId]; if (teamColorTexture.replaceableId === 0 || teamColorTexture.replaceableId === 1) { teamColorTexture = teamColors[instance.teamColor]; } const actualDiffuseTexture = textureOverrides.get(diffuseId) || diffuseTexture.texture; const actualNormalsTexture = textureOverrides.get(normalsId) || normalsTexture.texture; const actualOrmTexture = textureOverrides.get(ormId) || ormTexture.texture; const actualEmissiveTexture = textureOverrides.get(emissiveId) || emissiveTexture.texture; const actualTeamColorTexture = textureOverrides.get(teamColorId) || teamColorTexture.texture; const actualEnvironmentMapTexture = textureOverrides.get(environmentMapId) || environmentMapTexture.texture; webgl.bindTextureAndWrap(actualDiffuseTexture, 0, diffuseTexture.wrapS, diffuseTexture.wrapT); webgl.bindTextureAndWrap(actualNormalsTexture, 1, normalsTexture.wrapS, normalsTexture.wrapT); webgl.bindTextureAndWrap(actualOrmTexture, 2, ormTexture.wrapS, ormTexture.wrapT); webgl.bindTextureAndWrap(actualEmissiveTexture, 3, emissiveTexture.wrapS, emissiveTexture.wrapT); webgl.bindTextureAndWrap(actualTeamColorTexture, 4, teamColorTexture.wrapS, teamColorTexture.wrapT); webgl.bindTextureAndWrap(actualEnvironmentMapTexture, 5, environmentMapTexture.wrapS, environmentMapTexture.wrapT); // const { lutTexture, envDiffuseTexture, envSpecularTexture }= mdxCache; // if (lutTexture && envDiffuseTexture && envSpecularTexture) { // webgl.bindTextureAndWrap(lutTexture.texture, 6, lutTexture.wrapS, lutTexture.wrapT); // webgl.bindTextureAndWrap(envDiffuseTexture.texture, 7, envDiffuseTexture.wrapS, envDiffuseTexture.wrapT); // webgl.bindTextureAndWrap(envSpecularTexture.texture, 8, envSpecularTexture.wrapS, envSpecularTexture.wrapT); // } geoset.bindHd(shader, batch.skinningType, diffuseLayer.coordId); geoset.render(); } } } else { const geosetColors = instance.geosetColors; const layerTextures = instance.layerTextures; const uvAnims = instance.uvAnims; gl.uniform4fv(uniforms['u_vertexColor'], instance.vertexColor); gl.uniform1i(uniforms['u_texture'], 0); for (const object of this.objects) { const batch = batches[object]; const geoset = batch.geoset; const layer = batch.layer; const geosetIndex = geoset.index; const layerIndex = layer.index; const geosetColor = geosetColors[geosetIndex]; const layerAlpha = layerAlphas[layerIndex]; if (geosetColor[3] > 0.01 && layerAlpha > 0.01) { const textureIndex = layerTextures[layerIndex]; const layerTexture = textures[textureIndex]; const uvAnim = uvAnims[layerIndex]; gl.uniform4fv(uniforms['u_geosetColor'], geosetColor); gl.uniform1f(uniforms['u_layerAlpha'], layerAlpha); gl.uniform1f(uniforms['u_unshaded'], layer.unshaded); gl.uniform2f(uniforms['u_uvTrans'], uvAnim[0], uvAnim[1]); gl.uniform2f(uniforms['u_uvRot'], uvAnim[2], uvAnim[3]); gl.uniform1f(uniforms['u_uvScale'], uvAnim[4]); layer.bind(shader); let texture = textureOverrides.get(textureIndex); if (!texture) { const replaceable = layerTexture.replaceableId; let mdxTexture; if (replaceable === 1) { mdxTexture = teamColors[instance.teamColor]; } else if (replaceable === 2) { mdxTexture = teamGlows[instance.teamColor]; } else { mdxTexture = layerTexture; } if (mdxTexture) { texture = mdxTexture.texture; } } webgl.bindTextureAndWrap(texture, 0, layerTexture.wrapS, layerTexture.wrapT); if (skinningType === batch_1.SkinningType.ExtendedVertexGroups) { geoset.bindExtended(shader, layer.coordId); } else { geoset.bind(shader, layer.coordId); } geoset.render(); } } } } } exports.default = BatchGroup; //# sourceMappingURL=batchgroup.js.map