diff --git "a/\\" "b/\\" new file mode 100644 index 0000000..d03060c --- /dev/null +++ "b/\\" @@ -0,0 +1,166 @@ +import { client } from "../index.js"; +import { Game } from "../api/game/Game.js"; +import AbstractView from "./abstracts/AbstractView.js"; +import { initShaderProgram, shaderInfos } from "../3D/shaders.js" +import { initBuffers } from "../3D/buffers.js" +import "../3D/maths/gl-matrix-min.js" +import { renderCube } from "../3D/cube.js" + +export default class extends AbstractView +{ + constructor(params) + { + super(params, "Game"); + this.game = new Game(client, params.id); + this.keys_pressed = []; + this.my_player = undefined; + this.gl = null; + this.shader_prog = null; + this.buffers = null; + this.cam_pos = [0, 1000, 0]; + this.cam_target = [0, 0, 0]; + } + + initGL() + { + const canvas = document.getElementById('glcanva'); + this.gl = canvas.getContext("webgl"); + + if(this.gl === null) + { + alert("Unable to initialize WebGL. Your browser or machine may not support it. You may also be a bozo"); + return; + } + + this.shader_prog = initShaderProgram(this.gl); + this.buffers = initBuffers(this.gl); + + this.gl.enable(this.gl.CULL_FACE); + this.gl.cullFace(this.gl.BACK); + } + + async join_game() + { + await this.game.join() + + let canvas = document.createElement("canvas"); + + canvas.height = this.game.config.size_x; + canvas.width = this.game.config.size_y; + canvas.id = "glcanva"; + + document.getElementById("app").appendChild(canvas); + + this.initGL(); + + this.render_game(); + } + + draw() + { + const canvas = document.getElementById('glcanva'); + if(canvas === null) + return 1; + + this.gl.clearColor(0.1, 0.1, 0.1, 1.0); + this.gl.clearDepth(1.0); + this.gl.enable(this.gl.DEPTH_TEST); + this.gl.depthFunc(this.gl.LEQUAL); + this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); + + const projectionMatrix = mat4.create(); + const viewMatrix = mat4.create(); + + mat4.perspective(projectionMatrix, (90 * Math.PI) / 180, this.gl.canvas.clientWidth / this.gl.canvas.clientHeight, 0.1, 10000000.0); + mat4.lookAt(viewMatrix, this.cam_pos, this.cam_target, [0, 1, 0]); + + this.setPositionAttribute(); + this.setNormalAttribute(); + + this.gl.useProgram(shaderInfos.program); + + this.gl.uniformMatrix4fv(shaderInfos.uniformLocations.projectionMatrix, false, projectionMatrix); + this.gl.uniformMatrix4fv(shaderInfos.uniformLocations.viewMatrix, false, viewMatrix); + + this.game.render(this.gl); + } + + setNormalAttribute() + { + const numComponents = 3; + const type = this.gl.FLOAT; + const normalize = false; + const stride = 0; + const offset = 0; + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.normal); + this.gl.vertexAttribPointer( + shaderInfos.attribLocations.vertexNormal, + numComponents, + type, + normalize, + stride, + offset, + ); + this.gl.enableVertexAttribArray(shaderInfos.attribLocations.vertexNormal); + } + + setPositionAttribute() + { + const numComponents = 3; + const type = this.gl.FLOAT; + const normalize = false; + const stride = 0; + const offset = 0; + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.vertex); + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.buffers.index); + this.gl.vertexAttribPointer( + shaderInfos.attribLocations.vertexPosition, + numComponents, + type, + normalize, + stride, + offset + ); + this.gl.enableVertexAttribArray(shaderInfos.attribLocations.vertexPosition); + } + + render_game() + { + let loop_id = setInterval(() => { + if (this.game === undefined) + clearInterval(loop_id); + if (this.my_player) + this.my_player.update_paddle(this.keys_pressed); + this.draw(); + this.game?.time.new_frame(); + }, 1000 / 60); + } + + async update_game_state() + { + document.getElementById("game-state").innerText = this.game.state; + + if (this.game.finished === false) + await this.join_game(); + } + + async postInit() + { + let error_code = await this.game.init(); + + if (error_code) + return error_code; + + await this.update_game_state(); + } + + async getHtml() + { + return /* HTML */ ` + +
+ + `; + } +} + diff --git a/frontend/static/js/3D/cube.js b/frontend/static/js/3D/cube.js index 3544d4f..8fc59fa 100644 --- a/frontend/static/js/3D/cube.js +++ b/frontend/static/js/3D/cube.js @@ -27,16 +27,8 @@ function renderCube(ctx, x, y, z, angle = 0, sx = 1, sy = 1, sz = 1) mat4.invert(normalMatrix, modelMatrix); mat4.transpose(normalMatrix, normalMatrix); - ctx.uniformMatrix4fv( - shaderInfos.uniformLocations.modelMatrix, - false, - modelMatrix - ); - ctx.uniformMatrix4fv( - shaderInfos.uniformLocations.normalMatrix, - false, - normalMatrix, - ); + ctx.uniformMatrix4fv(shaderInfos.uniformLocations.modelMatrix, false, modelMatrix); + ctx.uniformMatrix4fv(shaderInfos.uniformLocations.normalMatrix, false, normalMatrix); ctx.drawElements(ctx.TRIANGLES, 36, ctx.UNSIGNED_SHORT, 0); } diff --git a/frontend/static/js/api/game/Ball.js b/frontend/static/js/api/game/Ball.js index 6a0603e..6c0d4d7 100644 --- a/frontend/static/js/api/game/Ball.js +++ b/frontend/static/js/api/game/Ball.js @@ -1,6 +1,6 @@ import { Game } from "./Game.js"; import { Point } from "./Point.js"; - +import { renderCube } from "../../3D/cube.js" class Ball { @@ -46,7 +46,19 @@ class Ball */ draw(ctx) { - ctx.rect(this.position.x - this.size / 2, this.position.y - this.size / 2, this.size, this.size); + if(ctx instanceof CanvasRenderingContext2D) + { + ctx.rect(this.position.x - this.size / 2, this.position.y - this.size / 2, this.size, this.size); + } + else if(ctx instanceof WebGLRenderingContext) + { + console.log((this.position.x - this.size / 2) / 10, 0, (this.position.y - this.size / 2) / 10) + renderCube(ctx, (this.position.x - this.size / 2) / 10, 0, (this.position.y - this.size / 2) / 10, 0, this.size * 10, this.size * 10, this.size * 10); + } + else + { + alert('Unknown rendering context type'); + } } /** diff --git a/frontend/static/js/api/game/Player.js b/frontend/static/js/api/game/Player.js index 1802d48..b6b96b3 100644 --- a/frontend/static/js/api/game/Player.js +++ b/frontend/static/js/api/game/Player.js @@ -1,6 +1,7 @@ import { Game } from "./Game.js"; import { Point } from "./Point.js"; import { Segment } from "./Segment.js"; +import { renderCube } from "../../3D/cube.js" class Player { @@ -61,8 +62,11 @@ class Player { if (this.is_connected === false) { - ctx.moveTo(this.rail.start.x, this.rail.start.y); - ctx.lineTo(this.rail.stop.x, this.rail.stop.y); + if(ctx instanceof CanvasRenderingContext2D) + { + ctx.moveTo(this.rail.start.x, this.rail.start.y); + ctx.lineTo(this.rail.stop.x, this.rail.stop.y); + } return; } diff --git a/frontend/static/js/views/GameView3D.js b/frontend/static/js/views/GameView3D.js index 4585d5e..cfdbb8e 100644 --- a/frontend/static/js/views/GameView3D.js +++ b/frontend/static/js/views/GameView3D.js @@ -17,8 +17,8 @@ export default class extends AbstractView this.gl = null; this.shader_prog = null; this.buffers = null; - this.cam_pos = [0, 100, 0]; - this.cam_target = [4, 0, 4]; + this.cam_pos = [0, 500, 0]; + this.cam_target = [0, 0, 35]; } initGL() @@ -71,7 +71,7 @@ export default class extends AbstractView const projectionMatrix = mat4.create(); const viewMatrix = mat4.create(); - mat4.perspective(projectionMatrix, (90 * Math.PI) / 180, this.gl.canvas.clientWidth / this.gl.canvas.clientHeight, 0.1, 1000.0); + mat4.perspective(projectionMatrix, (90 * Math.PI) / 180, this.gl.canvas.clientWidth / this.gl.canvas.clientHeight, 0.1, 10000000.0); mat4.lookAt(viewMatrix, this.cam_pos, this.cam_target, [0, 1, 0]); this.setPositionAttribute(); @@ -82,7 +82,7 @@ export default class extends AbstractView this.gl.uniformMatrix4fv(shaderInfos.uniformLocations.projectionMatrix, false, projectionMatrix); this.gl.uniformMatrix4fv(shaderInfos.uniformLocations.viewMatrix, false, viewMatrix); - this.game.draw(this.gl); + this.game.render(this.gl); } setNormalAttribute()