2014-02-14 5 views
2

У меня есть простое приложение WebGL. имеет холст и пару простых шейдеров:WebGL drawArrays генерирует белый фон

код
<canvas id="render" width="320" height="240"> 
<div id="vertexShader" class="shader"> 
    attribute vec4 position; 
    void main() 
    { 
     gl_Position = position; 
    } 
</div> 
<div id="fragmentShader" class="shader"> 
    precision mediump float; 
    void main() 
    { 
     gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); 
    } 
</div> 

Приложение выглядит следующим образом:

function getContext() { 
    var canvas = document.getElementById("render"); 
    return canvas.getContext("webgl"); 
} 

function initContext(context) { 
    context.clearColor(0.0, 0.0, 0.0, 1.0); 
    context.clear(context.COLOR_BUFFER_BIT); 
} 

function getShader(shaderId, type, context) { 
    var shaderSource = document.getElementById(shaderId).innerHTML; 
    var shader = context.createShader(type); 
    context.shaderSource(shader, shaderSource); 
    context.compileShader(shader); 
    if (!context.getShaderParameter(shader, context.COMPILE_STATUS)) { 
     console.log(context.getShaderInfoLog(shader)); 
     return null; 
    } 
    return shader; 
} 

function initShaders(context) { 
    var program = context.createProgram(); 
    context.attachShader(program, getShader("vertexShader", context.VERTEX_SHADER, context)); 
    context.attachShader(program, getShader("fragmentShader", context.FRAGMENT_SHADER, context)); 
    context.linkProgram(program); 
    if (!context.getProgramParameter(program, context.LINK_STATUS)) { 
     console.log("Could not initialise shaders"); 
    } 
    return program; 
} 

function renderTile(context, program) { 
    var tileBuffer = context.createBuffer(); 
    var tile = [ 
     1.0, 1.0, 0, 1.0, 
     -1.0, 0, 0, 1.0, 
     1.0, -1.0, 0, 1.0 
    ]; 
    context.bindBuffer(context.ARRAY_BUFFER, tileBuffer); 
    context.bufferData(context.ARRAY_BUFFER, new Float32Array(tile), context.STATIC_DRAW); 
    positionLocation = context.getAttribLocation(program, "position"); 
    context.enableVertexAttribArray(positionLocation); 
    context.vertexAttribPointer(positionLocation, 4, context.FLOAT, false, 0, 0); 
    context.drawArrays(context.TRIANGLES, 0, 3); 
} 

var context = getContext(); 
initContext(context); 
var program = initShaders(context); 
context.useProgram(program); 
setTimeout(function() { 
    renderTile(context, program); 
}, 100); 

Это оказывает простой треугольник на холсте.

Проблема в том, что она иногда отображает треугольник на белом фоне, хотя прозрачный цвет установлен на непрозрачный черный цвет. (в последних версиях Google Chrome, Firefox в порядке) Во время отладки я обнаружил, что белый фон отображается при вызове метода drawArrays. Но я не могу понять, почему он не черный.

Для вашего удобства здесь jsFiddle.

ответ

3

В вашем примере вам просто нужно очистить свой цветовой буфер от каждого «кадра». Сначала ваш фон черный, затем он «перезаписывается» вашим треугольником (этим буфером вершин), как вы упомянули. На самом деле вы просто выполняете одну операцию в своей функции init при запуске.

function initContext(context) { 
    context.clearColor(0.0, 0.0, 0.0, 1.0); 
    context.clear(context.COLOR_BUFFER_BIT); 
} 

Просто добавьте context.clear(context.COLOR_BUFFER_BIT); в вашу функцию обновления, например:

setInterval(function() { 
    context.clear(context.COLOR_BUFFER_BIT); 
    renderTile(context, program); 
}, 100); 

Смотрите этот обновленный jsFiddle.

+1

Спасибо! Но почему это делает белый фон вокруг треугольника? Я думал, что только границы треугольника и его внутреннее пространство перерисовываются после вызова 'drawArrays' ... –

+0

@Just_Mad ваш фоновый фон по умолчанию белый, поэтому в первом кадре (на' initContext') вы устанавливаете свой холст в черный, то в вашем «Интервале» вы визуализируете треугольник, и вы меняете свой фрейм. После этого последнего изменения вы не устанавливаете новый «фон», поэтому он становится белым из-за настроек по умолчанию в вашем CSS. Измените этот id в вашем файле CSS на «background: black», и ваш холст останется черным. См. Это [jsFiddle] (http://jsfiddle.net/k8f7Q/7/). Но это только быстрое и грязное решение. – ztirom

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