2013-10-08 72 views
1

我寫道,試圖在一個WebGL的3D場景僅繪製背景圖像的代碼。下面是代碼的相關部分:添加背景圖像WebGL的3D場景

<script id="shader-fs" type="x-shader/x-fragment"> 
varying highp vec2 vTexCoord; 

uniform sampler2D uSampler; 

void main(void) { 
    gl_FragColor = texture2D(uSampler, vec2(vTexCoord.s, vTexCoord.t)); 
} 
</script> 

<script id="shader-vs" type="x-shader/x-vertex"> 
attribute vec3 aVertexPosition; 
attribute vec2 aTextureCoord; 

uniform mat4 uMVMatrix; 
uniform mat4 uPMatrix; 

varying highp vec2 vTexCoord; 

void main(void) { 
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); 
    vTexCoord = aTextureCoord; 
} 
</script> 

<script> 
var VBack = [ 
    -24.0, 0.0, 0.0, 
    24.0, 0.0, 0.0, 
    24.0, 48.0, 0.0, 
    -24.0, 48.0, 0.0 
    ]; 

var vTBack = [ 
    0.0, 0.0, 
    1.0, 0.0, 
    1.0, 1.0, 
    0.0, 1.0 
    ]; 

var VBuffer; 
var vTBuffer; 

function initMatrix() { 
    orthoMatrix = makeOrtho(-24.0, 24.0, 0.0, 48.0, 20.0, -20.0); // From glUtils.js 
    mvMatrix = Matrix.I(4); 
    ... 
} 

function handleBkTex(tex) { 
    GL.bindTexture(GL.TEXTURE_2D, tex); 
    GL.pixelStorei(GL.UNPACK_FLIP_Y_WEBGL, true); 
    GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, tex.Img); 
    GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST); 
    GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST); 
    GL.bindTexture(GL.TEXTURE_2D, null); 
} 

function initBkgnd() { 
    backTex = GL.createTexture(); 
    backTex.Img = new Image(); 
    backTex.Img.onload = function() { 
     handleBkTex(backTex); 
    } 
    backTex.Img.src = "Bkgnd.jpg"; 
} 

function drawBkgnd() { 
    GL.bindBuffer(GL.ARRAY_BUFFER, VBuffer); 
    GL.vertexAttribPointer(vertexPositionAttribute, 3, GL.FLOAT, false, 0, 0); 

    GL.bindBuffer(GL.ARRAY_BUFFER, vTBuffer); 
    GL.vertexAttribPointer(texCoordAttribute, 2, GL.FLOAT, false, 0, 0); 

    GL.activeTexture(GL.TEXTURE0); 
    GL.bindTexture(GL.TEXTURE_2D, backTex); 
    GL.uniform1i(GL.getUniformLocation(shaderProgram, "uSampler"), 0); 

    GL.drawArrays(GL.TRIANGLE_STRIP, 0, 4); 
} 


function start() { 
    var canvas = document.getElementById("glcanvas"); 
    initWebGL(canvas); 

    if (GL) { 
     initShaders(); 
     initBuffers(); 
     initMatrix(); 
     initBkgnd(); 
     drawBkgnd(); 
    } 
} 

畫布大小是512 x 512,相同的圖像尺寸。但我不明白在畫布上正確的圖像。如何正確執行此操作?

回答

1

我在代碼中發現了一些小錯誤。這裏是他們:

  • WebGL的場景必須總是被重繪。所以功能drawBkgnd()必須重複調用,使用setInterval()requestAnimationFrame()
  • 要使用drawArrays()GL_TRIANGLE_STRIP正確繪製一個矩形,頂點的順序必須是:

    *2  *3 
    
    
    *0  *1 
    

    或任何同等的命令,而不是:

    *3  *2 
    
    
    *0  *1 
    

    這樣的順序在VBack頂點必須改成:

    var VBack = [ 
        -24.0, 0.0, 0.0, 
        24.0, 0.0, 0.0, 
        -24.0, 48.0, 0.0 
        24.0, 48.0, 0.0, 
    ]; 
    

    並且vTBack中的頂點順序也必須相應地改變。

2

你想要的答案是如何建立一個三維矩陣來繪製2D圖像,或你想要的答案是如何有效地做到這一點?

這裏的有效答案。沒有理由使用3D繪製2D。你到vertexAttribPointer呼叫改變你的頂點

var VBack = [ 
    -1, -1, 
    1, -1, 
    1, 1, 
    -1, 1, 
]; 

更改爲

GL.vertexAttribPointer(vertexPositionAttribute, 2, GL.FLOAT, false, 0, 0); 

你的頂點着色器更改爲

attribute vec4 aVertexPosition; 
attribute vec2 aTextureCoord; 

varying highp vec2 vTexCoord; 

void main(void) { 
    gl_Position = aVertexPosition; 
    vTexCoord = aTextureCoord; 
} 

,它應該工作。

查看this set of articles for more about 2D in WebGL瞭解更多信息。

+0

謝謝。但是,正如我在標題中所寫的,我想在3D場景中設置背景圖像(2D)。無論如何,我已經找到了答案。 – ArthurN

+0

「在3D場景中」是什麼意思?如果你想用背景填充背景,那麼場景就是3D。嘿,你也可以通過設置畫布的背景圖像來實現它,如然後清除畫布到0,0,0,0,儘管我建議的方法仍然是更高效。 – gman