在WebGL中绘制多个2D图像 [英] Drawing multiple 2D images in WebGL

查看:98
本文介绍了在WebGL中绘制多个2D图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注html5rocks上的一些教程,并且设法制作了一个JavaScript程序,该程序使用webGL在画布上显示一个图像。我已经在下面发布了我对此的代码。

I've been following a couple of tutorials on html5rocks, and I managed to make a javascript program which displays ONE image on a canvas using webGL. I have posted the code I have for this below.

问题是,似乎没有人向您展示如何在webGL中绘制多个对象。我以前从未直接与webGL合作过,所以对我来说不是很直观。

The problem is, it seems there is nobody out there who shows you how to draw more than ONE object in webGL. I've never worked directly with webGL before, so it's not very intuitive for me.

如何修改此代码以绘制 imageObjectArray ? (请注意,现在我只绘制 imageObjectArray [0]

How can I modify this code to draw each object in the imageObjectArray? (notice that now I'm just drawing imageObjectArray[0].

    function render(canvas, contextGL, imageObjectArray) { 
        vertexShader = createShaderFromScriptElement(contextGL, "2d-vertex-shader");
        fragmentShader = createShaderFromScriptElement(contextGL, "2d-fragment-shader");

        program = createProgram(contextGL, [vertexShader, fragmentShader]);
        contextGL.useProgram(program);

        var positionLocation = contextGL.getAttribLocation(program, "a_position");

        var texCoordLocation = contextGL.getAttribLocation(program, "a_texCoord");

        var texCoordBuffer = contextGL.createBuffer();
        contextGL.bindBuffer(contextGL.ARRAY_BUFFER, texCoordBuffer);

        contextGL.enableVertexAttribArray(texCoordLocation);
        contextGL.vertexAttribPointer(texCoordLocation, 2, contextGL.FLOAT, false, 0, 0);

        setRectangle(contextGL, 0.0, 0.0, 1.0, 1.0);

        var texture = contextGL.createTexture();
        contextGL.bindTexture(contextGL.TEXTURE_2D, texture);

        contextGL.texParameteri(contextGL.TEXTURE_2D, contextGL.TEXTURE_WRAP_S, contextGL.CLAMP_TO_EDGE);
        contextGL.texParameteri(contextGL.TEXTURE_2D, contextGL.TEXTURE_WRAP_T, contextGL.CLAMP_TO_EDGE);
        contextGL.texParameteri(contextGL.TEXTURE_2D, contextGL.TEXTURE_MIN_FILTER, contextGL.NEAREST);
        contextGL.texParameteri(contextGL.TEXTURE_2D, contextGL.TEXTURE_MAG_FILTER, contextGL.NEAREST);

        contextGL.texImage2D(contextGL.TEXTURE_2D, 0, contextGL.RGBA, contextGL.RGBA, contextGL.UNSIGNED_BYTE, imageObjectArray[0].displayObject.data);

        var resolutionLocation = contextGL.getUniformLocation(program, "u_resolution");
        contextGL.uniform2f(resolutionLocation, canvas.width, canvas.height);

        var buffer = contextGL.createBuffer();
        contextGL.bindBuffer(contextGL.ARRAY_BUFFER, buffer);
        contextGL.enableVertexAttribArray(positionLocation);
        contextGL.vertexAttribPointer(positionLocation, 2, contextGL.FLOAT, false, 0, 0);

        setRectangle(contextGL, imageObjectArray[0].x, imageObjectArray[0].y, imageObjectArray[0].width, imageObjectArray[0].height);

        // draw
        contextGL.drawArrays(contextGL.TRIANGLES, 0, 6);
    }

function setRectangle(gl, x, y, width, height) {
    var x2 = x + width;
    var y2 = y + height;
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
                                        [x, y,
                                         x2, y,
                                         x, y2,
                                         x, y2,
                                         x2, y,
                                         x2, y2
                                        ]), gl.STATIC_DRAW);
}

我的目的是开发一款(非常基本的)2D Sprite游戏。没有图书馆的舒适。 (也许glMatrix.js除外)

My aim here is to work on a (very basic) 2d sprite game. Without the comfort of libraries. (except for maybe glMatrix.js)

我的渲染函数出现错误,已修复。

My render function had an error in it, fixed.

推荐答案

以下代码执行以下操作:

The following code does the following:


  1. 编译顶点和片段着色器

  2. 将它们链接到着色器程序中

  3. 创建一个顶点缓冲区以保存纹理坐标并填充纹理坐标(texCoordBuffer)

  4. 创建纹理(createTexture)

  5. 配置如何采样纹理(texParameteri)

  1. Compiles the vertex and fragment shaders
  2. Links them together into a shader program
  3. Creates a vertex buffer to hold texture coordinates and fills it (texCoordBuffer)
  4. Creates a texture (createTexture)
  5. Configures how the texture is sampled (texParameteri)

以上5个步骤仅需运行一次。

The above 5 steps only need to be run once.

    vertexShader = createShaderFromScriptElement(contextGL, "2d-vertex-shader");
    fragmentShader = createShaderFromScriptElement(contextGL, "2d-fragment-shader");

    program = createProgram(contextGL, [vertexShader, fragmentShader]);
    contextGL.useProgram(program);

    var positionLocation = contextGL.getAttribLocation(program, "a_position");

    var texCoordLocation = contextGL.getAttribLocation(program, "a_texCoord");

    var texCoordBuffer = contextGL.createBuffer();
    contextGL.bindBuffer(contextGL.ARRAY_BUFFER, texCoordBuffer);

    contextGL.enableVertexAttribArray(texCoordLocation);
    contextGL.vertexAttribPointer(texCoordLocation, 2, contextGL.FLOAT, false, 0, 0);

    var texture = contextGL.createTexture();
    contextGL.bindTexture(contextGL.TEXTURE_2D, texture);

    contextGL.texParameteri(contextGL.TEXTURE_2D, contextGL.TEXTURE_WRAP_S, contextGL.CLAMP_TO_EDGE);
    contextGL.texParameteri(contextGL.TEXTURE_2D, contextGL.TEXTURE_WRAP_T, contextGL.CLAMP_TO_EDGE);
    contextGL.texParameteri(contextGL.TEXTURE_2D, contextGL.TEXTURE_MIN_FILTER, contextGL.NEAREST);
    contextGL.texParameteri(contextGL.TEXTURE_2D, contextGL.TEXTURE_MAG_FILTER, contextGL.NEAREST);

    setRectangle(contextGL, 0.0, 0.0, 1.0, 1.0);

其余代码必须针对要绘制的每个图像执行,并且执行以下操作:

The rest of the code must execute for each image you want to draw and it does the following:


  1. 将图像上传到纹理(texImage2D)

  2. 创建一个顶点缓冲区以保存位置并填充它(缓冲区)

  3. 调用drawArrays




    contextGL.texImage2D(contextGL.TEXTURE_2D, 0, contextGL.RGBA, contextGL.RGBA,contextGL.UNSIGNED_BYTE, imageObjectArray[0].displayObject.data);

    var resolutionLocation = contextGL.getUniformLocation(program, "u_resolution");
    contextGL.uniform2f(resolutionLocation, canvas.width, canvas.height);

    var buffer = contextGL.createBuffer();
    contextGL.bindBuffer(contextGL.ARRAY_BUFFER, buffer);
    contextGL.enableVertexAttribArray(positionLocation);
    contextGL.vertexAttribPointer(positionLocation, 2, contextGL.FLOAT, false, 0, 0);

    setRectangle(contextGL, imageObjectArray[0].x, imageObjectArray[0].y, imageObjectArray[0].width, imageObjectArray[0].height);

    // draw
    contextGL.drawArrays(contextGL.TRIANGLES, 0, 6);

您需要将步骤2拆分为单独的步骤。第一步,为位置创建顶点缓冲区,应该只执行一次。第二步,填充图像的位置,需要对要绘制的每个图像执行。

You need to split step 2 into separate steps. The first step, creating the vertex buffer for posistions, should only be executed once. The second step, filling the position of the image, needs to be executed for each image you want to draw.

我应该说我的建议不会给出最佳实现,但可以绘制多于1张图片。为了达到最佳效果,您应该考虑执行以下操作:

I should say that my suggestions will not give the optimal implementation but it will get you drawing more than 1 image. To be optimal you should consider doing:


  • 实施纹理地图集(将所有图像打包到单个纹理中)。

  • 仅上载一次纹理和位置坐标。

  • 使用更好的顶点和片段着色器来选择要绘制的图像(纹理坐标偏移),要绘制的图像(位置偏移)以及图像的大小(宽度和宽度)。高度缩放)

这篇关于在WebGL中绘制多个2D图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆