diff --git a/assets/shaders/noise.frag b/assets/shaders/noise.frag new file mode 100644 index 0000000..4bdb0ae --- /dev/null +++ b/assets/shaders/noise.frag @@ -0,0 +1,30 @@ +#ifdef GL_ES +precision mediump float; +#endif + +#define FBM_OCTAVES 6 + +#include "lygia/generative/fbm.glsl" + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + +void main(){ + vec2 st=gl_FragCoord.xy/min(u_resolution.x,u_resolution.x)*2.; + + vec2 q=vec2(0.); + q.x=fbm(st); + q.y=fbm(st+vec2(1.)); + + q=q*.5+.5; + vec2 r=vec2(0.); + r.x=fbm(st+1.*q+vec2(1.7,9.2)+.0115*u_time); + r.y=fbm(st+1.*q+vec2(8.3,2.8)+.0226*u_time); + r=r*.5+.5; + + float f=fbm(st+r); + + f=mix(.5,1.,f); + gl_FragColor=vec4(0.,.1+f,0.,1.); +} \ No newline at end of file diff --git a/components/AnimatedBackground.vue b/components/AnimatedBackground.vue new file mode 100644 index 0000000..344a9df --- /dev/null +++ b/components/AnimatedBackground.vue @@ -0,0 +1,114 @@ + + + + + \ No newline at end of file diff --git a/components/GameBoard.vue b/components/GameBoard.vue index f437aee..5a02d01 100644 --- a/components/GameBoard.vue +++ b/components/GameBoard.vue @@ -70,10 +70,7 @@ function showWinnerScreen() { - @@ -98,7 +95,7 @@ function showWinnerScreen() { } #current_player.self { - background-image: url('../images/bg-grass.png'); + background-image: url('/images/bg-grass.png'); } #market { diff --git a/components/PlayerListElement.vue b/components/PlayerListElement.vue index b2aaa8c..726d3c9 100644 --- a/components/PlayerListElement.vue +++ b/components/PlayerListElement.vue @@ -122,7 +122,7 @@ const props = defineProps() } .player_list_element.self { - background-image: url('../images/bg-grass.png'); + background-image: url('/images/bg-grass.png'); } .view { diff --git a/components/ResultDialog.vue b/components/ResultDialog.vue index 67b21e1..834f703 100644 --- a/components/ResultDialog.vue +++ b/components/ResultDialog.vue @@ -66,7 +66,7 @@ const close = () => { } .dialog-box { - background-image: url('../images/bg-grass.png'); + background-image: url('/images/bg-grass.png'); padding: 0 20px; border-radius: 5px; width: 800px; diff --git a/nuxt.config.ts b/nuxt.config.ts index 880df38..07ae848 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -11,4 +11,13 @@ export default defineNuxtConfig({ modules: [ '@pinia/nuxt', ], + app: { + head: { + script: [{ + src: "/webgl-utils.js" + }, { + src: "https://lygia.xyz/resolve.js" + }] + } + }, }) diff --git a/pages/index.vue b/pages/index.vue index a45857b..b196a5e 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -15,6 +15,7 @@ import goStore, { setReady } from "@/netcode"; + diff --git a/public/webgl-utils.js b/public/webgl-utils.js new file mode 100644 index 0000000..aaa9125 --- /dev/null +++ b/public/webgl-utils.js @@ -0,0 +1,294 @@ +/* + * Copyright 2021, GFXFundamentals. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of GFXFundamentals. nor the names of his + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* global define */ +(function(root, factory) { // eslint-disable-line + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], function() { + return factory.call(root); + }); + } else { + // Browser globals + root.webglUtils = factory.call(root); + } +}(this, function() { + "use strict"; + + const topWindow = this; + + /** @module webgl-utils */ + + function isInIFrame(w) { + w = w || topWindow; + return w !== w.top; + } + + if (!isInIFrame()) { + console.log("%c%s", 'color:blue;font-weight:bold;', 'for more about webgl-utils.js see:'); // eslint-disable-line + console.log("%c%s", 'color:blue;font-weight:bold;', 'http://webgl2fundamentals.org/webgl/lessons/webgl-boilerplate.html'); // eslint-disable-line + } + + /** + * Wrapped logging function. + * @param {string} msg The message to log. + */ + function error(msg) { + if (topWindow.console) { + if (topWindow.console.error) { + topWindow.console.error(msg); + } else if (topWindow.console.log) { + topWindow.console.log(msg); + } + } + } + + const errorRE = /ERROR:\s*\d+:(\d+)/gi; + function addLineNumbersWithError(src, log = '') { + // Note: Error message formats are not defined by any spec so this may or may not work. + const matches = [...log.matchAll(errorRE)]; + const lineNoToErrorMap = new Map(matches.map((m, ndx) => { + const lineNo = parseInt(m[1]); + const next = matches[ndx + 1]; + const end = next ? next.index : log.length; + const msg = log.substring(m.index, end); + return [lineNo - 1, msg]; + })); + return src.split('\n').map((line, lineNo) => { + const err = lineNoToErrorMap.get(lineNo); + return `${lineNo + 1}: ${line}${err ? `\n\n^^^ ${err}` : ''}`; + }).join('\n'); + } + + + /** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @memberOf module:webgl-utils + */ + + /** + * Loads a shader. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {string} shaderSource The shader source. + * @param {number} shaderType The type of shader. + * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors. + * @return {WebGLShader} The created shader. + */ + function loadShader(gl, shaderSource, shaderType, opt_errorCallback) { + const errFn = opt_errorCallback || error; + // Create the shader object + const shader = gl.createShader(shaderType); + + // Load the shader source + gl.shaderSource(shader, shaderSource); + + // Compile the shader + gl.compileShader(shader); + + // Check the compile status + const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + const lastError = gl.getShaderInfoLog(shader); + errFn(`Error compiling shader: ${lastError}\n${addLineNumbersWithError(shaderSource, lastError)}`); + gl.deleteShader(shader); + return null; + } + + return shader; + } + + /** + * Creates a program, attaches shaders, binds attrib locations, links the + * program and calls useProgram. + * @param {WebGLShader[]} shaders The shaders to attach + * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in + * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations. + * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console + * on error. If you want something else pass an callback. It's passed an error message. + * @memberOf module:webgl-utils + */ + function createProgram( + gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { + const errFn = opt_errorCallback || error; + const program = gl.createProgram(); + shaders.forEach(function(shader) { + gl.attachShader(program, shader); + }); + if (opt_attribs) { + opt_attribs.forEach(function(attrib, ndx) { + gl.bindAttribLocation( + program, + opt_locations ? opt_locations[ndx] : ndx, + attrib); + }); + } + gl.linkProgram(program); + + // Check the link status + const linked = gl.getProgramParameter(program, gl.LINK_STATUS); + if (!linked) { + // something went wrong with the link + const lastError = gl.getProgramInfoLog(program); + errFn(`Error in program linking: ${lastError}\n${ + shaders.map(shader => { + const src = addLineNumbersWithError(gl.getShaderSource(shader)); + const type = gl.getShaderParameter(shader, gl.SHADER_TYPE); + return `${glEnumToString(gl, type)}:\n${src}`; + }).join('\n') + }`); + + gl.deleteProgram(program); + return null; + } + return program; + } + + /** + * Loads a shader from a script tag. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {string} scriptId The id of the script tag. + * @param {number} opt_shaderType The type of shader. If not passed in it will + * be derived from the type of the script tag. + * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors. + * @return {WebGLShader} The created shader. + */ + function createShaderFromScript( + gl, scriptId, opt_shaderType, opt_errorCallback) { + let shaderSource = ""; + let shaderType; + const shaderScript = document.getElementById(scriptId); + if (!shaderScript) { + throw ("*** Error: unknown script element" + scriptId); + } + shaderSource = shaderScript.text; + + if (!opt_shaderType) { + if (shaderScript.type === "x-shader/x-vertex") { + shaderType = gl.VERTEX_SHADER; + } else if (shaderScript.type === "x-shader/x-fragment") { + shaderType = gl.FRAGMENT_SHADER; + } else if (shaderType !== gl.VERTEX_SHADER && shaderType !== gl.FRAGMENT_SHADER) { + throw ("*** Error: unknown shader type"); + } + } + + return loadShader( + gl, shaderSource, opt_shaderType ? opt_shaderType : shaderType, + opt_errorCallback); + } + + const defaultShaderType = [ + "VERTEX_SHADER", + "FRAGMENT_SHADER", + ]; + + /** + * Creates a program from 2 script tags. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderScriptIds Array of ids of the script + * tags for the shaders. The first is assumed to be the + * vertex shader, the second the fragment shader. + * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in + * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations. + * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console + * on error. If you want something else pass an callback. It's passed an error message. + * @return {WebGLProgram} The created program. + * @memberOf module:webgl-utils + */ + function createProgramFromScripts( + gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { + const shaders = []; + for (let ii = 0; ii < shaderScriptIds.length; ++ii) { + shaders.push(createShaderFromScript( + gl, shaderScriptIds[ii], gl[defaultShaderType[ii]], opt_errorCallback)); + } + return createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback); + } + + /** + * Creates a program from 2 sources. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSourcess Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in + * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations. + * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console + * on error. If you want something else pass an callback. It's passed an error message. + * @return {WebGLProgram} The created program. + * @memberOf module:webgl-utils + */ + function createProgramFromSources( + gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + const shaders = []; + for (let ii = 0; ii < shaderSources.length; ++ii) { + shaders.push(loadShader( + gl, shaderSources[ii], gl[defaultShaderType[ii]], opt_errorCallback)); + } + return createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback); + } + + /** + * Resize a canvas to match the size its displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] amount to multiply by. + * Pass in window.devicePixelRatio for native pixels. + * @return {boolean} true if the canvas was resized. + * @memberOf module:webgl-utils + */ + function resizeCanvasToDisplaySize(canvas, multiplier) { + multiplier = multiplier || 1; + const width = canvas.clientWidth * multiplier | 0; + const height = canvas.clientHeight * multiplier | 0; + if (canvas.width !== width || canvas.height !== height) { + canvas.width = width; + canvas.height = height; + return true; + } + return false; + } + + return { + createProgram: createProgram, + createProgramFromScripts: createProgramFromScripts, + createProgramFromSources: createProgramFromSources, + resizeCanvasToDisplaySize: resizeCanvasToDisplaySize, + }; + +})); +