使用键盘方向键在Webgl中移动3d对象



我刚刚完成了一个创建旋转金字塔的作业,但我想更进一步,看看我如何使用键盘箭头键在画布中移动这个对象。我将在下面发布我的完整代码,主要代码开始于第143行,我有文档。addEventListener然后做一个开关(键)-我相信(在研究中)这应该工作,但我不明白的是为什么它不是动态更新-就像,每次我按左箭头键它应该向左移动。我使用gl.viewport (x,y,canvas)。宽度,画布。高度),并试图更新(x,y)片的视口,因为如果我手动输入x或y对象将移动,所以我认为这是我需要更新的项目的一部分,以移动对象,我相信…这是我的代码,任何提示将是伟大的。我的着色器在html文件中,但不认为这是需要的,但如果是这样,让我知道,我也可以发布。只是在寻找如何移动物体的技巧,这样我就可以应用这项技术了。提前谢谢。

"use strict";
var canvas;
var gl;
var numPositions  = 12;
var texSize = 1024;
var numChecks = 32;
var program;
var texture1, texture2, texture3, texture4;
var t1, t2;
var c;
var flag = true;
var image1 = new Image();
image1.src = "coolWater.jpg";
image1.crossOrigin = "anonymous";
var image2 = new Image();
image2.src = "coolWater.jpg";
image2.crossOrigin = "anonymous";
var image3 = new Image();
image3.src = "coolWater.jpg";
image3.crossOrigin = "anonymous";
var image4 = new Image();
image4.src = "coolWater.jpg";
image4.crossOrigin = "anonymous";
var positionsArray = [];
var colorsArray = [];
var texCoordsArray = [];
var texCoord = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];

var vertices = [
vec4(0.5, -0.2722,  0.2866, 1.0),
vec4(0.0, -0.2722,  -0.5773, 1.0),
vec4(-0.5, -0.2722,  0.2886, 1.0),
vec4(0.0, 0.5443,  0.0, 1.0)
];
//changing colors to white so you can just see the texture applied
var vertexColors = [
vec4(1.0, 1.0, 1.0, 1.0),
vec4(1.0, 1.0, 1.0, 1.0),
vec4(1.0, 1.0, 1.0, 1.0),
vec4(1.0, 1.0, 1.0, 1.0)
];
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;
var theta = vec3(45.0, 45.0, 45.0);
var thetaLoc;
function configureTexture() {
texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image1);
gl.generateMipmap(gl.TEXTURE_2D);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);


texture2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image2);
gl.generateMipmap(gl.TEXTURE_2D);
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
texture3 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture3);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image3);
gl.generateMipmap(gl.TEXTURE_2D);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);


texture4 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture4);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image4);
gl.generateMipmap(gl.TEXTURE_2D);
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

}
function tri(a, b, c) {
positionsArray.push(vertices[a]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[a]);
positionsArray.push(vertices[b]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[b]);
positionsArray.push(vertices[c]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[c]);
}
function colorPyramid()
{
tri(2, 1, 3);
tri(3, 1, 0);
tri(0, 1, 2);
tri(0, 2, 3);
}

window.onload = function init() {

canvas = document.getElementById("gl-canvas");
gl = canvas.getContext('webgl2');
if (!gl) alert("WebGL 2.0 isn't available");
//creating if / else statements for arrow keys pressed
var xPos = 0;
var yPos = 0;
document.addEventListener("keydown", function(e) {
e.preventDefault();
const key = e.key; // This will hold the arrow keys pressed
switch (key) {
case "ArrowLeft":
// Left Arrow pressed move object to the left
xPos += -25;
break;
case "ArrowRight":
// Right Arrow pressed move object to the right
xPos += 25;
break;
case "ArrowUp":
// Up Arrow pressed move object up
yPos += 25;
break;
case "ArrowDown":
// Down Arrow pressed move object down
yPos += -25;
break;
}
});
gl.viewport(xPos, yPos, canvas.width, canvas.height);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.enable(gl.DEPTH_TEST);
//
//  Load shaders and initialize attribute buffers
//
program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
colorPyramid();
var cBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
gl.bufferData(gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW);
var colorLoc = gl.getAttribLocation( program, "aColor");
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(colorLoc);
var vBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.bufferData(gl.ARRAY_BUFFER, flatten(positionsArray), gl.STATIC_DRAW);
var positionLoc = gl.getAttribLocation( program, "aPosition");
gl.vertexAttribPointer(positionLoc, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLoc );
var tBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, tBuffer);
gl.bufferData(gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW);
var texCoordLoc = gl.getAttribLocation(program, "aTexCoord");
gl.vertexAttribPointer(texCoordLoc, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(texCoordLoc);


configureTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.uniform1i(gl.getUniformLocation( program, "uTex0"), 0);
gl.activeTexture(gl.TEXTURE1 );
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.uniform1i(gl.getUniformLocation( program, "uTex1"), 1);
gl.activeTexture(gl.TEXTURE2 );
gl.bindTexture(gl.TEXTURE_2D, texture3);
gl.uniform1i(gl.getUniformLocation( program, "uTex1"), 2);
gl.activeTexture(gl.TEXTURE3 );
gl.bindTexture(gl.TEXTURE_2D, texture4);
gl.uniform1i(gl.getUniformLocation( program, "uTex1"), 3);
thetaLoc = gl.getUniformLocation(program, "uTheta");

document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};
document.getElementById("ButtonT").onclick = function(){flag = !flag;};
render();
}
var render = function() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if(flag) theta[axis] += 2.0;
gl.uniform3fv(thetaLoc, theta);
gl.drawArrays(gl.TRIANGLES, 0, numPositions);
requestAnimationFrame(render);
}

祝贺你渴望扩展你的知识,并"将其进一步发展"。我将尽力帮助回答你的问题。

从阅读你的问题来看,似乎你认为将(x, y)位置传递给gl.viewport会将你的金字塔移动到屏幕上的位置(x, y)。改变(x, y)值可能看起来会移动你的渲染形状,但实际上这是一个调整渲染视窗大小的巧合。这类似于调整浏览器窗口的大小,并使各种页面元素缩小以适应新的窗口大小。

在您的示例中,您向WebGL程序传递了一个角度以使金字塔旋转:

thetaLoc = gl.getUniformLocation(program, "uTheta");
...
if(flag) theta[axis] += 2.0;
gl.uniform3fv(thetaLoc, theta);

为了在屏幕上移动元素,您需要采用类似的方法创建uXuY统一变量,在按箭头键时更新它们并重新呈现。

xLoc = gl.getUniformLocation(program, "uX");
yLoc = gl.getUniformLocation(program, "uX");
...
gl.uniform1fv(xLoc, xPos);
gl.uniform1fv(xLoc, yPos);
Without seeing your complete code, including shaders, I won't be able to put together a working example.

相关内容

  • 没有找到相关文章

最新更新