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( 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