2013-10-08 3 views
1

Я написал код, который пытался нарисовать только фоновое изображение в 3D-сцене WebGL. Вот соответствующие части коды:Добавление фонового изображения в сцену 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

Вы хотите, чтобы ответить на вопрос, как настроить 3D-матрицу для рисования 2D-изображения или вы хотите, чтобы ответ был таким, как это сделать эффективно?

Вот эффективный ответ. Нет смысла использовать 3D для рисования 2D. Меняйте вершины в

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

Изменить свой призыв к vertexAttribPointer к

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

Спасибо. Однако, как я писал в названии, я хочу создать фоновое изображение (2D) в 3D-сцене. Я все равно нашел ответ. – ArthurN

+0

Что означает «в 3D-сцене»? Если вы хотите заполнить фон изображением, это не имеет значения, если сцена 3D. Черт, вы также можете сделать это, просто установив фоновое изображение холста, как в затем очистите холст до 0,0,0,0, хотя мой предложенный метод все еще более эффективным. – gman

Смежные вопросы