2013-10-08 51 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