2013-01-05 126 views
1

截至目前,我的代碼支持加載.obj(波前)文件並將其轉換爲WebGL對象(GL緩衝區和渲染函數)。但是,我現在只能將一個紋理映射到整個對象。在WebGL中,如何加載使用多個紋理的3D模型(波前)?

我的文件加載程序逐行讀取,並且當前忽略.obj文件的usemtl行。我的對象渲染功能看起來像這樣(改編自http://learningwebgl.com/blog/?page_id=1217教程) - 但並不完美,但爲了完整起見,我張貼的整個工作職能:

this.render = function(gl){ 
    // push identity to the matrix stack (to apply changes only to this object) 
    mvPushMatrix(); 

    // apply translations 
    mat4.translate(mvMatrix, [this.transX, this.transY, this.transZ]); 

    // apply scaling 
    mat4.scale(mvMatrix, [this.scaleX, this.scaleY, this.scaleZ]); 

    // apply rotations 
    mat4.rotate(mvMatrix, this.rotX, [1, 0, 0]); 
    mat4.rotate(mvMatrix, this.rotY, [0, 1, 0]); 
    mat4.rotate(mvMatrix, this.rotZ, [0, 0, 1]); 

    // load position buffer 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.positionVertexBuffer); 
    gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 
     this.positionVertexBuffer.itemSize, gl.FLOAT, false, 0, 0); 

    // load normals buffer 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.normalVertexBuffer); 
    gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, 
     this.normalVertexBuffer.itemSize, gl.FLOAT, false, 0, 0); 

    // load texture buffer 
    gl.bindBuffer(gl.ARRAY_BUFFER, this.textureVertexBuffer); 
    gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 
     this.textureVertexBuffer.itemSize, gl.FLOAT, false, 0, 0); 

    // load and apply the texture 
    gl.activeTexture(gl.TEXTURE0); 
    gl.bindTexture(gl.TEXTURE_2D, this.texture); 
    gl.uniform1i(shaderProgram.samplerUniform, 0); 

    // if blending is turned on, apply the blending and alpha value 
    if(this.blending || this.firstRun){ 
     gl.blendFunc(gl.SRC_ALPHA, gl.ONE); 
     gl.enable(gl.BLEND); 
     gl.disable(gl.DEPTH_TEST); 
     gl.uniform1f(shaderProgram.alphaUniform, this.alpha); 
    } 
    // otherwise, disable blending mode and render normally 
    else{ 
     gl.disable(gl.BLEND); 
     gl.enable(gl.DEPTH_TEST); 
     gl.uniform1f(shaderProgram.alphaUniform, 1.0); 
    } 

    // render with indices IF indices are enabled 
    if(this.indicesEnabled){ 
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexVertexBuffer); 
     setMatrixUniforms(); 
     gl.drawElements(gl.TRIANGLES, 
      this.indexVertexBuffer.numItems, gl.UNSIGNED_SHORT, 0); 
    } 
    // otherwise, render normally 
    else { 
     setMatrixUniforms(); 
     gl.drawArrays(gl.TRIANGLES, 0, this.textureVertexBuffer.numItems); 
    } 

    // pop the matrix stack 
    mvPopMatrix(); 

    // unflag first run after first frame rendering 
    this.firstRun = false; 
} 

我想什麼做的文件中被讀取使用多個紋理。我怎樣才能做到這一點?我最初的假設是從.obj讀取一個紋理的所有面,一旦紋理髮生變化,就開始讀取一個單獨的緩衝區,然後將該對象分成多塊(每個紋理一塊),並將它們呈現爲如果他們是獨立的對象。但在我更改代碼之前,我想知道這是否正確,或者是否有解決此問題的特別好方法?

說實話,我不知道如何去做這件事。有什麼建議麼?謝謝。

回答

2

是的,這幾乎是它完成的方式。

通常對於專業遊戲,藝術家需要爲每個物體使用1個紋理,因爲對於兩個100多邊形模型,2次調用gl.drawXXX比1次調用200個多邊形模型的gl.drawXXX要慢。

否則,某些團隊會擁有讀取文件並將所有內容轉換爲1紋理的工具,將紋理合併爲一個超級紋理。其他團隊擁有將多邊形按紋理分類爲1個模型的工具。

有效地爲每個多邊形他們找出它屬於哪個紋理,然後他們將這些頂點放入該紋理的存儲桶中。最後他們寫出每個桶,每個紋理1個。

+0

謝謝!我最終通過堅持使用一個紋理緩衝區來實現它,但是使用渲染函數的偏移量索引和該緩衝區段的長度。同樣的概念,但由於某些原因,它不會與多個緩衝區一起工作,但此解決方案完美工作。 – Sefu

相關問題