我编写了一个试图在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
,与图像大小相同。但我没有在画布上得到正确的图像。如何正确地做到这一点?
答案 0 :(得分: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;
}
它应该有用。
答案 1 :(得分:1)
我在代码中发现了一些小错误。他们是:
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
中的顶点顺序也必须相应更改。