【发布时间】:2017-03-25 10:11:02
【问题描述】:
我第一次尝试在 WebGL 中使用纹理,但在让它工作时遇到了问题。我正在尝试将类似石头的纹理应用于在 3D 空间中移动的立方体,如下面的rocks.js 所示。我总是收到这个我不知道该怎么做的错误(我正在使用 Chrome btw):
渲染警告:没有纹理绑定到单元 0
这是我的 index.html 文件:
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
attribute vec2 vTexCoord;
varying vec2 fTexCoord;
varying vec4 fColor;
uniform mat4 projection;
uniform mat4 modelview;
void main()
{
fTexCoord = vTexCoord;
fColor = vColor;
gl_Position = projection * modelview * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
varying vec2 fTexCoord;
uniform sampler2D texture;
void
main()
{
gl_FragColor = texture2D( texture, fTexCoord );
//gl_FragColor = fColor;
}
</script>
<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>
<script type="text/javascript" src="main.js"></script>
<script type="text/javascript" src="grid.js"></script>
<script type="text/javascript" src="spaceship.js"></script>
<script type="text/javascript" src="rocks.js"></script>
<body>
<canvas id="gl-canvas" width="1100" height="1200" style="float:left;">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</div>
</body>
</html>
这是我的rocks.js,其中定义了我尝试应用纹理的对象:
// global webgl variables
var gl;
var vBuffer;
var cBuffer;
var iBuffer;
var tBuffer;
var mvLoc;
var rocks = (function() {
var direction = vec3();
var lastDirection = vec3();
var location = vec3();
var lastLocation = vec3();
var rock = {
NumVertices : 36,
indices :[
1, 0, 3,
3, 2, 1,
2, 3, 7,
7, 6, 2,
3, 0, 4,
4, 7, 3,
6, 5, 1,
1, 2, 6,
4, 5, 6,
6, 7, 4,
5, 4, 0,
0, 1, 1
],
vertices : [
vec4( -0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 )
],
texVertices : [
vec2(-0.5, -0.5),
vec2(-0.5, 0.5 ),
vec2( 0.5, 0.5 ),
vec2( 0.5, -0.5 ),
vec2( -0.5, -0.5 ),
vec2( -0.5, 0.5 ),
vec2( 0.5, 0.5 ),
vec2( 0.5, -0.5 )
],
render : function(mv) {
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(this.vertices));
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuffer);
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint8Array(this.indices))
gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer);
gl.bufferSubData( gl.ARRAY_BUFFER, 0, flatten(this.texVertices) );
mv = mult( mv, scalem(0.2, 0.2, 0.2) );
mv = mult( mv, translate(0.0, 0.0, 0.0) );
gl.uniformMatrix4fv(mvLoc, false, flatten(mv));
gl.drawElements( gl.TRIANGLES, this.NumVertices, gl.UNSIGNED_BYTE, 0 );
}
}
var init = function(glIn, vBufferIn, iBufferIn, tBufferIn, mvLocIn) {
// set global webgl variagles
gl = gl;
vBuffer = vBufferIn;
iBuffer = iBufferIn;
mvLoc = mvLocIn;
tBuffer = tBufferIn;
direction = [(Math.random()*0.06-0.03)/2, (Math.random()*0.06-0.03)/2, (Math.random()*0.06-0.03)/2];
location = [Math.random()*6-3, Math.random()*6-3, Math.random()*6-3];
lastDirection = direction;
lastLocation = location;
}
var render = function(spinX, spinY, mv) {
mv = mult( mv, rotateX(spinX) );
mv = mult( mv, rotateY(spinY) );
mv = mult( mv, translate(location) );
rock.render(mv);
}
var updateRock = function() {
// direction = updatedDir;
location = add( location, direction );
if(location[0] > 3 || location[0] < -3) location[0] = -location[0];
if(location[1] > 3 || location[1] < -3) location[1] = -location[1];
if(location[2] > 3 || location[2] < -3) location[2] = -location[2];
lastDirection = direction;
lastLocation = location;
}
return {
init : init,
render : render,
update : updateRock
};
});
最后,我的 main.js 用于运行everyting:
// webgl global variables
var gl;
var canvas;
var texture;
var texCoords = [];
var movement = false;
var spinX = 0;
var spinY = 0;
var origX;
var origY;
var xRot = 0;
var yRot = 0;
var grid;
var spaceship;
var rocksArray = [];
function configureTexture( image ) {
texture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image );
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR );
}
window.onload = function init()
{
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 0.0, 0.0, 0.0, 0.0 );
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
var iBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 36, gl.DYNAMIC_DRAW);
var cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, 128, gl.DYNAMIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, 1024, gl.DYNAMIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
var tBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer);
gl.bufferData( gl.ARRAY_BUFFER, 128, gl.STATIC_DRAW );
var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vTexCoord );
var image = new Image();
image.src = "rock.jpg"
image.onload = function() {
configureTexture( image );
}
var proLoc = gl.getUniformLocation( program, "projection" );
mvLoc = gl.getUniformLocation( program, "modelview" );
gl.uniform1i(gl.getUniformLocation(program, "texture"), 0);
var pers = perspective( 100.0, 1.0, 0.2, 100.0 );
gl.uniformMatrix4fv(proLoc, false, flatten(pers));
grid = new grid();
grid.init(gl, vBuffer, cBuffer, iBuffer, mvLoc);
spaceship = new spaceship();
spaceship.init(gl, vBuffer, cBuffer, iBuffer, mvLoc);
for (var i = 0; i < 100; i++) {
rocksArray[i] = new rocks();
rocksArray[i].init(gl, vBuffer, iBuffer, tBuffer, mvLoc);
}
attachEventHandlers();
render();
}
function reloadPage() {
location.reload();
}
function attachEventHandlers() {
canvas.addEventListener("mousedown", function(e){
movement = true;
origX = e.offsetX;
origY = e.offsetY;
// Disable drag and drop
e.preventDefault();
});
canvas.addEventListener("mouseup", function(e){
movement = false;
});
canvas.addEventListener("mousemove", function(e){
if(movement) {
spinY += (e.offsetX - origX) % 360;
spinX += (e.offsetY - origY) % 360;
origX = e.offsetX;
origY = e.offsetY;
}
});
window.addEventListener("keydown", function(e) {
spaceship.keyArray[e.keyCode] = true;
});
window.addEventListener("keyup", function(e) {
spaceship.keyArray[e.keyCode] = false;
});
}
function render() {
spaceship.moveSpaceship();
rocksArray.forEach(function(rock) {
rock.update();
});
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mv = lookAt( vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 1.0, 0.0) );
mv = mult(mv, rotateX(90));
// spaceship.render(spinX, spinY, mv);
mv = mult( mv, translate(-xVal, -yVal, -zVal));
mv = mult(mv, rotateZ(-zSpin));
mv = mult(mv, rotateX(-xSpin));
grid.render(spinX, spinY, mv);
rocksArray.forEach(function(rock) {
rock.render(spinX, spinY, mv);
});
requestAnimFrame( render );
}
【问题讨论】:
标签: javascript textures webgl