2017-09-26 80 views
1

我正在用md2模型進行webgl演示。我知道這是一種舊格式,但我只需要使用md2。WebGL - 導入MD2模型,紋理問題

我閱讀md2格式的文檔。

我看着this網站是如何工作的: ,在我的程序中使用它的來源的一部分(我在評論中保存了作者的名字)

我做了頂點加載,模型加載太棒了!

但是,當我試圖映射texutre,奇怪的事情發生了:

Robot

首先,我認爲這是片段着色器的問題,但我用assimp2json製成的出口,用來自它的數據以及它應該繪製的數據。

問題是,assimp2json改變了三角形和uvs順序的頂點順序,所以我無法使用它調試程序。

也許,有人可以幫助找到錯誤,指出我的代碼中的錯誤?

PS因爲沒有動畫,我只用了第一幀

最有趣的是,如果我將通過未編入索引的數據(只是從文件中的UV),它看起來比索引的紋理更多的權利:

enter image description here

的問題是,這是錯誤的,有些地方,喜歡這裏:

enter image description here

完整的源代碼和模型:

ShaderProgram.js

class ShaderProgram 
{ 
    constructor(gl, VSSource, FSSource) // VS - Vertex Shader, FS - Fragment 
Shader 
     { 
    this.gl = gl; 
    let vertexShader = this.getShader(VSSource, gl.VERTEX_SHADER); 
    let fragmentShader = this.getShader(FSSource, gl.FRAGMENT_SHADER); 

    this.shaderProgram = gl.createProgram(); 

    gl.attachShader(this.shaderProgram, vertexShader); 
    gl.attachShader(this.shaderProgram, fragmentShader); 

    gl.linkProgram(this.shaderProgram); 

    if (!gl.getProgramParameter(this.shaderProgram, gl.LINK_STATUS)) { 
     alert("Can't load shaders"); 
    } 

    this.enableAttributes(); 
    this.getUniforms(); 

} 

getShader(source, type) 
{ 
    let gl = this.gl; 

    let shader = gl.createShader(type); 
    gl.shaderSource(shader, source); 
    gl.compileShader(shader); 

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 
     alert("Error compilation: " + gl.getShaderInfoLog(shader)); 
     gl.deleteShader(shader); 
     return null; 
    } 

    return shader; 
} 

getUniforms() 
{ 
    this.model = gl.getUniformLocation(this.shaderProgram, "model"); 
    this.view = gl.getUniformLocation(this.shaderProgram, "view"); 
    this.projection = gl.getUniformLocation(this.shaderProgram, "projection"); 

} 

enableAttributes() 
{ 
    let gl = this.gl; 
    let shaderProgram = this.shaderProgram; 


} 

use() 
{ 
    this.gl.useProgram(this.shaderProgram); 
} 


} 

Textures.js

function initTexture(filename) { 
let texture = gl.createTexture(); 
gl.bindTexture(gl.TEXTURE_2D, texture); 
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255])); 

let image = new Image(); 
image.onload = function() { handleTextureLoaded(image, texture); } 
image.src = filename; 

return texture; 
} 

function handleTextureLoaded(image, texture) { 
gl.bindTexture(gl.TEXTURE_2D, texture); 
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); 
gl.generateMipmap(gl.TEXTURE_2D); 
gl.bindTexture(gl.TEXTURE_2D, null); 
} 

MD2導入:

// BinaryReader 
// Refactored by Vjeux <[email protected]> 
// http://blog.vjeux.com/2010/javascript/javascript-binary-reader.html 

// Original 
//+ Jonas Raoni Soares Silva 
//@ http://jsfromhell.com/classes/binary-parser [rev. #1] 

BinaryReader = function (data) { 
this._buffer = data; 
this._pos = 0; 
}; 

BinaryReader.prototype = { 

/* Public */ 

readInt8: function(){ return this._decodeInt(8, true); }, 
readUInt8: function(){ return this._decodeInt(8, false); }, 
readInt16: function(){ return this._decodeInt(16, true); }, 
readUInt16: function(){ return this._decodeInt(16, false); }, 
readInt32: function(){ return this._decodeInt(32, true); }, 
readUInt32: function(){ return this._decodeInt(32, false); }, 

readFloat: function(){ return this._decodeFloat(23, 8); }, 
readDouble: function(){ return this._decodeFloat(52, 11); }, 

readChar: function() { return this.readString(1); }, 
readString: function (length) { 
    this._checkSize(length * 8); 
    var result = this._buffer.substr(this._pos, length); 
    this._pos += length; 
    return result; 
}, 

seek: function (pos) { 
    this._pos = pos; 
    this._checkSize(0); 
}, 

getPosition: function() { 
    return this._pos; 
}, 

getSize: function() { 
    return this._buffer.length; 
}, 


/* Private */ 

_decodeFloat: function(precisionBits, exponentBits) 
{ 

    return this._decodeFloat2(precisionBits, exponentBits); 


    var length = precisionBits + exponentBits + 1; 
    var size = length >> 3; 
    this._checkSize(length); 

    var bias = Math.pow(2, exponentBits - 1) - 1; 
    var signal = this._readBits(precisionBits + exponentBits, 1, size); 
    var exponent = this._readBits(precisionBits, exponentBits, size); 
    var significand = 0; 
    var divisor = 2; 
    var curByte = length + (-precisionBits >> 3) - 1; 

    do 
    { 
     var byteValue = this._readByte(++curByte, size); 
     var startBit = precisionBits % 8 || 8; 
     var mask = 1 << startBit; 

     while (mask >>= 1) 
     { 
      if (byteValue & mask) 
      { 
       significand += 1/divisor; 
      } 
      divisor *= 2; 
     } 
    } while (precisionBits -= startBit); 

    this._pos += size; 

    return exponent == (bias << 1) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity 
     : (1 + signal * -2) * (exponent || significand ? !exponent ? Math.pow(2, -bias + 1) * significand 
     : Math.pow(2, exponent - bias) * (1 + significand) : 0); 
}, 

// I added this because _decodeFloat gave me some real inaccuarate results? -Terry Butler 
_decodeFloat2: function(precisionBits, exponentBits) 
{ 
    var length = precisionBits + exponentBits + 1; 
    var value = this._decodeInt(length); 

    var sign = (value >> 31) & 0x1; 
    var allZero = 1; 
    var mantissa = 0.0; 
    var exponent = 0.0; 

    // Mantissa 
    for (var i = 22; i > -1; i--) 
    { 

     var test = 1.0/Math.pow(2, 23-i); 

     if ((value >> i & 0x1) == 1) 
     { 

      mantissa += test; 

      allZero = 0; 
     } 

    } 

    if (allZero == 0) 
     mantissa += 1.0; 

    // Exponent 
    for (var i = 30; i > 22; i--) 
    { 

     var test = Math.pow(2, i - 23); 

     if ((value >> i & 0x1) == 1) 
     { 
      exponent += test; 
     } 

    } 

    exponent -= 127.0; 

    // 
    var total = Math.pow(2.0, exponent) * mantissa; 

    // 
    if (sign == 1) 
    { 
     total *= -1.0; 
    } 

    return total; 

}, 

_decodeInt: function(bits, signed){ 
    var x = this._readBits(0, bits, bits/8), max = Math.pow(2, bits); 
    var result = signed && x >= max/2 ? x - max : x; 

    this._pos += bits/8; 
    return result; 
}, 

//shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) 
_shl: function (a, b){ 
    for (++b; --b; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); 
    return a; 
}, 

_readByte: function (i, size) { 
    return this._buffer.charCodeAt(this._pos + size - i - 1) & 0xff; 
}, 

_readBits: function (start, length, size) { 
    var offsetLeft = (start + length) % 8; 
    var offsetRight = start % 8; 
    var curByte = size - (start >> 3) - 1; 
    var lastByte = size + (-(start + length) >> 3); 
    var diff = curByte - lastByte; 

    var sum = (this._readByte(curByte, size) >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1); 

    if (diff && offsetLeft) { 
     sum += (this._readByte(lastByte++, size) & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight; 
    } 

    while (diff) { 
     sum += this._shl(this._readByte(lastByte++, size), (diff-- << 3) - offsetRight); 
    } 

    return sum; 
}, 

_checkSize: function (neededBits) { 
    if (!(this._pos + Math.ceil(neededBits/8) < this._buffer.length)) { 
     throw new Error("Index out of bound"); 
    } 
} 
}; 


/** 
* @author oosmoxiecode 
* based on http://www.terrybutler.co.uk/web-development/html5-canvas-md2- renderer/ 
* and 
* http://tfc.duke.free.fr/coding/md2-specs-en.html 
* 
* dependant on binaryReader.js 
* 
* Returns a object like: {string: json_string, info: {status: "Success",  faces: 10, vertices: 10, frames: 5 }} 
* 
**/ 

// Library is modified for this program by me 

function MD2_converter (file) { 

    var scope = this; 

    // Create the Binary Reader 
    var reader = new BinaryReader(file); 

    // Setup 
    var header = {}; 
    var frames = []; 
    var st = []; 
    var triag = []; 

    var string = ""; 
    var info = {}; 
    var returnObject = {string: string, info: info}; 

// Ident and version 
header.ident = reader.readString(4); 
header.version = reader.readInt32(); 

// Valid MD2 file? 
if (header.ident != "IDP2" || header.version != 8) { 
    info.status = "Not a valid MD2 file"; 
    return returnObject; 
} 

// header 
header.skinwidth  = reader.readInt32(); // texture width 
header.skinheight  = reader.readInt32(); // texture height 

header.framesize  = reader.readInt32(); // size in bytes of a frame 

header.num_skins  = reader.readInt32(); // number of skins 
header.num_vertices  = reader.readInt32(); // number of vertices per frame 
header.num_st   = reader.readInt32(); // number of texture coordinates 
header.num_tris   = reader.readInt32(); // number of triangles 
header.num_glcmds  = reader.readInt32(); // number of opengl commands 
header.num_frames  = reader.readInt32(); // number of frames 

header.offset_skins  = reader.readInt32(); // offset skin data 
header.offset_st  = reader.readInt32(); // offset texture coordinate data 
header.offset_tris  = reader.readInt32(); // offset triangle data 
header.offset_frames = reader.readInt32(); // offset frame data 
header.offset_glcmds = reader.readInt32(); // offset OpenGL command data 
header.offset_end  = reader.readInt32(); // offset end of file 

// faulty size 
if (reader.getSize() != header.offset_end) { 
    info.status = "Corrupted MD2 file"; 
    return returnObject; 
} 

// texture coordinates 
let count = 0; 
reader.seek(header.offset_st); 
for (var i = 0; i < header.num_st; i++) { 
    var s = reader.readInt16(); 
    var t = reader.readInt16(); 

    st[i] = { 
     s: s/header.skinwidth, 
     t: t/header.skinheight 
    }; 
} 

reader.seek(header.offset_tris); 
for (var i = 0; i < header.num_tris; i++) { 
    var a = reader.readInt16(); 
    var b = reader.readInt16(); 
    var c = reader.readInt16(); 

    var uva_i = reader.readUInt16(); 
    var uvb_i = reader.readUInt16(); 
    var uvc_i = reader.readUInt16(); 

    triag[i] = {}; 
    triag[i].vertex = []; 
    triag[i].st = []; 

    triag[i].vertex[0] = a; 
    triag[i].vertex[1] = b; 
    triag[i].vertex[2] = c; 

    triag[i].st[0] = uva_i; 
    triag[i].st[1] = uvb_i; 
    triag[i].st[2] = uvc_i; 
} 

// frames 
reader.seek(header.offset_frames); 
for (var f = 0; f < header.num_frames; f++) { 
    var frame = {}; 

    frame.name = ""; 
    frame.scale = {}; 
    frame.translate = {}; 

    frame.scale.x = reader.readFloat(); 
    frame.scale.y = reader.readFloat(); 
    frame.scale.z = reader.readFloat(); 

    frame.translate.x = reader.readFloat(); 
    frame.translate.y = reader.readFloat(); 
    frame.translate.z = reader.readFloat(); 

    frame.vertices = []; 

    frame.name = reader.readString(16).replace(/[^a-z0-9]/gi,''); // 4+4+4 4+4+4 (12 + 12) = 24 + 16 = 40 

    for (var v = 0; v < header.num_vertices; v++) { 
     var tempX = reader.readUInt8(); 
     var tempY = reader.readUInt8(); 
     var tempZ = reader.readUInt8(); 
     var normal = reader.readUInt8(); 

     var xx = frame.scale.x * tempX + frame.translate.x; 
     var yy = frame.scale.z * tempZ + frame.translate.z; 
     var zz = frame.scale.y * tempY + frame.translate.y; 

     let vertex = []; 

     vertex[0] = xx; 
     vertex[1] = yy; 
     vertex[2] = zz; 

     frame.vertices.push(vertex); 
    } 

    frames.push(frame); 
} 

let res = {}; 

res.st = st; 
res.triag = triag; 

res.frame = []; 
for (var i=0; i<frames.length; ++i) 
    res.frame[i]=frames[i]; 


res.faces_count = header.num_tris; 
res.vertices_count = header.num_vertices; 
res.frames_count = header.num_frames; 

return res; 

} 

main.js

let gl; 
let shaderProgram; 

let firstMouse = true; 
let mouseDown = false; 

let lastTime = 0; 
let deltaTime; 

let test; 

let lastX= 0; 
let lastY = 0; 


let DIRS = { 
    Forward: 0, 
    Backward: 1, 
    Left: 2, 
    Right: 3 
}; 

let KeyCodes = 
{ 
    Up: 38, 
    Down : 40, 
    Left : 37, 
    Right : 39, 

    W : 87, 
    S : 83, 
    A : 65, 
    D : 68, 

    Q : 81, 
    E : 69, 

    PageDown : 34, 
    PageUp : 33 
}; 

let pressedKeys = []; 


let vertexShaderSource = ` 
precision highp float; 

attribute vec3 aPos; 
attribute vec2 aTexCoord; 

uniform mat4 model; 
uniform mat4 view; 
uniform mat4 projection; 

varying vec2 vTexCoord; 


void main(void) 
{ 
    gl_Position = projection * view * model * vec4(aPos, 1.0); 
    vTexCoord = aTexCoord; 
} 
`; 

let fragmentShaderSource = ` 
precision highp float; 

varying highp vec2 vTexCoord; 
uniform sampler2D uSampler; 
void main(void) 
{ 
    gl_FragColor = texture2D(uSampler, vec2(vTexCoord.s,1.0-vTexCoord.t)); 
} 
`; 

let camera; 
function initGL() 
{ 
let canvas = document.getElementById("Canvas3D"); 
canvas.width = window.innerWidth; 
canvas.height = window.innerHeight; 
try 
{ 
    gl = canvas.getContext("webgl2") || canvas.getContext("experimental-webgl2"); 
} 
catch(e) 
{ 
    alert("Your browser don't support WebGL"); 
} 

gl.viewportWidth = canvas.width; 
gl.viewportHeight = canvas.height; 
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); 

gl.enable(gl.DEPTH_TEST); 
gl.depthFunc(gl.LESS); 

shaderProgram = new  ShaderProgram(gl,vertexShaderSource,fragmentShaderSource); 
shaderProgram.use(); 

camera = { 
    Init(shaderProgram) 
    { 
     this.shaderProgram = shaderProgram; 
     this.pos = vec3.create(); 
     this.up = vec3.create(); 
     this.front = vec3.create(); 
     this.right = vec3.create(); 

     this.WorldUp = vec3.create(); 

     this.pos = [51.656294013839215, 36.9293564686086, -28.23351748054847]; 
     this.front = [-0.7667674915573891, -0.6401096994849556, 0.04824092159224934]; 
     this.up = [-0.6388465891741784, 0.7682835235935235, 0.040192821190338686]; 

     this.WorldUp = [0,1,0]; 

     this.yaw = 176.39999999999998; 
     this.pitch = -39.8; 

     this.speed = 25; 
     this.sensivity = 0.1; 
     this.zoom = 100; 

     this.view = mat4.create(); 
     this.projection = mat4.create(); 
     mat4.perspective(this.projection, Math.PI/180.0*this.zoom,  gl.viewportWidth/gl.viewportHeight, 0.1, 200); 
      this.shaderProgram.gl.uniformMatrix4fv(this.shaderProgram.projection, false,  this.projection); 

     this.updateCameraVectors(); 
     this.updateView(); 

    }, 

    updateView: function() 
    { 
     let tmp = vec3.create(); 
     vec3.add(tmp, this.pos, this.front); 
     mat4.lookAt(this.view, this.pos, tmp, this.up); 
     this.shaderProgram.gl.uniformMatrix4fv(this.shaderProgram.view, false, this.view); 
    }, 

    processKeyboard(deltaTime) 
    { 
     let velocity = this.speed * deltaTime; 
     let tmp = vec3.create(); 

     if (pressedKeys[KeyCodes.W] || pressedKeys[KeyCodes.Up]) { 
      vec3.scale(tmp, this.front, velocity); 
      vec3.add(this.pos,this.pos,tmp); 
     } 
     if (pressedKeys[KeyCodes.S] || pressedKeys[KeyCodes.Down]) { 
      velocity *=(-1); 
      vec3.scale(tmp, this.front, velocity); 
      vec3.add(this.pos,this.pos,tmp); 
     } 
     if (pressedKeys[KeyCodes.A] || pressedKeys[KeyCodes.Left]) { 
      velocity *=(-1); 
      vec3.scale(tmp, this.right, velocity); 
      vec3.add(this.pos,this.pos,tmp); 
     } 
     if (pressedKeys[KeyCodes.D] || pressedKeys[KeyCodes.Right]) { 
      vec3.scale(tmp, this.right, velocity); 
      vec3.add(this.pos,this.pos,tmp); 
     } 
    }, 

    processMouseMovement(xoffset, yoffset) 
    { 
     this.yaw += (xoffset*this.sensivity); 
     this.pitch += (yoffset*this.sensivity); 

     if (this.pitch > 89.0) 
     this.pitch = 89.0; 
     if (this.pitch < -89.0) 
     this.pitch = -89.0; 

     this.updateCameraVectors(); 
    }, 

    updateCameraVectors() 
    { 
     let ToRads = Math.PI/180; 
     let yaw = this.yaw; 
     let pitch = this.pitch; 
     this.front[0] = Math.cos(ToRads*yaw) * Math.cos(ToRads*pitch); 
     this.front[1] = Math.sin(ToRads*pitch); 
     this.front[2] = Math.sin(ToRads*yaw) * Math.cos(ToRads*pitch); 
     vec3.normalize(this.front, this.front); 


     vec3.cross(this.right, this.front, this.WorldUp); 
     vec3.normalize(this.right, this.right); 

     vec3.cross(this.up, this.right, this.front); 
     vec3.normalize(this.up, this.up); 
    } 
}; 

function load_binary_resource(url) { 
    let req = new XMLHttpRequest(); 
    req.open('GET', url, false); 
    req.overrideMimeType('text/plain; charset=x-user-defined'); // No unicode data 
    req.send(null); 
    if (req.status != 200) return ''; 
    return req.responseText; 
} 

let file = load_binary_resource('../models/rhino/Tris.md2'); 
let res = MD2_converter(file); 

let texture = initTexture("../models/rhino/rhino.png"); 

let verts = []; 
let inds = []; 

let uvs = []; 

for (let i =0;i<res.frame[0].vertices.length;i++) 
{ 
    let vert = res.frame[0].vertices[i]; 
    verts.push(vert[0]); 
    verts.push(vert[1]); 
    verts.push(vert[2]); 
} 

for (let i =0;i<res.triag.length;i++) 
{ 
    let triag = res.triag[i]; 
    inds.push(triag.vertex[0]); 
    inds.push(triag.vertex[1]); 
    inds.push(triag.vertex[2]); 

    uvs.push(res.st[triag.st[0]].s); 
    uvs.push(res.st[triag.st[0]].t); 

    uvs.push(res.st[triag.st[1]].s); 
    uvs.push(res.st[triag.st[1]].t); 

    uvs.push(res.st[triag.st[2]].s); 
    uvs.push(res.st[triag.st[2]].t); 
} 

test = new Drawable(shaderProgram, verts, inds, uvs, texture); 

camera.Init(shaderProgram); 

requestAnimationFrame(gameCycle); 
} 

function recalculateFPS(gotTime) 
{ 
    deltaTime = (gotTime - lastTime)/1000; 
lastTime = gotTime; 
} 
function gameCycle(gotTime) 
{ 
    recalculateFPS(gotTime); 
    gl.clearColor(0,0,0,1); 
    gl.clear(gl.COLOR_BUFFER_BIT); 
    camera.processKeyboard(deltaTime); 
    camera.updateView(); 
    test.draw(); 


    requestAnimationFrame(gameCycle); 
} 

window.onload=function() 
{ 
    initGL(); 
}; 


document.onkeydown = function(e) 
{ 
    pressedKeys[e.keyCode]=true; 
}; 

document.onkeyup = function(e) 
{ 
    pressedKeys[e.keyCode]=false; 
}; 

document.body.onmousedown = function(event) 
{ 
    mouseDown = true; 
    lastX = event.clientX; 
    lastY = event.clientY; 
}; 

document.body.onmouseup = function(event) 
{ 
    mouseDown = false; 
}; 

document.body.onmouseout = function(event) 
{ 
    mouseDown = false; 
}; 

document.body.onmousemove = function (e) 
{ 
if (!mouseDown) 
    return; 
let xpos = e.clientX; 
let ypos = e.clientY; 
if(firstMouse) { 
    lastX = xpos; 
    lastY = ypos; 
    firstMouse = false; 
} 

    let xoffset = xpos - lastX; 
    let yoffset = lastY - ypos; 

lastX = xpos; 
lastY = ypos; 

camera.processMouseMovement(xoffset,yoffset); 


} 

main.html中

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Title</title> 
</head> 
<body scroll="no" style="overflow: hidden"> 
<canvas id="Canvas3D"></canvas> 
<script src="../js/glmatrix/dist/gl-matrix.js"></script> 

<script src="../js/MD2Import.js"></script> 
<script src="../js/ShaderProgram.js"></script> 
<script src="../js/Textures.js"></script> 
<script src="../js/Drawable.js"></script> 

<script src="../js/main.js"></script> 
</body> 
</html> 

Drawable.js

class Drawable { 
constructor(shaderProgram, vertices, indices, texCoords, texture) { 
    this.gl = shaderProgram.gl; 
    let gl = shaderProgram.gl; 
    this.shaderProgram = shaderProgram; 

    shaderProgram.aTexCoord = gl.getAttribLocation(shaderProgram.shaderProgram, "aTexCoord"); 
    shaderProgram.aPos = gl.getAttribLocation(shaderProgram.shaderProgram, "aPos"); 

    this.VAO = gl.createVertexArray(); 
    this.texture = texture; 
    gl.bindVertexArray(this.VAO); 

    this.vertexBuffer = gl.createBuffer(); 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 
    gl.vertexAttribPointer(shaderProgram.aPos, 3, gl.FLOAT, false, 12, 0); 
    gl.enableVertexAttribArray(shaderProgram.aPos); 

    this.EBO = gl.createBuffer(); 
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.EBO); 
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); 

    this.VBOTexCoords = gl.createBuffer(); 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.VBOTexCoords); 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords),gl.STATIC_DRAW); 
    gl.vertexAttribPointer(shaderProgram.aTexCoord, 2, gl.FLOAT, false, 8, 0); 
    gl.enableVertexAttribArray(shaderProgram.aTexCoord); 








    gl.bindVertexArray(null); 

    this.pos = vec3.create(); 
    this.rot = vec3.create(); // в Градусах 
    this.scale = vec3.create(); 

    this.pos = [0,0,0]; 
    this.rot = [0,0,0]; 
    this.scale=[1,1,1]; 

    this.vertCount = indices.length; 

    this.model = mat4.create(); 
} 

updateModel() { 
    mat4.identity(this.model); 
    mat4.translate(this.model, this.model, this.pos); 

    mat4.rotateX(this.model, this.model, Math.PI/180 * this.rot[0]); 
    mat4.rotateY(this.model, this.model, Math.PI/180 * this.rot[1]); 
    mat4.rotateZ(this.model, this.model, Math.PI/180 * this.rot[2]); 

    mat4.scale(this.model, this.model, this.scale); 

} 

translate(transX, transY, transZ) 
{ 
    this.pos[0] += transX; 
    this.pos[1] += transY; 
    this.pos[2] += transZ; 

} 

rotate(rotX, rotY, rotZ) 
{ 
    this.rot[0] += rotX; 
    this.rot[1] += rotY; 
    this.rot[2] += rotZ; 
} 

draw() { 
    this.updateModel(); 
    let gl =this.gl; 

    gl.uniformMatrix4fv(this.shaderProgram.model, false, this.model); 

    gl.bindVertexArray(this.VAO); 

    gl.activeTexture(gl.TEXTURE0); 
    gl.bindTexture(gl.TEXTURE_2D, this.texture); 
    gl.uniform1i(gl.getUniformLocation(shaderProgram.shaderProgram, "uSampler"), 0); 
    //gl.drawArrays(gl.TRIANGLES, 0, this.vertCount); 
    gl.drawElements(gl.TRIANGLES, this.vertCount,gl.UNSIGNED_SHORT,0); 
} 
} 

使用gl.pixelStorei(GL嘗試。UNPACK_FLIP_Y_WEBGL,真正的),結果是: Picture with flip

順便說一句,它不應該工作,因爲我已經翻轉紋理着色器:

gl_FragColor =的Texture2D(uSampler,VEC 2(vTexCoord.s,1.0 - vTexCoord.t));

rhino.png(紋理)textures

的MD2文件:http://dropmefiles.com/zhQFU

當我刪除索引緩衝區並置於頂點和UV的一個巨大的緩衝解決的問題。它可能是什麼?

+1

哪裏是整個webgl的東西?緩衝區設置,vao設置,繪製調用? – BDL

+0

嗨! 對不起,這個文件丟失了 – proggamer12

+0

現在這是在頁 – proggamer12

回答

0

解決方法是刪除索引緩衝區,並將所有內容放在頂點緩衝區中。它爲我工作