From e3cf871f790c71677d0f3882772d9192cfb15abe Mon Sep 17 00:00:00 2001 From: wan-may Date: Fri, 14 Mar 2025 13:46:15 -0300 Subject: [PATCH] two nights development --- conf.lua | 51 +++++++++ gpu.lua | 0 i18n/en.lua | 26 +++-- instance.lua | 82 ++++++++++++++ main.lua | 243 ++---------------------------------------- mat4.lua | 145 +++++++++++++++++-------- scene.lua | 8 ++ scenes/settings.lua | 35 ++++++ scenes/slideshow.lua | 42 ++++++++ scratch.lua | 248 +++++++++++++++++++++++++++++++++++++++++++ settings.lua | 7 ++ 11 files changed, 596 insertions(+), 291 deletions(-) create mode 100644 conf.lua create mode 100644 gpu.lua create mode 100644 instance.lua create mode 100644 scene.lua create mode 100644 scenes/settings.lua create mode 100644 scenes/slideshow.lua create mode 100644 scratch.lua create mode 100644 settings.lua diff --git a/conf.lua b/conf.lua new file mode 100644 index 0000000..450a4af --- /dev/null +++ b/conf.lua @@ -0,0 +1,51 @@ +function love.conf(t) + t.identity = "anno 1968" -- The name of the save directory (string) + t.appendidentity = false -- Search files in source directory before save directory (boolean) + t.version = "11.4" -- The LÖVE version this game was made for (string) + t.console = false -- Attach a console (boolean, Windows only) + t.accelerometerjoystick = true -- Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean) + t.externalstorage = false -- True to save files (and read from the save directory) in external storage on Android (boolean) + t.gammacorrect = false -- Enable gamma-correct rendering, when supported by the system (boolean) + + t.audio.mic = false -- Request and use microphone capabilities in Android (boolean) + t.audio.mixwithsystem = true -- Keep background music playing when opening LOVE (boolean, iOS and Android only) + + t.window.title = "ᐊᑯᓕᕕᒃ" -- The window title (string) + t.window.icon = nil -- Filepath to an image to use as the window's icon (string) + t.window.width = 800 -- The window width (number) + t.window.height = 600 -- The window height (number) + t.window.borderless = false -- Remove all border visuals from the window (boolean) + t.window.resizable = false -- Let the window be user-resizable (boolean) + t.window.minwidth = 1 -- Minimum window width if the window is resizable (number) + t.window.minheight = 1 -- Minimum window height if the window is resizable (number) + t.window.fullscreen = false -- Enable fullscreen (boolean) + t.window.fullscreentype = "desktop" -- Choose between "desktop" fullscreen or "exclusive" fullscreen mode (string) + t.window.vsync = 1 -- Vertical sync mode (number) + t.window.msaa = 0 -- The number of samples to use with multi-sampled antialiasing (number) + t.window.depth = nil -- The number of bits per sample in the depth buffer + t.window.stencil = nil -- The number of bits per sample in the stencil buffer + t.window.display = 1 -- Index of the monitor to show the window in (number) + t.window.highdpi = false -- Enable high-dpi mode for the window on a Retina display (boolean) + t.window.usedpiscale = true -- Enable automatic DPI scaling when highdpi is set to true as well (boolean) + t.window.x = nil -- The x-coordinate of the window's position in the specified display (number) + t.window.y = nil -- The y-coordinate of the window's position in the specified display (number) + + t.modules.audio = true -- Enable the audio module (boolean) + t.modules.data = true -- Enable the data module (boolean) + t.modules.event = true -- Enable the event module (boolean) + t.modules.font = true -- Enable the font module (boolean) + t.modules.graphics = true -- Enable the graphics module (boolean) + t.modules.image = true -- Enable the image module (boolean) + t.modules.joystick = true -- Enable the joystick module (boolean) + t.modules.keyboard = true -- Enable the keyboard module (boolean) + t.modules.math = true -- Enable the math module (boolean) + t.modules.mouse = true -- Enable the mouse module (boolean) + t.modules.physics = true -- Enable the physics module (boolean) + t.modules.sound = true -- Enable the sound module (boolean) + t.modules.system = true -- Enable the system module (boolean) + t.modules.thread = true -- Enable the thread module (boolean) + t.modules.timer = true -- Enable the timer module (boolean), Disabling it will result 0 delta time in love.update + t.modules.touch = true -- Enable the touch module (boolean) + t.modules.video = true -- Enable the video module (boolean) + t.modules.window = true -- Enable the window module (boolean) +end \ No newline at end of file diff --git a/gpu.lua b/gpu.lua new file mode 100644 index 0000000..e69de29 diff --git a/i18n/en.lua b/i18n/en.lua index c62844b..25fa697 100644 --- a/i18n/en.lua +++ b/i18n/en.lua @@ -1,11 +1,19 @@ return { - intro = { - "ᐊᑯᓕᕕᒃ", - "1968", - "BROTHER JARED has led his flock beyond darkest Thule", - "to conjure ZIMINIAR, KING OF THE NORTH.", - "You are the latest to attempt the ritual.", - "Succeed, and be crowned Brother Jared's foremost wife.", - "You are at the mercy of ZIMINIAR, and the elements he commands." - } + title = "ᐊᑯᓕᕕᒃ", + font = "fonts/bjcrus.ttf", + intro = [[ᐊᑯᓕᕕᒃ, 1968 + +BROTHER JARED HAS BROUGHT THE ROCK OF FINAL JUDGEMENT, HIS BELOVED FLOCK, BEYOND DARKEST THULE, TO THE REMAINS OF A REMOTE TRADING POST. + +HERE WE WILL ATTEMPT TO CONJURE ZIMINIAR, THE KING OF THE NORTH. + +I HAVE VOLUNTEERED TO BE THE FIRST TO ATTEMPT THE RITUAL, THAT I MIGHT BE CROWNED, AMID THE CHAOS LOOSED UPON THE WORLD, JARED'S FOREMOST AND ETERNAL WIFE.]], + loss = "YOU HAVE DIED OF %s", + win = "RICHES TO THE CONJURER", + settingsMenuTitle = "SETTINGS", + toContinue = "PRESS ENTER TO CONTINUE", + keyForward = "FORWARD", + keyBack = "BACK", + keyLeft = "LEFT", + keyRight = "RIGHT", } \ No newline at end of file diff --git a/instance.lua b/instance.lua new file mode 100644 index 0000000..51acbc2 --- /dev/null +++ b/instance.lua @@ -0,0 +1,82 @@ +local love = assert( love ) + +local mat4 = require( "mat4" ) +local alph = 1/math.sqrt(2) +local testMesh = love.graphics.newMesh( + {--attributes + {"VertexPosition", "float", 4}, + {"VertexColor", "float", 3}, + {"VertexTexCoord", "float", 2}, + }, + {--vertices + { 1, 0, -alph, 1, + 1, 1, 1, + 1, 0 }, + { -1, 0, -alph, 1, + 1, 0, 0, + 0, 0 }, + { 0, 1, alph, 1, + 0, 1, 0, + 1, 1, }, + { 0, -1, alph, 1, + 0, 0, 1, + 0, 1, }, + }, + "strip", + "static" +) +testMesh:setVertexMap{ 1,2,3,4,1,2 } +local rockTexture = love.graphics.newImage( "tex/rock.png" ) +rockTexture:setWrap( "repeat", "repeat" ) +testMesh:setTexture( rockTexture ) + +--Transforms +mat4.randomise() +local instanceTransforms = love.graphics.newMesh( { + {"itx", "float", 4}, + {"ity", "float", 4}, + {"itz", "float", 4}, + {"itw", "float", 4}}, 1024, nil, "static" ) +instanceTransforms:setVertices( mat4.data ) +testMesh:attachAttribute( "itx", instanceTransforms, "perinstance" ) +testMesh:attachAttribute( "ity", instanceTransforms, "perinstance" ) +testMesh:attachAttribute( "itz", instanceTransforms, "perinstance" ) +testMesh:attachAttribute( "itw", instanceTransforms, "perinstance" ) + + +local instanceShader = [[ + varying vec4 itxdbg; +#ifdef VERTEX + attribute vec4 itx; + attribute vec4 ity; + attribute vec4 itz; + attribute vec4 itw; + uniform mat4 view; + uniform mat4 proj; + vec4 position( mat4 _, vec4 pos ){ + mat4 inst = mat4( itx, ity, itz, itw ); + vec4 cam = view*pos; + itxdbg = itw; + return proj * cam; + } +#endif +#ifdef PIXEL + vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) { + return color * Texel(tex, texuv) * vec4( 2.0, 2.0, 2.0, itxdbg.w ) ; + } +#endif +]] +instanceShader = love.graphics.newShader( instanceShader, instanceShader ) + +return { draw = function( view, proj ) + love.graphics.push( "all" ) + love.graphics.setShader( instanceShader ) + instanceShader:send( "view", "column", view ) + instanceShader:send( "proj", "column", proj ) + io.flush() + love.graphics.drawInstanced( testMesh, 30, 0, 0 ) + love.graphics.pop() + end, + update = function() + mat4.randomise() + end} \ No newline at end of file diff --git a/main.lua b/main.lua index 4e22472..a654ce6 100644 --- a/main.lua +++ b/main.lua @@ -1,239 +1,8 @@ local love = assert( love ) -local mat4 = require( "mat4" ) -local alph = 1/math.sqrt(2) -local testMesh = love.graphics.newMesh( - {--attributes - {"VertexPosition", "float", 4}, - {"VertexColor", "float", 3}, - {"VertexTexCoord", "float", 2}, - }, - {--vertices - { 1, 0, -alph, 1, - 1, 1, 1, - 1, 0 }, - { -1, 0, -alph, 1, - 1, 0, 0, - 0, 0 }, - { 0, 1, alph, 1, - 0, 1, 0, - 1, 1, }, - { 0, -1, alph, 1, - 0, 0, 1, - 0, 1, }, - }, - "strip", - "static" -) -testMesh:setVertexMap{ 1,2,3,4,1,2 } -local rockTexture = love.graphics.newImage( "tex/rock.png" ) -rockTexture:setWrap( "repeat", "repeat" ) -testMesh:setTexture( rockTexture ) +local scene = require( "scene" ) +local strings = require( "i18n.en" ) +local slideshow = require( "scenes.slideshow" ) +local settings = require( "scenes.settings" ) -local testQuad = love.graphics.newMesh( - {--attributes - {"VertexPosition", "float", 4}, - {"VertexColor", "float", 3}, - {"VertexTexCoord", "float", 2}, - }, - {--vertices - { -1, -1,- 2, 1, - 1, 1, 1, - 0, 0, }, - { 1, -1,- 2, 1, - 1, 0, 0, - 1, 0, }, - { 1, 1,- 2, 1, - 0, 0, 1, - 1, 1, }, - { -1, 1,- 2, 1, - 0, 1, 0, - 0, 1, }, - }, - "fan", - "static" -) - -local testShader = [[ - varying float d; -#ifdef VERTEX - uniform mat4 mdl; - uniform mat4 view; - uniform mat4 proj; - vec4 position( mat4 _, vec4 pos ){ - vec4 cam = view*mdl*pos; - d = cam.z; - return proj * cam; - } -#endif -#ifdef PIXEL - vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) { - return color * Texel(tex, texuv) * vec4( 1.0, 1.0, 1.0, 1.0 ) ; - } -#endif -]] -testShader = love.graphics.newShader( testShader, testShader ) - ---column major -local function prod( A, B ) - local C = {} - for j = 1,4 do C[j] = {0, 0, 0, 0} end - for j = 1, 4 do - for i = 1, 4 do - C[j][i] = - A[1][i] * B[j][1] + - A[2][i] * B[j][2] + - A[3][i] * B[j][3] + - A[4][i] * B[j][4] - end - end - return C -end - - -local function roll( t ) - local c, s = math.cos(t), math.sin(t) - return { - {c, 0, s, 0}, - {0, 1, 0, 0}, - {-s, 0, c, 0}, - {0, 0, 0, 1}, - } -end - - -local function trans( x, y, z ) - return { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {x, y, z, 1}, - } -end - -local function scale( x, y, z ) - return { - {x, 0, 0, 0}, - {0, y, 0, 0}, - {0, 0, z, 0}, - {0, 0, 0, 1}, - } -end - -local function id() - return { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1}, - } -end - ---tait-bryan yaw pitch roll -local function rotate( a, b, g ) - local c, s = math.cos, math.sin - local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g) - return { - { ca*cb, sa*cb, -sb, 0}, - {ca*sb*sg - sa*cg, sa*sb*sg + ca*cg, cb*sg, 0}, - {ca*sb*cg + sa*sg, sa*sb*cg - ca*sg, cb*cg, 0}, - { 0, 0, 0, 1}, - } -end - ---fov in degrees, aspect w/h, near far -local function getProjectionMatrix(n, f, fov) - local r = love.graphics.getWidth() / 2 - local t = love.graphics.getHeight() / 2 - local aspect = r/t - local tan = math.tan( fov / 2 ) - return - --infinite z - --TODO: get finite - { {1.0 / tan, 0, 0, 0}, - {0, -1.0 / tan, 0, 0}, - {0, 0, ( f + n ) / (n-f), -1 }, - {0, 0, -2 * f * n / (f - n), 0}, - } -end - -local function getViewMatrix() - return { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1}, - } -end - -local testModelMatrix -local testViewMatrix = getViewMatrix() -local testProjection = getProjectionMatrix( 0.1, 10, math.rad( 30 ) ) -local time = 0 - -local testDSCanvas = love.graphics.newCanvas( - love.graphics.getWidth(), - love.graphics.getHeight(), - { readable = true, - format = "depth24" }) - -local testCanvas = love.graphics.newCanvas() -local creeFont = love.graphics.newFont( "fonts/bjcrus.ttf", 48 ) ---row major ---4th column [:][4] translates ---diagonal [i][i], i < 4 scales ---rotations in [1:3][1:3] -function love.draw() - - - love.graphics.setColor( 1, 1 ,1, 1 ) - love.graphics.push( "all" ) - love.graphics.setCanvas( { testCanvas, depthstencil = testDSCanvas } ) - love.graphics.clear() - love.graphics.setDepthMode( "less", true ) - love.graphics.setShader( testShader ) - testShader:send( "mdl", "column", testModelMatrix ) - testShader:send( "proj", "column", testProjection ) - testShader:send( "view", "column", testViewMatrix ) - --love.graphics.draw( testMesh ) - - math.randomseed( 4 ) - for i = 1, 15 do - local x, y, z = 3 * ( math.random() - 0.5 ), 3 * ( math.random() - 0.5 ) - testShader:send( "mdl", "column", - prod( trans( x, y, -8 ), - rotate( 0, time, math.random() ))) - love.graphics.draw( testMesh ) - end - - testShader:send( "mdl", "column", id() ) - -- love.graphics.draw( testQuad ) - - love.graphics.setShader() - love.graphics.setColor(1,1,1, 0.5 ) - --love.graphics.rectangle( "fill", 0, 0, love.graphics.getDimensions() ) - love.graphics.setCanvas() - love.graphics.setDepthMode( "always", true ) - love.graphics.pop() - love.graphics.draw( testCanvas ) - local str = require( "i18n.en" ) - love.graphics.print( string.format( "%05.2f\t:TIME\n%05.2f\t:ANGLE\n", time, time)) - love.graphics.print( { {1, 0.2, 0.2}, str.intro1}, - creeFont, - 0.5 * ( love.graphics.getWidth() - creeFont:getWidth(str.intro[1]) ), - 0.5 * ( love.graphics.getHeight() - creeFont:getHeight() )) - --[[love.graphics.setShader() - love.graphics.setColor( 1,1,1,1 ) - love.graphics.circle( "fill", time, time/2, 5 )]] -end - -function love.update( dt ) - time = time + dt - testModelMatrix = prod( - trans( 0, 0, -4 + math.sin( time )), - roll( time ) - ) - testModelMatrix = prod( - testModelMatrix, - rotate( time, time, time ) - ) -end +love.graphics.setNewFont( strings.font, 18 ) +return slideshow.play( strings.intro, function() return scene.load( settings ) end ) \ No newline at end of file diff --git a/mat4.lua b/mat4.lua index 7d1c83c..b6a2c27 100644 --- a/mat4.lua +++ b/mat4.lua @@ -2,25 +2,70 @@ local love = assert( love ) local ffi = require('ffi') -local cmat4 = ffi.typeof( [[struct{ float x[4][4]; }]] ) - ---this is actually the argument we need to send to shader:send -local data = love.data.newByteData( ffi.sizeof( cmat4 ) * 1024 ) -print( "size", data:getSize() ) +ffi.cdef[[ typedef struct{ float m[4][4]; } mat4_t ]] +local ctype = ffi.typeof( "mat4_t*" ) local t = {} -t.__index = t -ffi.metatype( cmat4, t ) +--this is actually the argument we need to send to shader:send +--and to newMesh +local data = love.data.newByteData( ffi.sizeof( "mat4_t" ) * 1024 ) +t.data = data +local ptr = data:getFFIPointer() +print( "size", data:getSize() ) -function t.__tostring( m ) +function t.__tostring( idx ) + assert( idx < 1024 ) + local ptr = ffi.cast( ctype, data:getFFIPointer() ) + local m = ptr[ idx ].m return ([[ - |%05.2f %05.2f %05.2f %05.2f| - |%05.2f %05.2f %05.2f %05.2f| - |%05.2f %05.2f %05.2f %05.2f| - |%05.2f %05.2f %05.2f %05.2f|]]):format( - m.x[0][0], m.x[1][0], m.x[2][0], m.x[3][0], - m.x[0][1], m.x[1][1], m.x[2][1], m.x[3][1], - m.x[0][2], m.x[1][2], m.x[2][2], m.x[3][2], - m.x[0][3], m.x[1][3], m.x[2][3], m.x[3][3]) + %.2f %.2f %.2f %.2f + %.2f %.2f %.2f %.2f + %.2f %.2f %.2f %.2f + %.2f %.2f %.2f %.2f + ]]):format( + m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3]) +end + +function t.lTRS( x, y, z, a, b, g, dx, dy, dz ) + local c, s = math.cos, math.sin + local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g) + return { + {x*ca*cb, y*sa*cb, z*(-sb), 0}, + {x*(ca*sb*sg - sa*cg), y*(sa*sb*sg+ca*cg), z*(cb*sg), 0}, + {x*(ca*sb*cg+sa*sg), y*(sa*sb*cg-ca*sg), z*cb*cg, 0}, + {dx, dy, dz, 1}} +end + +function t.transpose( A ) + for i = 1, 4 do + for j = 1, 4 do + A[i][j] = A[j][i] + end + end +end + +function t.TRS( idx, x, y, z, a, b, g, dx, dy, dz ) + assert( idx < 1024 ) + local ptr = ffi.cast( ctype, data:getFFIPointer() ) + local m = ptr[ idx ].m + + local c, s = math.cos, math.sin + local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g) + m[0][0], m[0][1], m[0][2], m[0][3], + m[1][0], m[1][1], m[1][2], m[1][3], + m[2][0], m[2][1], m[2][2], m[2][3], + m[3][0], m[3][1], m[3][2], m[3][3] = + + x*ca*cb, x*(ca*sb*sg - sa*cg), x*(ca*sb*cg+sa*sg), dx, + y*sa*cb, y*(sa*sb*sg+ca*cg), y*(sa*sb*cg-ca*sg), dy, + z*(-sb), z*(cb*sg), z*cb*cg, dz, + 0, 0, 0, 1 + + + do local p, m = ptr, m end --keep alive + return idx end function t.__mul( A, B ) @@ -47,40 +92,50 @@ function t.__add( A, B ) return C end -function t:rotate( a, b, g ) - local c, s = math.cos, math.sin - local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g) - return cmat4( - ca*cb, sa*cb, -sb, 0, - ca*sb*sg - sa*cg, sa*sb*sg + ca*cg, cb*sg, 0, - ca*sb*cg + sa*sg, sa*sb*cg - ca*sg, cb*cg, 0, - 0, 0, 0, 1 - ) * self +function t.randomise( start, len ) + start = start or 0 + len = len or 1023 + for i = start, start + len do + t.TRS( i, + --scale + 1, + 1, + 1, + 0, + 0, + 0, + --pos + 0, + 0, + -4 ) + end end -function t:scale( x, y, z ) - return cmat4( - x, 0, 0, 0, - 0, y, 0, 0, - 0, 0, z, 0, - 0, 0, 0, 1 - ) * self -end +function t.id() + local ptr = ffi.cast( ctype, data:getFFIPointer() ) + for i = 1, 1024 do + local m = ptr[ i ].m -function t:translate( x, y, z ) - local a = cmat4() - a.x[0][0], a.x[1][1], a.x[2][2], a.x[3][3] = 1, 1, 1, 1 - a.x[3][0], a.x[3][1], a.x[3][2] = x, y, z - return a * self + m[0][0], m[1][1], m[2][2], m[3][3] = 1, 1, 1, 1 + + do local p, m = ptr, m end --keep alive + end end do --tests - print( cmat4() ); io.flush() - local a = ffi.gc(cmat4(), nil) - a.x[0][0], a.x[1][1], a.x[2][2],a.x[3][3] = 1,1,1,1 - print( a ); io.flush() - print( a:translate( 1, 2, 3 ) ); - io.flush() + local math = math + --[[ for i = 0, 1023 do + t.TRS( i, + 0.5 + math.random(), + 0.5 + math.random(), + 0.5 + math.random(), + 2 * math.pi * math.random(), + 2 * math.pi * math.random(), + 2 * math.pi * math.random(), + 10 * math.random(), + 10 * math.random(), + 10 * math.random() ) + end]] end -return cmat4 \ No newline at end of file +return t \ No newline at end of file diff --git a/scene.lua b/scene.lua new file mode 100644 index 0000000..6cfd909 --- /dev/null +++ b/scene.lua @@ -0,0 +1,8 @@ +local love = assert( love ) +local scene = {} +function scene.load( t ) + for k, callback in pairs( t ) do + love[k] = callback + end +end +return scene \ No newline at end of file diff --git a/scenes/settings.lua b/scenes/settings.lua new file mode 100644 index 0000000..cc4a143 --- /dev/null +++ b/scenes/settings.lua @@ -0,0 +1,35 @@ +local love = assert( love ) +local strings = require( "i18n.en" ) +local settings = require( "settings" ) +local t = {} + +local currentSetting + +function t.keypressed( key, code, isRepeat ) + +end + +function t.mousemoved() + +end + +function t.mousepressed() + +end + +function t.update() + +end + +function t.draw() + love.graphics.print( strings.toContinue, 0, love.graphics.getHeight() - love.graphics.getFont():getHeight() ) + love.graphics.print( strings.settingsMenuTitle, 0, 0 ) + for i, setting in ipairs( settings ) do + local x, y = 10, 10 + i * 100 + love.graphics.rectangle( "line", x, y, love.graphics.getWidth(), 100 ) + love.graphics.print( setting.name, x + 10, y ) + love.graphics.print( setting.val, x + 10, y + 25 ) + end +end + +return t \ No newline at end of file diff --git a/scenes/slideshow.lua b/scenes/slideshow.lua new file mode 100644 index 0000000..af80b9d --- /dev/null +++ b/scenes/slideshow.lua @@ -0,0 +1,42 @@ +local love = assert( love ) +local scene = require( "scene" ) +local settings = require( "scenes.settings" ) +local strings = require( "i18n.en" ) +local printString +local fullString +local loadNextScene +local utf8 = require( "utf8" ) + +local t = {} + +local len = 0 +local time = 0 + + +function t.keypressed( key, code, isRepeat ) + if code == "return" then return loadNextScene() end +end + +function t.draw() + love.graphics.printf( printString, 10, 10, math.min( 400, love.graphics.getWidth() / 2 ), "left" ) + love.graphics.print( strings.toContinue, 10, love.graphics.getHeight() - love.graphics.getFont():getHeight() ) +end + +function t.update( dt ) + time = time + dt + if time > 0.05 then + time = 0 + len = len + 1 + if len > fullString:len() + 40 then return loadNextScene() end + printString = fullString:sub( 1, ( utf8.offset( fullString, len ) or 0 ) - 1 ) + end +end + +function t.play( str, nextScene ) + loadNextScene = nextScene + fullString = str + printString = "" + return scene.load( t ) +end + +return t \ No newline at end of file diff --git a/scratch.lua b/scratch.lua new file mode 100644 index 0000000..db4aee9 --- /dev/null +++ b/scratch.lua @@ -0,0 +1,248 @@ +local love = assert( love ) +local mat4 = require( "mat4" ) +local alph = 1/math.sqrt(2) +local testMesh = love.graphics.newMesh( + {--attributes + {"VertexPosition", "float", 4}, + {"VertexColor", "float", 3}, + {"VertexTexCoord", "float", 2}, + }, + {--vertices + { 1, 0, -alph, 1, + 1, 1, 1, + 1, 0 }, + { -1, 0, -alph, 1, + 1, 0, 0, + 0, 0 }, + { 0, 1, alph, 1, + 0, 1, 0, + 1, 1, }, + { 0, -1, alph, 1, + 0, 0, 1, + 0, 1, }, + }, + "strip", + "static" +) +testMesh:setVertexMap{ 1,2,3,4,1,2 } +local rockTexture = love.graphics.newImage( "tex/rock.png" ) +rockTexture:setWrap( "repeat", "repeat" ) +testMesh:setTexture( rockTexture ) + +local testQuad = love.graphics.newMesh( + {--attributes + {"VertexPosition", "float", 4}, + {"VertexColor", "float", 3}, + {"VertexTexCoord", "float", 2}, + }, + {--vertices + { -1, -1,- 2, 1, + 1, 1, 1, + 0, 0, }, + { 1, -1,- 2, 1, + 1, 0, 0, + 1, 0, }, + { 1, 1,- 2, 1, + 0, 0, 1, + 1, 1, }, + { -1, 1,- 2, 1, + 0, 1, 0, + 0, 1, }, + }, + "fan", + "static" +) + +local testShader = [[ + varying float d; +#ifdef VERTEX + uniform mat4 mdl; + uniform mat4 view; + uniform mat4 proj; + vec4 position( mat4 _, vec4 pos ){ + vec4 cam = view*mdl*pos; + d = cam.z; + return proj * cam; + } +#endif +#ifdef PIXEL + vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) { + return color * Texel(tex, texuv) * vec4( 2.0, 2.0, 2.0, -d / 9.0 ) ; + } +#endif +]] +testShader = love.graphics.newShader( testShader, testShader ) + +--column major +local function prod( A, B ) + local C = {} + for j = 1,4 do C[j] = {0, 0, 0, 0} end + for j = 1, 4 do + for i = 1, 4 do + C[j][i] = + A[1][i] * B[j][1] + + A[2][i] * B[j][2] + + A[3][i] * B[j][3] + + A[4][i] * B[j][4] + end + end + return C +end + + +local function roll( t ) + local c, s = math.cos(t), math.sin(t) + return { + {c, 0, s, 0}, + {0, 1, 0, 0}, + {-s, 0, c, 0}, + {0, 0, 0, 1}, + } +end + + +local function trans( x, y, z ) + return { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {x, y, z, 1}, + } +end + +local function scale( x, y, z ) + return { + {x, 0, 0, 0}, + {0, y, 0, 0}, + {0, 0, z, 0}, + {0, 0, 0, 1}, + } +end + +local function id() + return { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}, + } +end + +--tait-bryan yaw pitch roll +local function rotate( a, b, g ) + local c, s = math.cos, math.sin + local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g) + return { + { ca*cb, sa*cb, -sb, 0}, + {ca*sb*sg - sa*cg, sa*sb*sg + ca*cg, cb*sg, 0}, + {ca*sb*cg + sa*sg, sa*sb*cg - ca*sg, cb*cg, 0}, + { 0, 0, 0, 1}, + } +end + +--fov in degrees, aspect w/h, near far +local function getProjectionMatrix(n, f, fov) + local r = love.graphics.getWidth() / 2 + local t = love.graphics.getHeight() / 2 + local aspect = r/t + local tan = math.tan( fov / 2 ) + return + --infinite z + --TODO: get finite + { {1.0 / tan, 0, 0, 0}, + {0, -1.0 / tan, 0, 0}, + {0, 0, ( f + n ) / (n-f), -1 }, + {0, 0, -2 * f * n / (f - n), 0}, + } +end + +local function getViewMatrix() + return { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}, + } +end + +local testModelMatrix +local testViewMatrix = getViewMatrix() +local testProjection = getProjectionMatrix( 0.1, 70, math.rad( 90 ) ) +local time = 0 + +local testDSCanvas = love.graphics.newCanvas( + love.graphics.getWidth(), + love.graphics.getHeight(), + { readable = true, + format = "depth24" }) + +local testCanvas = love.graphics.newCanvas() +local creeFont = love.graphics.newFont( "fonts/bjcrus.ttf", 48 ) +--row major +--4th column [:][4] translates +--diagonal [i][i], i < 4 scales +--rotations in [1:3][1:3] +function love.draw() + local instance = require( "instance" ) + love.graphics.setCanvas( { testCanvas, depthstencil = testDSCanvas } ) + love.graphics.clear() + love.graphics.setDepthMode( "less", true ) + instance.draw(testViewMatrix, testProjection) + love.graphics.setCanvas() + love.graphics.draw( testCanvas ) + --[[ + + love.graphics.setColor( 1, 1 ,1, 1 ) + love.graphics.push( "all" ) + love.graphics.setCanvas( { testCanvas, depthstencil = testDSCanvas } ) + love.graphics.clear() + love.graphics.setDepthMode( "less", true ) + love.graphics.setShader( testShader ) + testShader:send( "mdl", "column", testModelMatrix ) + testShader:send( "proj", "column", testProjection ) + testShader:send( "view", "column", testViewMatrix ) + --love.graphics.draw( testMesh ) + + math.randomseed( 4 ) + for i = 1, 15 do + local x, y, z = 3 * ( math.random() - 0.5 ), 3 * ( math.random() - 0.5 ) + testShader:send( "mdl", "column", + prod( trans( x, y, -8 ), + rotate( 0, time, math.random() ))) + love.graphics.draw( testMesh ) + end + + testShader:send( "mdl", "column", id() ) + -- love.graphics.draw( testQuad ) + + love.graphics.setShader() + love.graphics.setColor(1,1,1, 0.5 ) + --love.graphics.rectangle( "fill", 0, 0, love.graphics.getDimensions() ) + love.graphics.setCanvas() + love.graphics.setDepthMode( "always", true ) + love.graphics.pop() + love.graphics.draw( testCanvas ) + local str = require( "i18n.en" ) + love.graphics.print( string.format( "%05.2f\t:TIME\n%05.2f\t:ANGLE\n", time, time)) + love.graphics.print( { {1, 0.2, 0.2}, str.intro1}, + creeFont, + 0.5 * ( love.graphics.getWidth() - creeFont:getWidth(str.intro[1]) ), + 0.5 * ( love.graphics.getHeight() - creeFont:getHeight() ))]] + --[[love.graphics.setShader() + love.graphics.setColor( 1,1,1,1 ) + love.graphics.circle( "fill", time, time/2, 5 )]] +end + +function love.update( dt ) + local instance = require("instance") + time = time + dt + testModelMatrix = prod( + trans( 0, 0, -4 + math.sin( time )), + roll( time ) + ) + testModelMatrix = prod( + testModelMatrix, + rotate( time, time, time ) + ) + return instance.update() +end diff --git a/settings.lua b/settings.lua new file mode 100644 index 0000000..416c3dc --- /dev/null +++ b/settings.lua @@ -0,0 +1,7 @@ +local strings = require( "i18n.en" ) +return { + { setting = "keyForward", name = strings.keyForward, val = "w" }, + { setting = "keyBack", name = strings.keyBack, val = "a" }, + { setting = "keyLeft", name = strings.keyLeft, val = "s" }, + { setting = "keyRight", name = strings.keyRight, val = "d" }, +} \ No newline at end of file