mirror of
https://github.com/GTAmodding/modelviewjs.git
synced 2025-07-08 18:10:14 +02:00
261 lines
6.0 KiB
JavaScript
261 lines
6.0 KiB
JavaScript
var RenderPass = -1;
|
|
|
|
var defaultPipe = {
|
|
renderCB: defaultRenderCB
|
|
};
|
|
var matFXPipe = {
|
|
renderCB: matfxRenderCB
|
|
};
|
|
var carPipe = {
|
|
renderCB: carRenderCB
|
|
};
|
|
|
|
function
|
|
RenderThisPass(mat)
|
|
{
|
|
switch(RenderPass){
|
|
case 0: // opaque
|
|
return mat.color[3] == 255;
|
|
case 1: // transparent
|
|
return mat.color[3] != 255;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
function
|
|
uploadState(proginfo)
|
|
{
|
|
gl.uniformMatrix4fv(proginfo.u.u_proj, false, state.projectionMatrix);
|
|
gl.uniformMatrix4fv(proginfo.u.u_view, false, state.viewMatrix);
|
|
gl.uniformMatrix4fv(proginfo.u.u_world, false, state.worldMatrix);
|
|
if(proginfo.u.u_env)
|
|
gl.uniformMatrix4fv(proginfo.u.u_env, false, state.envMatrix);
|
|
|
|
gl.uniform3fv(proginfo.u.u_ambLight, state.ambLight);
|
|
gl.uniform3fv(proginfo.u.u_lightDir, state.lightDir);
|
|
gl.uniform3fv(proginfo.u.u_lightCol, state.lightCol);
|
|
|
|
gl.uniform1i(proginfo.u.u_tex0, 0);
|
|
gl.uniform1i(proginfo.u.u_tex1, 1);
|
|
gl.uniform1i(proginfo.u.u_tex2, 2);
|
|
|
|
gl.uniform1f(proginfo.u.u_alphaRef, state.alphaRef);
|
|
}
|
|
|
|
function
|
|
setAttributes(attribs, proginfo)
|
|
{
|
|
for(let i = 0; i < attribs.length; i++){
|
|
a = attribs[i];
|
|
if(proginfo.a[a.index] < 0)
|
|
continue;
|
|
gl.vertexAttribPointer(proginfo.a[a.index],
|
|
a.size, a.type,
|
|
a.normalized,
|
|
a.stride, a.offset);
|
|
gl.enableVertexAttribArray(proginfo.a[a.index]);
|
|
}
|
|
}
|
|
|
|
function
|
|
resetAttributes(attribs, proginfo)
|
|
{
|
|
for(let i = 0; i < attribs.length; i++){
|
|
a = attribs[i];
|
|
if(proginfo.a[a.index] >= 0)
|
|
gl.disableVertexAttribArray(proginfo.a[a.index]);
|
|
}
|
|
}
|
|
|
|
function
|
|
defaultRenderCB(atomic)
|
|
{
|
|
if(!atomic.visible)
|
|
return;
|
|
|
|
mat4.copy(state.worldMatrix, atomic.frame.ltm);
|
|
|
|
let header = atomic.geometry.instData;
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, header.vbo);
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, header.ibo);
|
|
|
|
let prg = defaultProgram;
|
|
gl.useProgram(prg.program);
|
|
|
|
setAttributes(header.attribs, prg);
|
|
uploadState(prg);
|
|
|
|
for(let i = 0; i < header.inst.length; i++){
|
|
inst = header.inst[i];
|
|
m = inst.material;
|
|
|
|
if(!RenderThisPass(m))
|
|
continue;
|
|
|
|
gl.activeTexture(gl.TEXTURE0);
|
|
if(m.texture)
|
|
gl.bindTexture(gl.TEXTURE_2D, m.texture.tex);
|
|
else
|
|
gl.bindTexture(gl.TEXTURE_2D, whitetex);
|
|
|
|
vec4.scale(state.matColor, m.color, 1.0/255.0);
|
|
state.surfaceProps[0] = m.surfaceProperties[0];
|
|
state.surfaceProps[1] = m.surfaceProperties[1];
|
|
state.surfaceProps[2] = m.surfaceProperties[2];
|
|
|
|
gl.uniform4fv(prg.u.u_matColor, state.matColor);
|
|
gl.uniform4fv(prg.u.u_surfaceProps, state.surfaceProps);
|
|
|
|
if(m.color[3] != 255 || m.texture){
|
|
gl.enable(gl.BLEND);
|
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
}else
|
|
gl.disable(gl.BLEND);
|
|
|
|
gl.drawElements(header.prim, inst.numIndices, gl.UNSIGNED_SHORT, inst.offset);
|
|
}
|
|
|
|
resetAttributes(header.attribs, programInfo);
|
|
}
|
|
|
|
var envMatScale = mat4.fromValues(
|
|
-0.5, 0.0, 0.0, 0.0,
|
|
0.0, -0.5, 0.0, 0.0,
|
|
0.0, 0.0, 1.0, 0.0,
|
|
0.5, 0.5, 0.0, 1.0
|
|
);
|
|
|
|
function
|
|
matfxRenderCB(atomic)
|
|
{
|
|
if(!atomic.visible)
|
|
return;
|
|
|
|
mat4.copy(state.worldMatrix, atomic.frame.ltm);
|
|
|
|
let tmp = mat4.create();
|
|
mat4.invert(tmp, envFrame.ltm);
|
|
mat4.multiply(tmp, tmp, state.viewMatrix);
|
|
tmp[12] = tmp[13] = tmp[14] = 0.0;
|
|
|
|
mat4.multiply(state.envMatrix, envMatScale, tmp);
|
|
|
|
let header = atomic.geometry.instData;
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, header.vbo);
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, header.ibo);
|
|
|
|
let prg = envMapProgram;
|
|
gl.useProgram(prg.program);
|
|
|
|
setAttributes(header.attribs, prg);
|
|
uploadState(prg);
|
|
|
|
for(let i = 0; i < header.inst.length; i++){
|
|
inst = header.inst[i];
|
|
m = inst.material;
|
|
|
|
if(!RenderThisPass(m))
|
|
continue;
|
|
|
|
gl.activeTexture(gl.TEXTURE0);
|
|
if(m.texture)
|
|
gl.bindTexture(gl.TEXTURE_2D, m.texture.tex);
|
|
else
|
|
gl.bindTexture(gl.TEXTURE_2D, whitetex);
|
|
|
|
gl.activeTexture(gl.TEXTURE1);
|
|
envcoef = 0.0;
|
|
if(m.matfx && m.matfx.envTex){
|
|
envcoef = m.matfx.envCoefficient;
|
|
gl.bindTexture(gl.TEXTURE_2D, m.matfx.envTex.tex);
|
|
}else
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
|
|
vec4.scale(state.matColor, m.color, 1.0/255.0);
|
|
state.surfaceProps[0] = m.surfaceProperties[0];
|
|
state.surfaceProps[1] = envcoef;
|
|
state.surfaceProps[2] = m.surfaceProperties[2];
|
|
|
|
gl.uniform4fv(prg.u.u_matColor, state.matColor);
|
|
gl.uniform4fv(prg.u.u_surfaceProps, state.surfaceProps);
|
|
|
|
if(m.color[3] != 255 || m.texture){
|
|
gl.enable(gl.BLEND);
|
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
}else
|
|
gl.disable(gl.BLEND);
|
|
|
|
gl.drawElements(header.prim, inst.numIndices, gl.UNSIGNED_SHORT, inst.offset);
|
|
}
|
|
|
|
resetAttributes(header.attribs, programInfo);
|
|
}
|
|
|
|
function
|
|
carRenderCB(atomic)
|
|
{
|
|
if(!atomic.visible)
|
|
return;
|
|
|
|
mat4.copy(state.worldMatrix, atomic.frame.ltm);
|
|
|
|
let header = atomic.geometry.instData;
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, header.vbo);
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, header.ibo);
|
|
|
|
let prg = carPS2Program;
|
|
gl.useProgram(prg.program);
|
|
|
|
setAttributes(header.attribs, prg);
|
|
uploadState(prg);
|
|
|
|
for(let i = 0; i < header.inst.length; i++){
|
|
inst = header.inst[i];
|
|
m = inst.material;
|
|
|
|
if(!RenderThisPass(m))
|
|
continue;
|
|
|
|
gl.activeTexture(gl.TEXTURE0);
|
|
if(m.texture)
|
|
gl.bindTexture(gl.TEXTURE_2D, m.texture.tex);
|
|
else
|
|
gl.bindTexture(gl.TEXTURE_2D, whitetex);
|
|
|
|
let shininess = 0.0;
|
|
let specularity = 0.0;
|
|
|
|
if(m.fxFlags & 3){
|
|
shininess = m.envMap.shininess;
|
|
gl.activeTexture(gl.TEXTURE1);
|
|
gl.bindTexture(gl.TEXTURE_2D, m.envMap.texture.tex);
|
|
}
|
|
|
|
if(m.fxFlags & 4){
|
|
specularity = m.specMap.specularity;
|
|
gl.activeTexture(gl.TEXTURE2);
|
|
gl.bindTexture(gl.TEXTURE_2D, m.specMap.texture.tex);
|
|
}
|
|
|
|
vec4.scale(state.matColor, m.color, 1.0/255.0);
|
|
state.surfaceProps[0] = m.surfaceProperties[0];
|
|
state.surfaceProps[1] = specularity;
|
|
state.surfaceProps[2] = m.surfaceProperties[2];
|
|
state.surfaceProps[3] = shininess;
|
|
|
|
gl.uniform4fv(prg.u.u_matColor, state.matColor);
|
|
gl.uniform4fv(prg.u.u_surfaceProps, state.surfaceProps);
|
|
|
|
if(m.color[3] != 255 || m.texture){
|
|
gl.enable(gl.BLEND);
|
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
}else
|
|
gl.disable(gl.BLEND);
|
|
|
|
gl.drawElements(header.prim, inst.numIndices, gl.UNSIGNED_SHORT, inst.offset);
|
|
}
|
|
|
|
resetAttributes(header.attribs, programInfo);
|
|
}
|