2011-11-11 122 views
5

在视频游戏中,仅应用颜色来帮助加速加载过程。纹理准备就绪后,它们会替换当前的颜色。有没有办法在WebGL中做到这一点?到目前为止,我所见过的所有教程只展示了如何加载颜色或纹理(而不是一个接一个地加载)。用WebGL中的纹理替换颜色

我猜想每个形状的缓冲区在其纹理完全加载后需要改变。我会假设这是通过AJAX调用键入的,该纹理可用,然后通过某种JavaScript函数应用。没有复杂的图像加载过程,WebGL是否有内置的方法?

+0

好吧,几个月后,我看完自己的问题后,明白我在问什么。要完全回答我自己的问题,请阅读下文。 要在同一时间加载纹理和颜色,您需要两组x-fragment和x-vertex脚本。一个用于颜色,另一个用于纹理。由于它们是通过DOM拉入的,因此您只需在初始化对象时使用正确的着色器标识。可以是颜色或纹理。希望这可以帮助无能的WebGL像我一样发扬光大。 –

回答

5

在我所见过的大多数游戏中,您将描述它们的行为,通常以每顶点着色或非常低分辨率的纹理开始,并在可用时“融合”到完整纹理。这种平稳的过渡是棘手的,但如果你想要的只是从一个到另一个的快速“流行”,它应该不会太麻烦。

我会采取的基本路线是创建一个顶点缓冲区,同时具有纹理坐标和颜色信息,以及两个不同的着色器。一个着色器将使用颜色信息,另一个将忽略它并使用纹理。一旦纹理准备就绪,您就会发信号通知网格开始使用基于纹理的网格。

至于检测图像负载,这是不难的,你甚至不需要AJAX吧:

var image = new Image(); 
image.addEventListener("load", function() { 
    // Image is done loading, push to texture 
    gl.bindTexture(gl.TEXTURE_2D, texture); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); 
    // Set up any other state needed, such as switching the shader for the mesh 
}, true); 
image.src = src; 

我不知道我能多少帮助,在这个问题上没有给出发布非常大的代码块,但是如果你还在挣扎,我可以详细介绍一些其他部分。

+0

远比我预想的简单。当你说“两个不同的着色器”时,你是在谈论设置的初始着色器?如果是这样,我猜测绘图功能需要在某个点上切换纹理和纹理输出。 –

+0

我不完全确定“初始着色器”的含义。你在使用特定的教程或框架吗? – Toji

+0

实际上从零开始构建自己的WebGL引擎,遵循Mozilla WebGL教程中的许多想法和原则。通过初始着色器,我指的是在设置WebGL时(如果我没有记错的话),您可以使用它来抓取并存储着色器元素。 –

0

这实际上很简单,没有WebGL专门为此特别设计的任何功能,这是您可以从DOM API中免费获得的东西。当你加载图片时,无论如何你必须实现他们的'onload'回调,因为图片加载是异步的。因此,只需在'onload'回调中加入任何代码即可从纯色切换到纹理。

1

我会采取的方法是如下

loadTexture(url, initialColor) { 

    var tex = gl.createTexture(); 

    // start with a single color. 
    gl.bindTexture(gl.TEXTURE_2D, tex); 
    var pixel = new Uint8Array(initialColor); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, pixel); 

    // start loading the image 
    var img = new Image(); 
    img.src = url; 
    img.onLoad = function() { 

    // when the image has loaded update the texture.   
    gl.bindTexture(gl.TEXTURE_2D, tex); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); 
    gl.generateMipmap(gl.TEXTURE_2D); 
    } 
    return tex; 
} 

// Load a tree texture, use brown until the texture loads. 
var treeTexture = loadTexture("tree.png", [255, 200, 0, 255]); 
// Load a water texture, use blue until it loads. 
var waterTexture = loadTexture("water.jpg", [0, 0, 255, 255]); 

这是怎么上http://webglsamples.googlecode.com工作大部分样品,虽然他们都默认为蓝色纹理。

您可以轻松地将该想法扩展为使用纯色,加载低分辨率纹理,然后在完成时加载高分辨率纹理。

注意:上面的代码假定您正在加载2次幂的纹理。如果没有,你需要正确设置你的纹理参数。