diff --git a/license.txt b/LICENSE similarity index 100% rename from license.txt rename to LICENSE diff --git a/examples/complex.lua b/examples/complex.lua new file mode 100644 index 0000000..b4d916b --- /dev/null +++ b/examples/complex.lua @@ -0,0 +1,715 @@ +-- Example: Complex Example +require "lib/postshader" +require "lib/light" + +function initScene() + -- physic world + physicWorld = love.physics.newWorld(0, 9.81 * 64, true) + wall1 = {} + wall1.body = love.physics.newBody(physicWorld, 400, 605, "static") + wall1.shape = love.physics.newRectangleShape(0, 0, 800, 10) + wall1.fixture = love.physics.newFixture(wall1.body, wall1.shape) + + wall2 = {} + wall2.body = love.physics.newBody(physicWorld, -5, 300, "static") + wall2.shape = love.physics.newRectangleShape(0, 0, 10, 600) + wall2.fixture = love.physics.newFixture(wall2.body, wall2.shape) + + wall3 = {} + wall3.body = love.physics.newBody(physicWorld, 805, 300, "static") + wall3.shape = love.physics.newRectangleShape(0, 0, 10, 600) + wall3.fixture = love.physics.newFixture(wall3.body, wall3.shape) + + wall4 = {} + wall4.body = love.physics.newBody(physicWorld, 400, -5, "static") + wall4.shape = love.physics.newRectangleShape(0, 0, 800, 10) + wall4.fixture = love.physics.newFixture(wall4.body, wall4.shape) + + phyCnt = 0 + phyLight = {} + phyBody = {} + phyShape = {} + phyFixture = {} +end + +function love.load() + love.graphics.setBackgroundColor(0, 0, 0) + love.graphics.setDefaultFilter("nearest", "nearest") + + -- load image font + font = love.graphics.newImageFont("gfx/font.png", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&`'*#=[]\"") + love.graphics.setFont(font) + + -- set background + quadScreen = love.graphics.newQuad(0, 0, love.window.getWidth() + 32, love.window.getHeight() + 24, 32, 24) + imgFloor = love.graphics.newImage("gfx/floor.png") + imgFloor:setWrap("repeat", "repeat") + + -- load image examples + circle = love.graphics.newImage("gfx/circle.png") + circle_normal = love.graphics.newImage("gfx/circle_normal.png") + cone = love.graphics.newImage("gfx/cone.png") + cone_large = love.graphics.newImage("gfx/cone_large.png") + cone_large_normal = love.graphics.newImage("gfx/cone_large_normal.png") + cone_normal = love.graphics.newImage("gfx/cone_normal.png") + chest = love.graphics.newImage("gfx/chest.png") + chest_normal = love.graphics.newImage("gfx/chest_normal.png") + machine = love.graphics.newImage("gfx/machine.png") + machine_normal = love.graphics.newImage("gfx/machine_normal.png") + machine_glow = love.graphics.newImage("gfx/machine_glow.png") + machine2 = love.graphics.newImage("gfx/machine2.png") + machine2_normal = love.graphics.newImage("gfx/machine2_normal.png") + machine2_glow = love.graphics.newImage("gfx/machine2_glow.png") + blopp = love.graphics.newImage("gfx/blopp.png") + tile = love.graphics.newImage("gfx/tile.png") + tile_normal = love.graphics.newImage("gfx/tile_normal.png") + tile_glow = love.graphics.newImage("gfx/tile_glow.png") + refraction_normal = love.graphics.newImage("gfx/refraction_normal.png") + water = love.graphics.newImage("gfx/water.png") + led = love.graphics.newImage("gfx/led.png") + led2 = love.graphics.newImage("gfx/led2.png") + led3 = love.graphics.newImage("gfx/led3.png") + led_normal = love.graphics.newImage("gfx/led_normal.png") + led_glow = love.graphics.newImage("gfx/led_glow.png") + led_glow2 = love.graphics.newImage("gfx/led_glow2.png") + led_glow3 = love.graphics.newImage("gfx/led_glow3.png") + ape = love.graphics.newImage("gfx/ape.png") + ape_normal = love.graphics.newImage("gfx/ape_normal.png") + ape_glow = love.graphics.newImage("gfx/ape_glow.png") + imgLight = love.graphics.newImage("gfx/light.png") + + -- materials + material = {} + + local files = love.filesystem.getDirectoryItems("gfx/sphere") + for i, file in ipairs(files) do + material[i] = love.graphics.newImage("gfx/sphere/" .. file) + end + + -- light world + lightRange = 400 + lightSmooth = 1.0 + lightWorld = love.light.newWorld() + lightWorld.setAmbientColor(15, 15, 31) + lightWorld.setRefractionStrength(16.0) + lightWorld.setReflectionVisibility(0.75) + mouseLight = lightWorld.newLight(0, 0, 255, 191, 127, lightRange) + mouseLight.setGlowStrength(0.3) + mouseLight.setSmooth(lightSmooth) + mouseLight.z = 63 + lightDirection = 0.0 + colorAberration = 0.0 + + -- init physic world + initScene() + + helpOn = false + physicOn = false + lightOn = true + gravityOn = 1 + shadowBlur = 2.0 + bloomOn = 0.25 + textureOn = true + normalOn = false + glowBlur = 1.0 + effectOn = 0.0 + + offsetX = 0.0 + offsetY = 0.0 + offsetOldX = 0.0 + offsetOldY = 0.0 + offsetChanged = false + + tileX = 0 + tileY = 0 +end + +function love.update(dt) + love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")") + mouseLight.setPosition(love.mouse.getX(), love.mouse.getY(), 16.0 + (math.sin(lightDirection) + 1.0) * 64.0) + mx = love.mouse.getX() + my = love.mouse.getY() + lightDirection = lightDirection + dt + colorAberration = math.max(0.0, colorAberration - dt * 10.0) + + if love.keyboard.isDown("w") then + for i = 1, phyCnt do + if phyBody[i] then + phyBody[i]:applyForce(0, -2000) + end + end + elseif love.keyboard.isDown("s") then + for i = 1, phyCnt do + if phyBody[i] then + phyBody[i]:applyForce(0, 2000) + end + end + end + + if love.keyboard.isDown("a") then + for i = 1, phyCnt do + if phyBody[i] then + phyBody[i]:applyForce(-2000, 0) + end + end + elseif love.keyboard.isDown("d") then + for i = 1, phyCnt do + if phyBody[i] then + phyBody[i]:applyForce(2000, 0) + end + end + end + + if love.keyboard.isDown("up") then + offsetY = offsetY + dt * 200 + elseif love.keyboard.isDown("down") then + offsetY = offsetY - dt * 200 + end + + if love.keyboard.isDown("left") then + offsetX = offsetX + dt * 200 + elseif love.keyboard.isDown("right") then + offsetX = offsetX - dt * 200 + end + + if offsetX ~= offsetOldX or offsetY ~= offsetOldY then + offsetChanged = true + for i = 2, lightWorld.getLightCount() do + lightWorld.setLightPosition(i, lightWorld.getLightX(i) + (offsetX - offsetOldX), lightWorld.getLightY(i) + (offsetY - offsetOldY)) + end + else + offsetChanged = false + end + + for i = 1, lightWorld.getLightCount() do + lightWorld.setLightDirection(i, lightDirection) + end + + tileX = tileX + dt * 32.0 + tileY = tileY + dt * 8.0 + + for i = 1, phyCnt do + if phyBody[i] and (phyBody[i]:isAwake() or offsetChanged) then + if offsetChanged then + phyBody[i]:setX(phyBody[i]:getX() + (offsetX - offsetOldX)) + phyBody[i]:setY(phyBody[i]:getY() + (offsetY - offsetOldY)) + end + if phyLight[i].getType() == "polygon" then + phyLight[i].setPoints(phyBody[i]:getWorldPoints(phyShape[i]:getPoints())) + elseif phyLight[i].getType() == "circle" then + phyLight[i].setPosition(phyBody[i]:getX(), phyBody[i]:getY()) + elseif phyLight[i].getType() == "image" then + phyLight[i].setPosition(phyBody[i]:getX(), phyBody[i]:getY()) + elseif phyLight[i].getType() == "refraction" then + --phyLight[i].setPosition(phyBody[i]:getX(), phyBody[i]:getY()) + end + end + if phyLight[i].getType() == "refraction" then + --if math.mod(i, 2) == 0 then + phyLight[i].setNormalTileOffset(tileX, tileY) + --end + if offsetChanged then + phyLight[i].setPosition(phyLight[i].getX() + (offsetX - offsetOldX), phyLight[i].getY() + (offsetY - offsetOldY)) + end + end + end + + if physicOn then + physicWorld:update(dt) + end + + offsetOldX = offsetX + offsetOldY = offsetY +end + +function love.draw() + -- update lightmap (don't need deltatime) + if lightOn then + lightWorld.update() + end + + -- set shader buffer + if bloomOn then + love.postshader.setBuffer("render") + end + + love.graphics.setBlendMode("alpha") + if normalOn then + love.graphics.setColor(127, 127, 255) + love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + else + love.graphics.setColor(255, 255, 255) + if textureOn then + love.graphics.draw(imgFloor, quadScreen, offsetX % 32 - 32, offsetY % 24 - 24) + else + love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + end + end + + for i = 1, phyCnt do + if phyLight[i].getType() == "refraction" then + if not normalOn then + --if math.mod(i, 2) == 0 then + love.graphics.setBlendMode("alpha") + love.graphics.setColor(255, 255, 255, 191) + love.graphics.draw(water, phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy) + --else + --love.graphics.setBlendMode("multiplicative") + --math.randomseed(i) + --love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + --love.graphics.rectangle("fill", phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy, 128, 128) + --end + end + end + end + + -- draw lightmap shadows + if lightOn and not normalOn then + lightWorld.drawShadow() + end + + for i = 1, phyCnt do + math.randomseed(i) + love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + if phyLight[i].getType() == "polygon" then + love.graphics.polygon("fill", phyLight[i].getPoints()) + elseif phyLight[i].getType() == "circle" then + love.graphics.circle("fill", phyLight[i].getX(), phyLight[i].getY(), phyLight[i].getRadius()) + end + end + + -- draw lightmap shine + if lightOn and not normalOn then + lightWorld.drawShine() + end + + love.graphics.setBlendMode("alpha") + for i = 1, phyCnt do + if phyLight[i].getType() == "image" then + if normalOn and phyLight[i].normal then + love.graphics.setColor(255, 255, 255) + love.graphics.draw(phyLight[i].normal, phyLight[i].x - phyLight[i].nx, phyLight[i].y - phyLight[i].ny) + elseif not phyLight[i].material then + math.randomseed(i) + love.graphics.setColor(math.random(127, 255), math.random(127, 255), math.random(127, 255)) + love.graphics.draw(phyLight[i].img, phyLight[i].x - phyLight[i].ix, phyLight[i].y - phyLight[i].iy) + end + end + end + + if not normalOn then + lightWorld.drawMaterial() + end + + -- draw pixel shadow + if lightOn and not normalOn then + lightWorld.drawPixelShadow() + end + + -- draw glow + if lightOn and not normalOn then + lightWorld.drawGlow() + end + + -- draw reflection + lightWorld.drawReflection() + + -- draw refraction + lightWorld.drawRefraction() + + love.graphics.draw(imgLight, mx - 5, (my - 5) - (16.0 + (math.sin(lightDirection) + 1.0) * 64.0)) + + -- draw help + if helpOn then + love.graphics.setBlendMode("alpha") + love.graphics.setColor(0, 0, 0, 191) + love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), 44) + love.graphics.rectangle("fill", 0, love.graphics.getHeight() - 68, 240, 68) + love.graphics.rectangle("fill", love.graphics.getWidth() - 244, love.graphics.getHeight() - 84, 244, 84) + love.graphics.setColor(0, 255, 0) + love.graphics.print("F1: Help (on)", 4 + 152 * 0, 4) + if physicOn then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F2: Physic (on)", 4 + 152 * 1, 4) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F2: Physic (off)", 4 + 152 * 1, 4) + end + if lightOn then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F3: Light (on)", 4 + 152 * 2, 4) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F3: Light (off)", 4 + 152 * 2, 4) + end + if gravityOn == 1.0 then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F4: Gravity (on)", 4 + 152 * 3, 4) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F4: Gravity (off)", 4 + 152 * 3, 4) + end + if shadowBlur >= 1.0 then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F5: Shadowblur (" .. shadowBlur .. ")", 4 + 152 * 4, 4) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F5: Shadowblur (off)", 4 + 152 * 4, 4) + end + if bloomOn > 0.0 then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F6: Bloom (" .. (bloomOn * 4) .. ")", 4 + 152 * 0, 4 + 20 * 1) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F6: Bloom (off)", 4 + 152 * 0, 4 + 20 * 1) + end + if textureOn then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F7: Texture (on)", 4 + 152 * 1, 4 + 20 * 1) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F7: Texture (off)", 4 + 152 * 1, 4 + 20 * 1) + end + if normalOn then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F8: Normal (on)", 4 + 152 * 2, 4 + 20 * 1) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F8: Normal (off)", 4 + 152 * 2, 4 + 20 * 1) + end + if glowBlur >= 1.0 then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F9: Glow Blur (" .. glowBlur .. ")", 4 + 152 * 3, 4 + 20 * 1) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F9: Glow Blur (off)", 4 + 152 * 3, 4 + 20 * 1) + end + if effectOn >= 1.0 then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F10: Effects (" .. effectOn .. ")", 4 + 152 * 4, 4 + 20 * 1) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F10: Effects (off)", 4 + 152 * 4, 4 + 20 * 1) + end + love.graphics.setColor(255, 0, 255) + love.graphics.print("F11: Clear obj.", 4 + 152 * 4, 4 + 20 * 2) + love.graphics.print("F12: Clear lights", 4 + 152 * 4, 4 + 20 * 3) + love.graphics.setColor(0, 127, 255) + love.graphics.print("WASD Keys: Move objects", 4, love.graphics.getHeight() - 20 * 3) + love.graphics.print("Arrow Keys: Move map", 4, love.graphics.getHeight() - 20 * 2) + love.graphics.print("0-9 Keys: Add object", 4, love.graphics.getHeight() - 20 * 1) + love.graphics.setColor(255, 127, 0) + love.graphics.print("M.left: Add cube", love.graphics.getWidth() - 240, love.graphics.getHeight() - 20 * 4) + love.graphics.print("M.middle: Add light", love.graphics.getWidth() - 240, love.graphics.getHeight() - 20 * 3) + love.graphics.print("M.right: Add circle", love.graphics.getWidth() - 240, love.graphics.getHeight() - 20 * 2) + love.graphics.print("M.scroll: Change smooth", love.graphics.getWidth() - 240, love.graphics.getHeight() - 20 * 1) + love.graphics.setColor(255, 127, 0) + else + love.graphics.setColor(255, 255, 255, 191) + love.graphics.print("F1: Help", 4, 4) + end + + -- draw shader + if colorAberration > 0.0 then + -- vert / horz blur + love.postshader.addEffect("blur", 2.0, 2.0) + love.postshader.addEffect("chromatic", math.sin(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * colorAberration, math.sin(lightDirection * 10.0) * -colorAberration, math.sin(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * -colorAberration) + end + + if bloomOn > 0.0 then + -- blur, strength + love.postshader.addEffect("bloom", 2.0, bloomOn) + end + + if effectOn == 1.0 then + love.postshader.addEffect("4colors", {15, 56, 15}, {48, 98, 48}, {139, 172, 15}, {155, 188, 15}) + --love.postshader.addEffect("4colors", {108, 108, 78}, {142, 139, 87}, {195, 196, 165}, {227, 230, 201}) + elseif effectOn == 2.0 then + love.postshader.addEffect("monochrom") + elseif effectOn == 3.0 then + love.postshader.addEffect("scanlines") + elseif effectOn == 4.0 then + love.postshader.addEffect("tiltshift", 4.0) + end + + love.postshader.draw() +end + +function love.mousepressed(x, y, c) + if c == "m" then + -- add light + local r = lightWorld.getLightCount() % 3 + local light + + if r == 0 then + light = lightWorld.newLight(x, y, 31, 127, 63, lightRange) + elseif r == 1 then + light = lightWorld.newLight(x, y, 127, 63, 31, lightRange) + else + light = lightWorld.newLight(x, y, 31, 63, 127, lightRange) + end + light.setSmooth(lightSmooth) + light.setGlowStrength(0.3) + elseif c == "l" then + -- add rectangle + math.randomseed(love.timer.getTime()) + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newPolygon() + phyBody[phyCnt] = love.physics.newBody(physicWorld, x, y, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, math.random(32, 64), math.random(32, 64)) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif c == "r" then + -- add circle + math.randomseed(love.timer.getTime()) + cRadius = math.random(8, 32) + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newCircle(x, y, cRadius) + phyBody[phyCnt] = love.physics.newBody(physicWorld, x, y, "dynamic") + phyShape[phyCnt] = love.physics.newCircleShape(0, 0, cRadius) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif c == "wu" then + if lightSmooth < 4.0 then + lightSmooth = lightSmooth * 1.1 + mouseLight.setSmooth(lightSmooth) + end + elseif c == "wd" then + if lightSmooth > 0.5 then + lightSmooth = lightSmooth / 1.1 + mouseLight.setSmooth(lightSmooth) + end + end +end + +function love.keypressed(k, u) + -- debug options + if k == "f1" then + helpOn = not helpOn + elseif k == "f2" then + physicOn = not physicOn + elseif k == "f3" then + lightOn = not lightOn + elseif k == "f4" then + gravityOn = 1 - gravityOn + physicWorld:setGravity(0, gravityOn * 9.81 * 64) + elseif k == "f5" then + shadowBlur = math.max(1, shadowBlur * 2.0) + if shadowBlur > 8.0 then + shadowBlur = 0.0 + end + lightWorld.setBlur(shadowBlur) + elseif k == "f6" or k == "b" then + bloomOn = math.max(0.25, bloomOn * 2.0) + if bloomOn > 1.0 then + bloomOn = 0.0 + end + elseif k == "f7" then + textureOn = not textureOn + elseif k == "f8" then + normalOn = not normalOn + elseif k == "f9" then + glowBlur = glowBlur + 1.0 + if glowBlur > 8.0 then + glowBlur = 0.0 + end + lightWorld.setGlowStrength(glowBlur) + elseif k == "f10" then + effectOn = effectOn + 1.0 + if effectOn > 4.0 then + effectOn = 0.0 + end + elseif k == "f11" then + physicWorld:destroy() + lightWorld.clearBodys() + initScene() + elseif k == "f12" then + lightWorld.clearLights() + mouseLight = lightWorld.newLight(0, 0, 255, 191, 127, lightRange) + mouseLight.setGlowStrength(0.3) + mouseLight.setSmooth(lightSmooth) + elseif k == "1" then + -- add image + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(circle, mx, my) + phyLight[phyCnt].setNormalMap(circle_normal) + phyLight[phyCnt].setShadowType("circle", 16) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 32) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif k == "2" then + local r = lightWorld.getBodyCount() % 2 + if r == 0 then + -- add image + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(cone, mx, my, 24, 12, 12, 16) + phyLight[phyCnt].setNormalMap(cone_normal) + phyLight[phyCnt].setShadowType("circle", 12, 0, -8) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 24, 32) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif r == 1 then + -- add image + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(chest, mx, my, 32, 24, 16, 0) + phyLight[phyCnt].setNormalMap(chest_normal) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 24) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + end + elseif k == "3" then + -- add image + local r = lightWorld.getBodyCount() % #material + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(ape, mx, my, 160, 128, 80, 64) + phyLight[phyCnt].setNormalMap(ape_normal) + if r == 3 then + phyLight[phyCnt].setGlowMap(ape_glow) + end + phyLight[phyCnt].setMaterial(material[r + 1]) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 24) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + phyLight[phyCnt].setShadowType("image", 0, -16, 0.0) + elseif k == "4" then + -- add glow image + local r = lightWorld.getBodyCount() % 5 + if r == 0 then + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(machine, mx, my, 32, 24, 16, 0) + phyLight[phyCnt].setNormalMap(machine_normal) + phyLight[phyCnt].setGlowMap(machine_glow) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 24) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif r == 1 then + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(machine2, mx, my, 24, 12, 12, -4) + phyLight[phyCnt].setNormalMap(machine2_normal) + phyLight[phyCnt].setGlowMap(machine2_glow) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 24, 32) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif r == 2 then + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(led, mx, my, 32, 6, 16, -8) + phyLight[phyCnt].setNormalMap(led_normal) + phyLight[phyCnt].setGlowMap(led_glow) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 6) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif r == 3 then + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(led2, mx, my, 32, 6, 16, -8) + phyLight[phyCnt].setNormalMap(led_normal) + phyLight[phyCnt].setGlowMap(led_glow2) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 6) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif r == 4 then + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(led3, mx, my, 32, 6, 16, -8) + phyLight[phyCnt].setNormalMap(led_normal) + phyLight[phyCnt].setGlowMap(led_glow3) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 6) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + end + elseif k == "5" then + -- add image + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(cone_large, mx, my, 24, 128, 12, 64) + phyLight[phyCnt].setNormalMap(cone_large_normal) + phyLight[phyCnt].setShadowType("image", 0, -6, 0.0) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 24, 32) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif k == "6" then + -- add image + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(blopp, mx, my, 42, 16, 21, 0) + phyLight[phyCnt].generateNormalMapGradient("gradient", "gradient") + phyLight[phyCnt].setAlpha(0.5) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 42, 29) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif k == "7" then + -- add image + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(tile, mx, my) + phyLight[phyCnt].setHeightMap(tile_normal, 2.0) + phyLight[phyCnt].setGlowMap(tile_glow) + phyLight[phyCnt].setShadow(false) + phyLight[phyCnt].reflective = false + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 64, 64) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif k == "8" then + -- add rectangle + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newPolygon() + phyLight[phyCnt].setAlpha(0.5) + phyLight[phyCnt].setGlowStrength(1.0) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + math.randomseed(love.timer.getTime()) + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, math.random(32, 64), math.random(32, 64)) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + math.randomseed(phyCnt) + phyLight[phyCnt].setGlowColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + math.randomseed(phyCnt) + phyLight[phyCnt].setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + elseif k == "9" then + -- add circle + math.randomseed(love.timer.getTime()) + cRadius = math.random(8, 32) + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newCircle(mx, my, cRadius) + phyLight[phyCnt].setAlpha(0.5) + phyLight[phyCnt].setGlowStrength(1.0) + math.randomseed(phyCnt) + phyLight[phyCnt].setGlowColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + math.randomseed(phyCnt) + phyLight[phyCnt].setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newCircleShape(0, 0, cRadius) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif k == "0" then + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newRefraction(refraction_normal, mx, my) + phyLight[phyCnt].setReflection(true) + elseif k == "l" then + -- add light + local r = lightWorld.getLightCount() % 3 + local light + + if r == 0 then + light = lightWorld.newLight(mx, my, 31, 127, 63, lightRange) + elseif r == 1 then + light = lightWorld.newLight(mx, my, 127, 63, 31, lightRange) + else + light = lightWorld.newLight(mx, my, 31, 63, 127, lightRange) + end + light.setSmooth(lightSmooth) + light.setGlowStrength(0.3) + math.randomseed(love.timer.getTime()) + light.setAngle(math.random(1, 5) * 0.1 * math.pi) + elseif k == "c" then + if colorAberration == 0.0 then + colorAberration = 3.0 + end + end +end \ No newline at end of file diff --git a/example.lua b/examples/short.lua similarity index 97% rename from example.lua rename to examples/short.lua index 5dc172d..251e0b1 100644 --- a/example.lua +++ b/examples/short.lua @@ -1,5 +1,6 @@ -require "postshader" -require "light" +-- Example: Short Example +require "lib/postshader" +require "lib/light" function love.load() -- load images diff --git a/gfx/love-big-ball.png b/gfx/love-big-ball.png new file mode 100644 index 0000000..8212fd3 Binary files /dev/null and b/gfx/love-big-ball.png differ diff --git a/light.lua b/lib/light.lua similarity index 55% rename from light.lua rename to lib/light.lua index e69beba..9f5d86f 100644 --- a/light.lua +++ b/lib/light.lua @@ -1,3 +1,27 @@ +--[[ +The MIT License (MIT) + +Copyright (c) 2014 Marcus Ihde + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +]] + LOVE_LIGHT_CURRENT = nil LOVE_LIGHT_CIRCLE = nil LOVE_LIGHT_POLY = nil @@ -16,16 +40,15 @@ LOVE_LIGHT_TRANSLATE_Y = 0 LOVE_LIGHT_TRANSLATE_X_OLD = 0 LOVE_LIGHT_TRANSLATE_Y_OLD = 0 LOVE_LIGHT_DIRECTION = 0 + love.light = {} -- light world function love.light.newWorld() local o = {} + o.lights = {} o.ambient = {0, 0, 0} - o.circle = {} - o.poly = {} - o.img = {} o.body = {} o.refraction = {} o.shadow = love.graphics.newCanvas() @@ -41,7 +64,6 @@ function love.light.newWorld() o.reflectionMap2 = love.graphics.newCanvas() o.normalInvert = false o.glowBlur = 1.0 - o.isGlowBlur = false o.glowTimer = 0.0 o.glowDown = false o.refractionStrength = 8.0 @@ -60,10 +82,21 @@ function love.light.newWorld() o.reflectionVisibility = 1.0 o.changed = true o.blur = 2.0 + o.optionShadows = true + o.optionPixelShadows = true + o.optionGlow = true + o.optionRefraction = true + o.optionReflection = true + o.isShadows = false + o.isLight = false + o.isPixelShadows = false + o.isGlow = false + o.isRefraction = false + o.isReflection = false + -- update o.update = function() LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() - love.graphics.setShader(o.shader) if LOVE_LIGHT_TRANSLATE_X ~= LOVE_LIGHT_TRANSLATE_X_OLD or LOVE_LIGHT_TRANSLATE_Y ~= LOVE_LIGHT_TRANSLATE_Y_OLD then LOVE_LIGHT_TRANSLATE_X_OLD = LOVE_LIGHT_TRANSLATE_X @@ -74,251 +107,215 @@ function love.light.newWorld() love.graphics.setColor(255, 255, 255) love.graphics.setBlendMode("alpha") - local lightsOnScreen = 0 - LOVE_LIGHT_CIRCLE = o.circle - LOVE_LIGHT_POLY = o.poly - LOVE_LIGHT_IMAGE = o.img - LOVE_LIGHT_BODY = o.body - for i = 1, #o.lights do - if o.lights[i].changed or o.changed then - if o.lights[i].x + o.lights[i].range > LOVE_LIGHT_TRANSLATE_X and o.lights[i].x - o.lights[i].range < love.graphics.getWidth() + LOVE_LIGHT_TRANSLATE_X - and o.lights[i].y + o.lights[i].range > LOVE_LIGHT_TRANSLATE_Y and o.lights[i].y - o.lights[i].range < love.graphics.getHeight() + LOVE_LIGHT_TRANSLATE_Y - then - local lightposrange = {o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, o.lights[i].range} - LOVE_LIGHT_CURRENT = o.lights[i] - LOVE_LIGHT_DIRECTION = LOVE_LIGHT_DIRECTION + 0.002 - o.shader:send("lightPosition", {o.lights[i].x - LOVE_LIGHT_TRANSLATE_X, love.graphics.getHeight() - (o.lights[i].y - LOVE_LIGHT_TRANSLATE_Y), o.lights[i].z}) - o.shader:send("lightRange", o.lights[i].range) - o.shader:send("lightColor", {o.lights[i].red / 255.0, o.lights[i].green / 255.0, o.lights[i].blue / 255.0}) - o.shader:send("lightSmooth", o.lights[i].smooth) - o.shader:send("lightGlow", {1.0 - o.lights[i].glowSize, o.lights[i].glowStrength}) - o.shader:send("lightAngle", math.pi - o.lights[i].angle / 2.0) - o.shader:send("lightDirection", o.lights[i].direction) + if o.optionShadows and (o.isShadows or o.isLight) then + love.graphics.setShader(o.shader) - love.graphics.setCanvas(o.lights[i].shadow) - love.graphics.clear() + local lightsOnScreen = 0 + LOVE_LIGHT_BODY = o.body + for i = 1, #o.lights do + if o.lights[i].changed or o.changed then + if o.lights[i].x + o.lights[i].range > LOVE_LIGHT_TRANSLATE_X and o.lights[i].x - o.lights[i].range < love.graphics.getWidth() + LOVE_LIGHT_TRANSLATE_X + and o.lights[i].y + o.lights[i].range > LOVE_LIGHT_TRANSLATE_Y and o.lights[i].y - o.lights[i].range < love.graphics.getHeight() + LOVE_LIGHT_TRANSLATE_Y + then + local lightposrange = {o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, o.lights[i].range} + LOVE_LIGHT_CURRENT = o.lights[i] + LOVE_LIGHT_DIRECTION = LOVE_LIGHT_DIRECTION + 0.002 + o.shader:send("lightPosition", {o.lights[i].x - LOVE_LIGHT_TRANSLATE_X, love.graphics.getHeight() - (o.lights[i].y - LOVE_LIGHT_TRANSLATE_Y), o.lights[i].z}) + o.shader:send("lightRange", o.lights[i].range) + o.shader:send("lightColor", {o.lights[i].red / 255.0, o.lights[i].green / 255.0, o.lights[i].blue / 255.0}) + o.shader:send("lightSmooth", o.lights[i].smooth) + o.shader:send("lightGlow", {1.0 - o.lights[i].glowSize, o.lights[i].glowStrength}) + o.shader:send("lightAngle", math.pi - o.lights[i].angle / 2.0) + o.shader:send("lightDirection", o.lights[i].direction) - -- calculate shadows - LOVE_LIGHT_SHADOW_GEOMETRY = calculateShadows(LOVE_LIGHT_CURRENT, LOVE_LIGHT_BODY) + love.graphics.setCanvas(o.lights[i].shadow) + love.graphics.clear() - -- draw shadow - love.graphics.setInvertedStencil(shadowStencil) - love.graphics.setBlendMode("additive") - love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) + -- calculate shadows + LOVE_LIGHT_SHADOW_GEOMETRY = calculateShadows(LOVE_LIGHT_CURRENT, LOVE_LIGHT_BODY) - -- draw color shadows - love.graphics.setBlendMode("multiplicative") - love.graphics.setShader() - for k = 1,#LOVE_LIGHT_SHADOW_GEOMETRY do - if LOVE_LIGHT_SHADOW_GEOMETRY[k].alpha < 1.0 then - love.graphics.setColor( - LOVE_LIGHT_SHADOW_GEOMETRY[k].red * (1.0 - LOVE_LIGHT_SHADOW_GEOMETRY[k].alpha), - LOVE_LIGHT_SHADOW_GEOMETRY[k].green * (1.0 - LOVE_LIGHT_SHADOW_GEOMETRY[k].alpha), - LOVE_LIGHT_SHADOW_GEOMETRY[k].blue * (1.0 - LOVE_LIGHT_SHADOW_GEOMETRY[k].alpha) - ) - love.graphics.polygon("fill", unpack(LOVE_LIGHT_SHADOW_GEOMETRY[k])) - end - end + -- draw shadow + love.graphics.setInvertedStencil(shadowStencil) + love.graphics.setBlendMode("additive") + love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) - for k = 1, #LOVE_LIGHT_BODY do - if LOVE_LIGHT_BODY[k].alpha < 1.0 then - love.graphics.setBlendMode("multiplicative") - love.graphics.setColor(LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue) - if LOVE_LIGHT_BODY[k].shadowType == "circle" then - love.graphics.circle("fill", LOVE_LIGHT_BODY[k].x - LOVE_LIGHT_BODY[k].ox, LOVE_LIGHT_BODY[k].y - LOVE_LIGHT_BODY[k].oy, LOVE_LIGHT_BODY[k].radius) - elseif LOVE_LIGHT_BODY[k].shadowType == "rectangle" then - love.graphics.rectangle("fill", LOVE_LIGHT_BODY[k].x - LOVE_LIGHT_BODY[k].ox, LOVE_LIGHT_BODY[k].y - LOVE_LIGHT_BODY[k].oy, LOVE_LIGHT_BODY[k].width, LOVE_LIGHT_BODY[k].height) - elseif LOVE_LIGHT_BODY[k].shadowType == "polygon" then - love.graphics.polygon("fill", unpack(LOVE_LIGHT_BODY[k].data)) + -- draw color shadows + love.graphics.setBlendMode("multiplicative") + love.graphics.setShader() + for k = 1,#LOVE_LIGHT_SHADOW_GEOMETRY do + if LOVE_LIGHT_SHADOW_GEOMETRY[k].alpha < 1.0 then + love.graphics.setColor( + LOVE_LIGHT_SHADOW_GEOMETRY[k].red * (1.0 - LOVE_LIGHT_SHADOW_GEOMETRY[k].alpha), + LOVE_LIGHT_SHADOW_GEOMETRY[k].green * (1.0 - LOVE_LIGHT_SHADOW_GEOMETRY[k].alpha), + LOVE_LIGHT_SHADOW_GEOMETRY[k].blue * (1.0 - LOVE_LIGHT_SHADOW_GEOMETRY[k].alpha) + ) + love.graphics.polygon("fill", unpack(LOVE_LIGHT_SHADOW_GEOMETRY[k])) end end - if LOVE_LIGHT_BODY[k].shadowType == "image" and LOVE_LIGHT_BODY[k].img then - love.graphics.setBlendMode("alpha") - local length = 1.0 - local shadowRotation = math.atan2((LOVE_LIGHT_BODY[k].x) - o.lights[i].x, (LOVE_LIGHT_BODY[k].y + LOVE_LIGHT_BODY[k].oy) - o.lights[i].y) - --local alpha = math.abs(math.cos(shadowRotation)) - LOVE_LIGHT_BODY[k].shadowVert = { - {math.sin(shadowRotation) * LOVE_LIGHT_BODY[k].imgHeight * length, (length * math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].imgHeight + (math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].shadowY, 0, 0, LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue, LOVE_LIGHT_BODY[k].alpha * LOVE_LIGHT_BODY[k].fadeStrength * 255}, - {LOVE_LIGHT_BODY[k].imgWidth + math.sin(shadowRotation) * LOVE_LIGHT_BODY[k].imgHeight * length, (length * math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].imgHeight + (math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].shadowY, 1, 0, LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue, LOVE_LIGHT_BODY[k].alpha * LOVE_LIGHT_BODY[k].fadeStrength * 255}, - {LOVE_LIGHT_BODY[k].imgWidth, LOVE_LIGHT_BODY[k].imgHeight + (math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].shadowY, 1, 1, LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue, LOVE_LIGHT_BODY[k].alpha * 255}, - {0, LOVE_LIGHT_BODY[k].imgHeight + (math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].shadowY, 0, 1, LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue, LOVE_LIGHT_BODY[k].alpha * 255} - } + for k = 1, #LOVE_LIGHT_BODY do + if LOVE_LIGHT_BODY[k].alpha < 1.0 then + love.graphics.setBlendMode("multiplicative") + love.graphics.setColor(LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue) + if LOVE_LIGHT_BODY[k].shadowType == "circle" then + love.graphics.circle("fill", LOVE_LIGHT_BODY[k].x - LOVE_LIGHT_BODY[k].ox, LOVE_LIGHT_BODY[k].y - LOVE_LIGHT_BODY[k].oy, LOVE_LIGHT_BODY[k].radius) + elseif LOVE_LIGHT_BODY[k].shadowType == "rectangle" then + love.graphics.rectangle("fill", LOVE_LIGHT_BODY[k].x - LOVE_LIGHT_BODY[k].ox, LOVE_LIGHT_BODY[k].y - LOVE_LIGHT_BODY[k].oy, LOVE_LIGHT_BODY[k].width, LOVE_LIGHT_BODY[k].height) + elseif LOVE_LIGHT_BODY[k].shadowType == "polygon" then + love.graphics.polygon("fill", unpack(LOVE_LIGHT_BODY[k].data)) + end + end - LOVE_LIGHT_BODY[k].shadowMesh:setVertices(LOVE_LIGHT_BODY[k].shadowVert) - love.graphics.draw(LOVE_LIGHT_BODY[k].shadowMesh, LOVE_LIGHT_BODY[k].x - LOVE_LIGHT_BODY[k].ox + LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_BODY[k].y - LOVE_LIGHT_BODY[k].oy + LOVE_LIGHT_TRANSLATE_Y) + if LOVE_LIGHT_BODY[k].shadowType == "image" and LOVE_LIGHT_BODY[k].img then + love.graphics.setBlendMode("alpha") + local length = 1.0 + local shadowRotation = math.atan2((LOVE_LIGHT_BODY[k].x) - o.lights[i].x, (LOVE_LIGHT_BODY[k].y + LOVE_LIGHT_BODY[k].oy) - o.lights[i].y) + --local alpha = math.abs(math.cos(shadowRotation)) + + LOVE_LIGHT_BODY[k].shadowVert = { + {math.sin(shadowRotation) * LOVE_LIGHT_BODY[k].imgHeight * length, (length * math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].imgHeight + (math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].shadowY, 0, 0, LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue, LOVE_LIGHT_BODY[k].alpha * LOVE_LIGHT_BODY[k].fadeStrength * 255}, + {LOVE_LIGHT_BODY[k].imgWidth + math.sin(shadowRotation) * LOVE_LIGHT_BODY[k].imgHeight * length, (length * math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].imgHeight + (math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].shadowY, 1, 0, LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue, LOVE_LIGHT_BODY[k].alpha * LOVE_LIGHT_BODY[k].fadeStrength * 255}, + {LOVE_LIGHT_BODY[k].imgWidth, LOVE_LIGHT_BODY[k].imgHeight + (math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].shadowY, 1, 1, LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue, LOVE_LIGHT_BODY[k].alpha * 255}, + {0, LOVE_LIGHT_BODY[k].imgHeight + (math.cos(shadowRotation) + 1.0) * LOVE_LIGHT_BODY[k].shadowY, 0, 1, LOVE_LIGHT_BODY[k].red, LOVE_LIGHT_BODY[k].green, LOVE_LIGHT_BODY[k].blue, LOVE_LIGHT_BODY[k].alpha * 255} + } + + LOVE_LIGHT_BODY[k].shadowMesh:setVertices(LOVE_LIGHT_BODY[k].shadowVert) + love.graphics.draw(LOVE_LIGHT_BODY[k].shadowMesh, LOVE_LIGHT_BODY[k].x - LOVE_LIGHT_BODY[k].ox + LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_BODY[k].y - LOVE_LIGHT_BODY[k].oy + LOVE_LIGHT_TRANSLATE_Y) + end end + + love.graphics.setShader(o.shader) + + -- draw shine + love.graphics.setCanvas(o.lights[i].shine) + o.lights[i].shine:clear(255, 255, 255) + love.graphics.setBlendMode("alpha") + love.graphics.setStencil(polyStencil) + love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) + + lightsOnScreen = lightsOnScreen + 1 + + o.lights[i].visible = true + else + o.lights[i].visible = false end - love.graphics.setShader(o.shader) - - -- draw shine - love.graphics.setCanvas(o.lights[i].shine) - o.lights[i].shine:clear(255, 255, 255) - love.graphics.setBlendMode("alpha") - love.graphics.setStencil(polyStencil) - love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) - - lightsOnScreen = lightsOnScreen + 1 - - o.lights[i].visible = true - else - o.lights[i].visible = false + o.lights[i].changed = o.changed end - - o.lights[i].changed = o.changed end - end - -- update shadow - love.graphics.setShader() - love.graphics.setCanvas(o.shadow) - love.graphics.setStencil() - love.graphics.setColor(unpack(o.ambient)) - love.graphics.setBlendMode("alpha") - love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("additive") - for i = 1, #o.lights do - if o.lights[i].visible then - love.graphics.draw(o.lights[i].shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - end - end - o.isShadowBlur = false - - -- update shine - love.graphics.setCanvas(o.shine) - love.graphics.setColor(unpack(o.ambient)) - love.graphics.setBlendMode("alpha") - love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("additive") - for i = 1, #o.lights do - if o.lights[i].visible then - love.graphics.draw(o.lights[i].shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - end - end - - -- update pixel shadow - love.graphics.setBlendMode("alpha") - - -- create normal map - o.normalMap:clear() - love.graphics.setShader() - love.graphics.setCanvas(o.normalMap) - for i = 1, #o.body do - if o.body[i].type == "image" and o.body[i].normal then - love.graphics.setColor(255, 255, 255) - love.graphics.draw(o.body[i].normal, o.body[i].x - o.body[i].nx + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].ny + LOVE_LIGHT_TRANSLATE_Y) - end - end - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("alpha") - - o.pixelShadow2:clear() - love.graphics.setCanvas(o.pixelShadow2) - love.graphics.setBlendMode("additive") - love.graphics.setShader(o.shader2) - - for i = 1, #o.lights do - if o.lights[i].visible then - if normalInvert then - o.normalInvertShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()}) - o.normalInvertShader:send('lightColor', {o.lights[i].red / 255.0, o.lights[i].green / 255.0, o.lights[i].blue / 255.0}) - o.normalInvertShader:send('lightPosition',{o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, o.lights[i].z / 255.0}) - o.normalInvertShader:send('lightRange',{o.lights[i].range}) - o.normalInvertShader:send("lightSmooth", o.lights[i].smooth) - o.normalInvertShader:send("lightAngle", math.pi - o.lights[i].angle / 2.0) - o.normalInvertShader:send("lightDirection", o.lights[i].direction) - love.graphics.setShader(o.normalInvertShader) - else - o.normalShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()}) - o.normalShader:send('lightColor', {o.lights[i].red / 255.0, o.lights[i].green / 255.0, o.lights[i].blue / 255.0}) - o.normalShader:send('lightPosition',{o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, o.lights[i].z / 255.0}) - o.normalShader:send('lightRange',{o.lights[i].range}) - o.normalShader:send("lightSmooth", o.lights[i].smooth) - o.normalShader:send("lightAngle", math.pi - o.lights[i].angle / 2.0) - o.normalShader:send("lightDirection", o.lights[i].direction) - love.graphics.setShader(o.normalShader) + -- update shadow + love.graphics.setShader() + love.graphics.setCanvas(o.shadow) + love.graphics.setStencil() + love.graphics.setColor(unpack(o.ambient)) + love.graphics.setBlendMode("alpha") + love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) + love.graphics.setColor(255, 255, 255) + love.graphics.setBlendMode("additive") + for i = 1, #o.lights do + if o.lights[i].visible then + love.graphics.draw(o.lights[i].shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + end + end + o.isShadowBlur = false + + -- update shine + love.graphics.setCanvas(o.shine) + love.graphics.setColor(unpack(o.ambient)) + love.graphics.setBlendMode("alpha") + love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + love.graphics.setColor(255, 255, 255) + love.graphics.setBlendMode("additive") + for i = 1, #o.lights do + if o.lights[i].visible then + love.graphics.draw(o.lights[i].shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) end - love.graphics.draw(o.normalMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) end end - love.graphics.setShader() - o.pixelShadow:clear(255, 255, 255) - love.graphics.setCanvas(o.pixelShadow) - love.graphics.setBlendMode("alpha") - love.graphics.draw(o.pixelShadow2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setBlendMode("additive") - love.graphics.setColor({o.ambient[1], o.ambient[2], o.ambient[3]}) - love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) - love.graphics.setBlendMode("alpha") + if o.optionPixelShadows and o.isPixelShadows then + -- update pixel shadow + love.graphics.setBlendMode("alpha") - -- create glow map - o.glowMap:clear(0, 0, 0) - love.graphics.setCanvas(o.glowMap) - - if o.glowDown then - o.glowTimer = math.max(0.0, o.glowTimer - love.timer.getDelta()) - if o.glowTimer == 0.0 then - o.glowDown = not o.glowDown - end - else - o.glowTimer = math.min(o.glowTimer + love.timer.getDelta(), 1.0) - if o.glowTimer == 1.0 then - o.glowDown = not o.glowDown - end - end - - for i = 1, #o.body do - if o.body[i].glowStrength > 0.0 then - love.graphics.setColor(o.body[i].glowRed * o.body[i].glowStrength, o.body[i].glowGreen * o.body[i].glowStrength, o.body[i].glowBlue * o.body[i].glowStrength) - else - love.graphics.setColor(0, 0, 0) - end - - if o.body[i].type == "circle" then - love.graphics.circle("fill", o.body[i].x, o.body[i].y, o.body[i].radius) - elseif o.body[i].type == "rectangle" then - love.graphics.rectangle("fill", o.body[i].x, o.body[i].y, o.body[i].width, o.body[i].height) - elseif o.body[i].type == "polygon" then - love.graphics.polygon("fill", unpack(o.body[i].data)) - elseif o.body[i].type == "image" and o.body[i].img then - if o.body[i].glowStrength > 0.0 and o.body[i].glow then - love.graphics.setShader(o.glowShader) - o.glowShader:send("glowImage", o.body[i].glow) - o.glowShader:send("glowTime", love.timer.getTime()) + -- create normal map + o.normalMap:clear() + love.graphics.setShader() + love.graphics.setCanvas(o.normalMap) + for i = 1, #o.body do + if o.body[i].type == "image" and o.body[i].normalMesh then love.graphics.setColor(255, 255, 255) - else - love.graphics.setShader() - love.graphics.setColor(0, 0, 0) - end - love.graphics.draw(o.body[i].img, o.body[i].x - o.body[i].ix + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].iy + LOVE_LIGHT_TRANSLATE_Y) - end - end - - love.graphics.setShader() - o.isGlowBlur = false - - -- create refraction map - o.refractionMap:clear() - love.graphics.setCanvas(o.refractionMap) - for i = 1, #o.body do - if o.body[i].refraction and o.body[i].normal then - love.graphics.setColor(255, 255, 255) - if o.body[i].tileX == 0.0 and o.body[i].tileY == 0.0 then - love.graphics.draw(normal, o.body[i].x - o.body[i].nx + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].ny + LOVE_LIGHT_TRANSLATE_Y) - else - o.body[i].normalMesh:setVertices(o.body[i].normalVert) love.graphics.draw(o.body[i].normalMesh, o.body[i].x - o.body[i].nx + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].ny + LOVE_LIGHT_TRANSLATE_Y) end end + love.graphics.setColor(255, 255, 255) + love.graphics.setBlendMode("alpha") + + o.pixelShadow2:clear() + love.graphics.setCanvas(o.pixelShadow2) + love.graphics.setBlendMode("additive") + love.graphics.setShader(o.shader2) + + for i = 1, #o.lights do + if o.lights[i].visible then + if o.normalInvert then + o.normalInvertShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()}) + o.normalInvertShader:send('lightColor', {o.lights[i].red / 255.0, o.lights[i].green / 255.0, o.lights[i].blue / 255.0}) + o.normalInvertShader:send('lightPosition',{o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, o.lights[i].z / 255.0}) + o.normalInvertShader:send('lightRange',{o.lights[i].range}) + o.normalInvertShader:send("lightSmooth", o.lights[i].smooth) + o.normalInvertShader:send("lightAngle", math.pi - o.lights[i].angle / 2.0) + o.normalInvertShader:send("lightDirection", o.lights[i].direction) + love.graphics.setShader(o.normalInvertShader) + else + o.normalShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()}) + o.normalShader:send('lightColor', {o.lights[i].red / 255.0, o.lights[i].green / 255.0, o.lights[i].blue / 255.0}) + o.normalShader:send('lightPosition',{o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, o.lights[i].z / 255.0}) + o.normalShader:send('lightRange',{o.lights[i].range}) + o.normalShader:send("lightSmooth", o.lights[i].smooth) + o.normalShader:send("lightAngle", math.pi - o.lights[i].angle / 2.0) + o.normalShader:send("lightDirection", o.lights[i].direction) + love.graphics.setShader(o.normalShader) + end + love.graphics.draw(o.normalMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + end + end + + love.graphics.setShader() + o.pixelShadow:clear(255, 255, 255) + love.graphics.setCanvas(o.pixelShadow) + love.graphics.setBlendMode("alpha") + love.graphics.draw(o.pixelShadow2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setBlendMode("additive") + love.graphics.setColor({o.ambient[1], o.ambient[2], o.ambient[3]}) + love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) + love.graphics.setBlendMode("alpha") end - - love.graphics.setColor(0, 0, 0) - for i = 1, #o.body do - if not o.body[i].refractive then + + if o.optionGlow and o.isGlow then + -- create glow map + o.glowMap:clear(0, 0, 0) + love.graphics.setCanvas(o.glowMap) + + if o.glowDown then + o.glowTimer = math.max(0.0, o.glowTimer - love.timer.getDelta()) + if o.glowTimer == 0.0 then + o.glowDown = not o.glowDown + end + else + o.glowTimer = math.min(o.glowTimer + love.timer.getDelta(), 1.0) + if o.glowTimer == 1.0 then + o.glowDown = not o.glowDown + end + end + + for i = 1, #o.body do + if o.body[i].glowStrength > 0.0 then + love.graphics.setColor(o.body[i].glowRed * o.body[i].glowStrength, o.body[i].glowGreen * o.body[i].glowStrength, o.body[i].glowBlue * o.body[i].glowStrength) + else + love.graphics.setColor(0, 0, 0) + end + if o.body[i].type == "circle" then love.graphics.circle("fill", o.body[i].x, o.body[i].y, o.body[i].radius) elseif o.body[i].type == "rectangle" then @@ -326,29 +323,74 @@ function love.light.newWorld() elseif o.body[i].type == "polygon" then love.graphics.polygon("fill", unpack(o.body[i].data)) elseif o.body[i].type == "image" and o.body[i].img then + if o.body[i].glowStrength > 0.0 and o.body[i].glow then + love.graphics.setShader(o.glowShader) + o.glowShader:send("glowImage", o.body[i].glow) + o.glowShader:send("glowTime", love.timer.getTime() * 0.5) + love.graphics.setColor(255, 255, 255) + else + love.graphics.setShader() + love.graphics.setColor(0, 0, 0) + end love.graphics.draw(o.body[i].img, o.body[i].x - o.body[i].ix + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].iy + LOVE_LIGHT_TRANSLATE_Y) end end end - -- create reflection map - if o.changed then - o.reflectionMap:clear(0, 0, 0) - love.graphics.setCanvas(o.reflectionMap) + if o.optionRefraction and o.isRefraction then + love.graphics.setShader() + + -- create refraction map + o.refractionMap:clear() + love.graphics.setCanvas(o.refractionMap) for i = 1, #o.body do - if o.body[i].reflection and o.body[i].normal then - love.graphics.setColor(255, 0, 0) - o.body[i].normalMesh:setVertices(o.body[i].normalVert) - love.graphics.draw(o.body[i].normalMesh, o.body[i].x - o.body[i].nx + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].ny + LOVE_LIGHT_TRANSLATE_Y) + if o.body[i].refraction and o.body[i].normal then + love.graphics.setColor(255, 255, 255) + if o.body[i].tileX == 0.0 and o.body[i].tileY == 0.0 then + love.graphics.draw(normal, o.body[i].x - o.body[i].nx + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].ny + LOVE_LIGHT_TRANSLATE_Y) + else + o.body[i].normalMesh:setVertices(o.body[i].normalVert) + love.graphics.draw(o.body[i].normalMesh, o.body[i].x - o.body[i].nx + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].ny + LOVE_LIGHT_TRANSLATE_Y) + end end end + + love.graphics.setColor(0, 0, 0) for i = 1, #o.body do - if o.body[i].reflective and o.body[i].img then - love.graphics.setColor(0, 255, 0) - love.graphics.draw(o.body[i].img, o.body[i].x - o.body[i].ix + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].iy + LOVE_LIGHT_TRANSLATE_Y) - elseif not o.body[i].reflection and o.body[i].img then - love.graphics.setColor(0, 0, 0) - love.graphics.draw(o.body[i].img, o.body[i].x - o.body[i].ix + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].iy + LOVE_LIGHT_TRANSLATE_Y) + if not o.body[i].refractive then + if o.body[i].type == "circle" then + love.graphics.circle("fill", o.body[i].x, o.body[i].y, o.body[i].radius) + elseif o.body[i].type == "rectangle" then + love.graphics.rectangle("fill", o.body[i].x, o.body[i].y, o.body[i].width, o.body[i].height) + elseif o.body[i].type == "polygon" then + love.graphics.polygon("fill", unpack(o.body[i].data)) + elseif o.body[i].type == "image" and o.body[i].img then + love.graphics.draw(o.body[i].img, o.body[i].x - o.body[i].ix + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].iy + LOVE_LIGHT_TRANSLATE_Y) + end + end + end + end + + if o.optionReflection and o.isReflection then + -- create reflection map + if o.changed then + o.reflectionMap:clear(0, 0, 0) + love.graphics.setCanvas(o.reflectionMap) + for i = 1, #o.body do + if o.body[i].reflection and o.body[i].normal then + love.graphics.setColor(255, 0, 0) + o.body[i].normalMesh:setVertices(o.body[i].normalVert) + love.graphics.draw(o.body[i].normalMesh, o.body[i].x - o.body[i].nx + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].ny + LOVE_LIGHT_TRANSLATE_Y) + end + end + for i = 1, #o.body do + if o.body[i].reflective and o.body[i].img then + love.graphics.setColor(0, 255, 0) + love.graphics.draw(o.body[i].img, o.body[i].x - o.body[i].ix + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].iy + LOVE_LIGHT_TRANSLATE_Y) + elseif not o.body[i].reflection and o.body[i].img then + love.graphics.setColor(0, 0, 0) + love.graphics.draw(o.body[i].img, o.body[i].x - o.body[i].ix + LOVE_LIGHT_TRANSLATE_X, o.body[i].y - o.body[i].iy + LOVE_LIGHT_TRANSLATE_Y) + end end end end @@ -360,65 +402,86 @@ function love.light.newWorld() o.changed = false end + o.refreshScreenSize = function() + o.shadow = love.graphics.newCanvas() + o.shadow2 = love.graphics.newCanvas() + o.shine = love.graphics.newCanvas() + o.shine2 = love.graphics.newCanvas() + o.normalMap = love.graphics.newCanvas() + o.glowMap = love.graphics.newCanvas() + o.glowMap2 = love.graphics.newCanvas() + o.refractionMap = love.graphics.newCanvas() + o.refractionMap2 = love.graphics.newCanvas() + o.reflectionMap = love.graphics.newCanvas() + o.reflectionMap2 = love.graphics.newCanvas() + o.pixelShadow = love.graphics.newCanvas() + o.pixelShadow2 = love.graphics.newCanvas() + end -- draw shadow o.drawShadow = function() - love.graphics.setColor(255, 255, 255) - if o.blur then - LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() - LOVE_LIGHT_BLURV:send("steps", o.blur) - LOVE_LIGHT_BLURH:send("steps", o.blur) - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(o.shadow2) - love.graphics.setShader(LOVE_LIGHT_BLURV) - love.graphics.draw(o.shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setCanvas(o.shadow) - love.graphics.setShader(LOVE_LIGHT_BLURH) - love.graphics.draw(o.shadow2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) - love.graphics.setBlendMode("multiplicative") - love.graphics.setShader() - love.graphics.draw(o.shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setBlendMode("alpha") - else - love.graphics.setBlendMode("multiplicative") - love.graphics.setShader() - love.graphics.draw(o.shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setBlendMode("alpha") + if o.optionShadows and (o.isShadows or o.isLight) then + love.graphics.setColor(255, 255, 255) + if o.blur then + LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() + LOVE_LIGHT_BLURV:send("steps", o.blur) + LOVE_LIGHT_BLURH:send("steps", o.blur) + love.graphics.setBlendMode("alpha") + love.graphics.setCanvas(o.shadow2) + love.graphics.setShader(LOVE_LIGHT_BLURV) + love.graphics.draw(o.shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setCanvas(o.shadow) + love.graphics.setShader(LOVE_LIGHT_BLURH) + love.graphics.draw(o.shadow2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) + love.graphics.setBlendMode("multiplicative") + love.graphics.setShader() + love.graphics.draw(o.shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setBlendMode("alpha") + else + love.graphics.setBlendMode("multiplicative") + love.graphics.setShader() + love.graphics.draw(o.shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setBlendMode("alpha") + end end end -- draw shine o.drawShine = function() - love.graphics.setColor(255, 255, 255) - if o.blur and false then - LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() - LOVE_LIGHT_BLURV:send("steps", o.blur) - LOVE_LIGHT_BLURH:send("steps", o.blur) - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(o.shine2) - love.graphics.setShader(LOVE_LIGHT_BLURV) - love.graphics.draw(o.shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setCanvas(o.shine) - love.graphics.setShader(LOVE_LIGHT_BLURH) - love.graphics.draw(o.shine2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) - love.graphics.setBlendMode("multiplicative") - love.graphics.setShader() - love.graphics.draw(o.shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setBlendMode("alpha") - else - love.graphics.setBlendMode("multiplicative") - love.graphics.setShader() - love.graphics.draw(o.shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setBlendMode("alpha") + if o.optionShadows and o.isShadows then + love.graphics.setColor(255, 255, 255) + if o.blur and false then + LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() + LOVE_LIGHT_BLURV:send("steps", o.blur) + LOVE_LIGHT_BLURH:send("steps", o.blur) + love.graphics.setBlendMode("alpha") + love.graphics.setCanvas(o.shine2) + love.graphics.setShader(LOVE_LIGHT_BLURV) + love.graphics.draw(o.shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setCanvas(o.shine) + love.graphics.setShader(LOVE_LIGHT_BLURH) + love.graphics.draw(o.shine2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) + love.graphics.setBlendMode("multiplicative") + love.graphics.setShader() + love.graphics.draw(o.shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setBlendMode("alpha") + else + love.graphics.setBlendMode("multiplicative") + love.graphics.setShader() + love.graphics.draw(o.shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setBlendMode("alpha") + end end end -- draw pixel shadow o.drawPixelShadow = function() - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("multiplicative") - love.graphics.setShader() - love.graphics.draw(o.pixelShadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setBlendMode("alpha") + if o.optionPixelShadows and o.isPixelShadows then + love.graphics.setColor(255, 255, 255) + love.graphics.setBlendMode("multiplicative") + love.graphics.setShader() + love.graphics.draw(o.pixelShadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setBlendMode("alpha") + end end -- draw material o.drawMaterial = function() @@ -434,64 +497,67 @@ function love.light.newWorld() end -- draw glow o.drawGlow = function() - love.graphics.setColor(255, 255, 255) - if o.isGlowBlur or o.glowBlur == 0.0 then - love.graphics.setBlendMode("additive") - love.graphics.setShader() - love.graphics.draw(o.glowMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setBlendMode("alpha") - else - LOVE_LIGHT_BLURV:send("steps", o.glowBlur) - LOVE_LIGHT_BLURH:send("steps", o.glowBlur) - LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() - love.graphics.setBlendMode("additive") - o.glowMap2:clear() - love.graphics.setCanvas(o.glowMap2) - love.graphics.setShader(LOVE_LIGHT_BLURV) - love.graphics.draw(o.glowMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setCanvas(o.glowMap) - love.graphics.setShader(LOVE_LIGHT_BLURH) - love.graphics.draw(o.glowMap2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) - --love.graphics.setBlendMode("additive") - love.graphics.setShader() - love.graphics.draw(o.glowMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setBlendMode("alpha") - - o.isGlowBlur = true + if o.optionGlow and o.isGlow then + love.graphics.setColor(255, 255, 255) + if o.glowBlur == 0.0 then + love.graphics.setBlendMode("additive") + love.graphics.setShader() + love.graphics.draw(o.glowMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setBlendMode("alpha") + else + LOVE_LIGHT_BLURV:send("steps", o.glowBlur) + LOVE_LIGHT_BLURH:send("steps", o.glowBlur) + LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() + love.graphics.setBlendMode("additive") + o.glowMap2:clear() + love.graphics.setCanvas(o.glowMap2) + love.graphics.setShader(LOVE_LIGHT_BLURV) + love.graphics.draw(o.glowMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setCanvas(o.glowMap) + love.graphics.setShader(LOVE_LIGHT_BLURH) + love.graphics.draw(o.glowMap2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) + love.graphics.setShader() + love.graphics.draw(o.glowMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setBlendMode("alpha") + end end end -- draw refraction o.drawRefraction = function() - LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() - if LOVE_LIGHT_LAST_BUFFER then - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(o.refractionMap2) - love.graphics.draw(LOVE_LIGHT_LAST_BUFFER, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) - o.refractionShader:send("backBuffer", o.refractionMap2) - o.refractionShader:send("refractionStrength", o.refractionStrength) - love.graphics.setShader(o.refractionShader) - love.graphics.draw(o.refractionMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setShader() + if o.optionRefraction and o.isRefraction then + LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() + if LOVE_LIGHT_LAST_BUFFER then + love.graphics.setColor(255, 255, 255) + love.graphics.setBlendMode("alpha") + love.graphics.setCanvas(o.refractionMap2) + love.graphics.draw(LOVE_LIGHT_LAST_BUFFER, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) + o.refractionShader:send("backBuffer", o.refractionMap2) + o.refractionShader:send("refractionStrength", o.refractionStrength) + love.graphics.setShader(o.refractionShader) + love.graphics.draw(o.refractionMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setShader() + end end end -- draw reflection o.drawReflection = function() - LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() - if LOVE_LIGHT_LAST_BUFFER then - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(o.reflectionMap2) - love.graphics.draw(LOVE_LIGHT_LAST_BUFFER, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) - o.reflectionShader:send("backBuffer", o.reflectionMap2) - o.reflectionShader:send("reflectionStrength", o.reflectionStrength) - o.reflectionShader:send("reflectionVisibility", o.reflectionVisibility) - love.graphics.setShader(o.reflectionShader) - love.graphics.draw(o.reflectionMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - love.graphics.setShader() + if o.optionReflection and o.isReflection then + LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() + if LOVE_LIGHT_LAST_BUFFER then + love.graphics.setColor(255, 255, 255) + love.graphics.setBlendMode("alpha") + love.graphics.setCanvas(o.reflectionMap2) + love.graphics.draw(LOVE_LIGHT_LAST_BUFFER, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) + o.reflectionShader:send("backBuffer", o.reflectionMap2) + o.reflectionShader:send("reflectionStrength", o.reflectionStrength) + o.reflectionShader:send("reflectionVisibility", o.reflectionVisibility) + love.graphics.setShader(o.reflectionShader) + love.graphics.draw(o.reflectionMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setShader() + end end end -- new light @@ -503,12 +569,18 @@ function love.light.newWorld() -- clear lights o.clearLights = function() o.lights = {} + o.isLight = false o.changed = true end -- clear objects o.clearBodys = function() o.body = {} o.changed = true + o.isShadows = false + o.isPixelShadows = false + o.isGlow = false + o.isRefraction = false + o.isReflection = false end -- set offset o.setTranslation = function(translateX, translateY) @@ -545,6 +617,18 @@ function love.light.newWorld() o.blur = blur o.changed = true end + -- set buffer + o.setBuffer = function(buffer) + if buffer == "render" then + love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) + else + LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() + end + + if buffer == "glow" then + love.graphics.setCanvas(o.glowMap) + end + end -- set glow blur o.setGlowStrength = function(strength) o.glowBlur = strength @@ -672,13 +756,15 @@ function love.light.newLight(p, x, y, red, green, blue, range) o.glowStrength = 0.0 o.changed = true o.visible = true + p.isLight = true -- set position o.setPosition = function(x, y, z) - o.z = z or o.z - if x ~= o.x or y ~= o.y or z ~= o.z then + if x ~= o.x or y ~= o.y or (z and z ~= o.z) then o.x = x o.y = y - o.z = z + if z then + o.z = z + end o.changed = true end end @@ -763,6 +849,18 @@ function love.light.newLight(p, x, y, red, green, blue, range) o.getType = function() return "light" end + -- clear + o.clear = function() + for i = 1, #p.lights do + if p.lights[i] == o then + for k = i, #p.lights - 1 do + p.lights[k] = p.lights[k + 1] + end + p.lights[#p.lights] = nil + break + end + end + end return o end @@ -789,6 +887,7 @@ function love.light.newBody(p, type, ...) o.reflective = false o.refraction = false o.refractive = false + p.isShadows = true elseif o.type == "rectangle" then o.x = args[1] or 0 o.y = args[2] or 0 @@ -811,6 +910,7 @@ function love.light.newBody(p, type, ...) o.reflective = false o.refraction = false o.refractive = false + p.isShadows = true elseif o.type == "polygon" then o.shadowType = "polygon" o.data = args or {0, 0, 0, 0, 0, 0} @@ -818,6 +918,7 @@ function love.light.newBody(p, type, ...) o.reflective = false o.refraction = false o.refractive = false + p.isShadows = true elseif o.type == "image" then o.img = args[1] o.x = args[2] or 0 @@ -829,6 +930,13 @@ function love.light.newBody(p, type, ...) o.height = args[5] or o.imgHeight o.ix = o.imgWidth * 0.5 o.iy = o.imgHeight * 0.5 + o.vert = { + { 0.0, 0.0, 0.0, 0.0 }, + { o.width, 0.0, 1.0, 0.0 }, + { o.width, o.height, 1.0, 1.0 }, + { 0.0, o.height, 0.0, 1.0 }, + } + o.msh = love.graphics.newMesh(o.vert, o.img, "fan") else o.width = args[4] or 64 o.height = args[5] or 64 @@ -850,6 +958,7 @@ function love.light.newBody(p, type, ...) o.reflective = true o.refraction = false o.refractive = false + p.isShadows = true elseif o.type == "refraction" then o.normal = args[1] o.x = args[2] or 0 @@ -879,6 +988,7 @@ function love.light.newBody(p, type, ...) o.reflective = false o.refraction = true o.refractive = false + p.isRefraction = true elseif o.type == "reflection" then o.normal = args[1] o.x = args[2] or 0 @@ -908,6 +1018,7 @@ function love.light.newBody(p, type, ...) o.reflective = false o.refraction = false o.refractive = false + p.isReflection = true end o.shine = true o.red = 0 @@ -1104,22 +1215,30 @@ function love.light.newBody(p, type, ...) end end -- set normal - o.setNormalMap = function(normal) + o.setNormalMap = function(normal, width, height, nx, ny) if normal then o.normal = normal - o.normalWidth = o.normal:getWidth() - o.normalHeight = o.normal:getHeight() - o.nx = o.normalWidth * 0.5 - o.ny = o.normalHeight * 0.5 + o.normal:setWrap("repeat", "repeat") + o.normalWidth = width or o.normal:getWidth() + o.normalHeight = height or o.normal:getHeight() + o.nx = nx or o.normalWidth * 0.5 + o.ny = ny or o.normalHeight * 0.5 + o.normalVert = { + {0.0, 0.0, 0.0, 0.0}, + {o.normalWidth, 0.0, o.normalWidth / o.normal:getWidth(), 0.0}, + {o.normalWidth, o.normalHeight, o.normalWidth / o.normal:getWidth(), o.normalHeight / o.normal:getHeight()}, + {0.0, o.normalHeight, 0.0, o.normalHeight / o.normal:getHeight()} + } + o.normalMesh = love.graphics.newMesh(o.normalVert, o.normal, "fan") + + p.isPixelShadows = true + else + o.normalMesh = nil end end -- set height map o.setHeightMap = function(heightMap, strength) - o.normal = HeightMapToNormalMap(heightMap, strength) - o.normalWidth = o.normal:getWidth() - o.normalHeight = o.normal:getHeight() - o.nx = o.normalWidth * 0.5 - o.ny = o.normalHeight * 0.5 + o.setNormalMap(HeightMapToNormalMap(heightMap, strength)) end -- generate flat normal map o.generateNormalMapFlat = function(mode) @@ -1148,11 +1267,7 @@ function love.light.newBody(p, type, ...) end end - o.normal = love.graphics.newImage(imgNormalData) - o.normalWidth = o.normal:getWidth() - o.normalHeight = o.normal:getHeight() - o.nx = o.normalWidth * 0.5 - o.ny = o.normalHeight * 0.5 + o.setNormalMap(love.graphics.newImage(imgNormalData)) end -- generate faded normal map o.generateNormalMapGradient = function(horizontalGradient, verticalGradient) @@ -1192,19 +1307,11 @@ function love.light.newBody(p, type, ...) end end - o.normal = love.graphics.newImage(imgNormalData) - o.normalWidth = o.normal:getWidth() - o.normalHeight = o.normal:getHeight() - o.nx = o.normalWidth * 0.5 - o.ny = o.normalHeight * 0.5 + o.setNormalMap(love.graphics.newImage(imgNormalData)) end -- generate normal map o.generateNormalMap = function(strength) - o.normal = HeightMapToNormalMap(o.img, strength) - o.normalWidth = o.normal:getWidth() - o.normalHeight = o.normal:getHeight() - o.nx = o.normalWidth * 0.5 - o.ny = o.normalHeight * 0.5 + o.setNormalMap(HeightMapToNormalMap(o.img, strength)) end -- set material o.setMaterial = function(material) @@ -1216,6 +1323,8 @@ function love.light.newBody(p, type, ...) o.setGlowMap = function(glow) o.glow = glow o.glowStrength = 1.0 + + p.isGlow = true end -- set tile offset o.setNormalTileOffset = function(tx, ty) @@ -1281,6 +1390,19 @@ function love.light.newBody(p, type, ...) o.fadeStrength = args[3] or 0.0 end end + -- clear + o.clear = function() + for i = 1, #p.body do + if p.body[i] == o then + for k = i, #p.body - 1 do + p.body[k] = p.body[k + 1] + end + p.body[#p.body] = nil + break + end + end + p.changed = true + end return o end @@ -1339,21 +1461,21 @@ function dot(v1, v2) end function lengthSqr(v) - return v[1] * v[1] + v[2] * v[2] + return v[1] * v[1] + v[2] * v[2] end function length(v) - return math.sqrt(lengthSqr(v)) + return math.sqrt(lengthSqr(v)) end function calculateShadows(light, body) - local shadowGeometry = {} - local shadowLength = 10000 + local shadowGeometry = {} + local shadowLength = 100000 - for i = 1, #body do + for i = 1, #body do if body[i].shadowType == "rectangle" or body[i].shadowType == "polygon" then curPolygon = body[i].data - if not body[i].castsNoShadow then + if not body[i].castsNoShadow then local edgeFacingTo = {} for k = 1, #curPolygon, 2 do local indexOfNextVertex = (k + 2) % #curPolygon @@ -1372,7 +1494,7 @@ function calculateShadows(light, body) for k = 1, #edgeFacingTo do local nextIndex = (k + 1) % #edgeFacingTo if nextIndex == 0 then nextIndex = #edgeFacingTo end - if edgeFacingTo[k] and not edgeFacingTo[nextIndex] then + if edgeFacingTo[k] and not edgeFacingTo[nextIndex] then curShadowGeometry[1] = curPolygon[nextIndex*2-1] curShadowGeometry[2] = curPolygon[nextIndex*2] @@ -1380,7 +1502,7 @@ function calculateShadows(light, body) curShadowGeometry[3] = curShadowGeometry[1] + lightVecFrontBack[1] * shadowLength curShadowGeometry[4] = curShadowGeometry[2] + lightVecFrontBack[2] * shadowLength - elseif not edgeFacingTo[k] and edgeFacingTo[nextIndex] then + elseif not edgeFacingTo[k] and edgeFacingTo[nextIndex] then curShadowGeometry[7] = curPolygon[nextIndex*2-1] curShadowGeometry[8] = curPolygon[nextIndex*2] @@ -1390,13 +1512,13 @@ function calculateShadows(light, body) end end if curShadowGeometry[1] - and curShadowGeometry[2] - and curShadowGeometry[3] - and curShadowGeometry[4] - and curShadowGeometry[5] - and curShadowGeometry[6] - and curShadowGeometry[7] - and curShadowGeometry[8] + and curShadowGeometry[2] + and curShadowGeometry[3] + and curShadowGeometry[4] + and curShadowGeometry[5] + and curShadowGeometry[6] + and curShadowGeometry[7] + and curShadowGeometry[8] then curShadowGeometry.alpha = body[i].alpha curShadowGeometry.red = body[i].red @@ -1406,34 +1528,36 @@ function calculateShadows(light, body) end end elseif body[i].shadowType == "circle" then - local length = math.sqrt(math.pow(light.x - (body[i].x - body[i].ox), 2) + math.pow(light.y - (body[i].y - body[i].oy), 2)) - if length >= body[i].radius and length <= light.range then - local curShadowGeometry = {} - local angle = math.atan2(light.x - (body[i].x - body[i].ox), (body[i].y - body[i].oy) - light.y) + math.pi / 2 - local x2 = ((body[i].x - body[i].ox) + math.sin(angle) * body[i].radius) - local y2 = ((body[i].y - body[i].oy) - math.cos(angle) * body[i].radius) - local x3 = ((body[i].x - body[i].ox) - math.sin(angle) * body[i].radius) - local y3 = ((body[i].y - body[i].oy) + math.cos(angle) * body[i].radius) + if not body[i].castsNoShadow then + local length = math.sqrt(math.pow(light.x - (body[i].x - body[i].ox), 2) + math.pow(light.y - (body[i].y - body[i].oy), 2)) + if length >= body[i].radius and length <= light.range then + local curShadowGeometry = {} + local angle = math.atan2(light.x - (body[i].x - body[i].ox), (body[i].y - body[i].oy) - light.y) + math.pi / 2 + local x2 = ((body[i].x - body[i].ox) + math.sin(angle) * body[i].radius) + local y2 = ((body[i].y - body[i].oy) - math.cos(angle) * body[i].radius) + local x3 = ((body[i].x - body[i].ox) - math.sin(angle) * body[i].radius) + local y3 = ((body[i].y - body[i].oy) + math.cos(angle) * body[i].radius) - curShadowGeometry[1] = x2 - curShadowGeometry[2] = y2 - curShadowGeometry[3] = x3 - curShadowGeometry[4] = y3 + curShadowGeometry[1] = x2 + curShadowGeometry[2] = y2 + curShadowGeometry[3] = x3 + curShadowGeometry[4] = y3 - curShadowGeometry[5] = x3 - (light.x - x3) * shadowLength - curShadowGeometry[6] = y3 - (light.y - y3) * shadowLength - curShadowGeometry[7] = x2 - (light.x - x2) * shadowLength - curShadowGeometry[8] = y2 - (light.y - y2) * shadowLength - curShadowGeometry.alpha = body[i].alpha - curShadowGeometry.red = body[i].red - curShadowGeometry.green = body[i].green - curShadowGeometry.blue = body[i].blue - shadowGeometry[#shadowGeometry + 1] = curShadowGeometry + curShadowGeometry[5] = x3 - (light.x - x3) * shadowLength + curShadowGeometry[6] = y3 - (light.y - y3) * shadowLength + curShadowGeometry[7] = x2 - (light.x - x2) * shadowLength + curShadowGeometry[8] = y2 - (light.y - y2) * shadowLength + curShadowGeometry.alpha = body[i].alpha + curShadowGeometry.red = body[i].red + curShadowGeometry.green = body[i].green + curShadowGeometry.blue = body[i].blue + shadowGeometry[#shadowGeometry + 1] = curShadowGeometry + end end end end - return shadowGeometry + return shadowGeometry end shadowStencil = function() @@ -1442,21 +1566,23 @@ shadowStencil = function() love.graphics.polygon("fill", unpack(LOVE_LIGHT_SHADOW_GEOMETRY[i])) end end - for i = 1, #LOVE_LIGHT_BODY do - if LOVE_LIGHT_BODY[i].shadowType == "circle" then - love.graphics.circle("fill", LOVE_LIGHT_BODY[i].x - LOVE_LIGHT_BODY[i].ox, LOVE_LIGHT_BODY[i].y - LOVE_LIGHT_BODY[i].oy, LOVE_LIGHT_BODY[i].radius) - elseif LOVE_LIGHT_BODY[i].shadowType == "rectangle" then - love.graphics.rectangle("fill", LOVE_LIGHT_BODY[i].x - LOVE_LIGHT_BODY[i].ox, LOVE_LIGHT_BODY[i].y - LOVE_LIGHT_BODY[i].oy, LOVE_LIGHT_BODY[i].width, LOVE_LIGHT_BODY[i].height) - elseif LOVE_LIGHT_BODY[i].shadowType == "polygon" then - love.graphics.polygon("fill", unpack(LOVE_LIGHT_BODY[i].data)) - elseif LOVE_LIGHT_BODY[i].shadowType == "image" then + for i = 1, #LOVE_LIGHT_BODY do + if not LOVE_LIGHT_BODY[i].castsNoShadow then + if LOVE_LIGHT_BODY[i].shadowType == "circle" then + love.graphics.circle("fill", LOVE_LIGHT_BODY[i].x - LOVE_LIGHT_BODY[i].ox, LOVE_LIGHT_BODY[i].y - LOVE_LIGHT_BODY[i].oy, LOVE_LIGHT_BODY[i].radius) + elseif LOVE_LIGHT_BODY[i].shadowType == "rectangle" then + love.graphics.rectangle("fill", LOVE_LIGHT_BODY[i].x - LOVE_LIGHT_BODY[i].ox, LOVE_LIGHT_BODY[i].y - LOVE_LIGHT_BODY[i].oy, LOVE_LIGHT_BODY[i].width, LOVE_LIGHT_BODY[i].height) + elseif LOVE_LIGHT_BODY[i].shadowType == "polygon" then + love.graphics.polygon("fill", unpack(LOVE_LIGHT_BODY[i].data)) + elseif LOVE_LIGHT_BODY[i].shadowType == "image" then --love.graphics.rectangle("fill", LOVE_LIGHT_BODY[i].x - LOVE_LIGHT_BODY[i].ox, LOVE_LIGHT_BODY[i].y - LOVE_LIGHT_BODY[i].oy, LOVE_LIGHT_BODY[i].width, LOVE_LIGHT_BODY[i].height) + end end end end polyStencil = function() - for i = 1, #LOVE_LIGHT_BODY do + for i = 1, #LOVE_LIGHT_BODY do if LOVE_LIGHT_BODY[i].shine and (LOVE_LIGHT_BODY[i].glowStrength == 0.0 or (LOVE_LIGHT_BODY[i].type == "image" and not LOVE_LIGHT_BODY[i].normal)) then if LOVE_LIGHT_BODY[i].shadowType == "circle" then love.graphics.circle("fill", LOVE_LIGHT_BODY[i].x - LOVE_LIGHT_BODY[i].ox, LOVE_LIGHT_BODY[i].y - LOVE_LIGHT_BODY[i].oy, LOVE_LIGHT_BODY[i].radius) @@ -1465,7 +1591,7 @@ polyStencil = function() elseif LOVE_LIGHT_BODY[i].shadowType == "polygon" then love.graphics.polygon("fill", unpack(LOVE_LIGHT_BODY[i].data)) elseif LOVE_LIGHT_BODY[i].shadowType == "image" then - --love.graphics.rectangle("fill", LOVE_LIGHT_BODY[i].x - LOVE_LIGHT_BODY[i].ox, LOVE_LIGHT_BODY[i].y - LOVE_LIGHT_BODY[i].oy, LOVE_LIGHT_BODY[i].width, LOVE_LIGHT_BODY[i].height) + --love.graphics.rectangle("fill", LOVE_LIGHT_BODY[i].x - LOVE_LIGHT_BODY[i].ox, LOVE_LIGHT_BODY[i].y - LOVE_LIGHT_BODY[i].oy, LOVE_LIGHT_BODY[i].width, LOVE_LIGHT_BODY[i].height) end end end diff --git a/postshader.lua b/lib/postshader.lua similarity index 64% rename from postshader.lua rename to lib/postshader.lua index 2a07d97..5ef889d 100644 --- a/postshader.lua +++ b/lib/postshader.lua @@ -1,3 +1,27 @@ +--[[ +The MIT License (MIT) + +Copyright (c) 2014 Marcus Ihde + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +]] + LOVE_POSTSHADER_BUFFER_RENDER = love.graphics.newCanvas() LOVE_POSTSHADER_BUFFER_BACK = love.graphics.newCanvas() LOVE_POSTSHADER_LAST_BUFFER = nil @@ -11,10 +35,6 @@ LOVE_POSTSHADER_MONOCHROM = love.graphics.newShader("shader/monochrom.glsl") LOVE_POSTSHADER_SCANLINES = love.graphics.newShader("shader/scanlines.glsl") LOVE_POSTSHADER_TILT_SHIFT = love.graphics.newShader("shader/tilt_shift.glsl") -LOVE_POSTSHADER_BLURV:send("screen", {love.window.getWidth(), love.window.getHeight()}) -LOVE_POSTSHADER_BLURH:send("screen", {love.window.getWidth(), love.window.getHeight()}) -LOVE_POSTSHADER_SCANLINES:send("screenHeight", {love.window.getWidth(), love.window.getHeight()}) - love.postshader = {} love.postshader.setBuffer = function(path) @@ -35,6 +55,8 @@ love.postshader.addEffect = function(shader, ...) if shader == "bloom" then -- Bloom Shader + LOVE_POSTSHADER_BLURV:send("screen", {love.window.getWidth(), love.window.getHeight()}) + LOVE_POSTSHADER_BLURH:send("screen", {love.window.getWidth(), love.window.getHeight()}) LOVE_POSTSHADER_BLURV:send("steps", args[1] or 2.0) LOVE_POSTSHADER_BLURH:send("steps", args[1] or 2.0) @@ -57,6 +79,8 @@ love.postshader.addEffect = function(shader, ...) love.graphics.setBlendMode("alpha") elseif shader == "blur" then -- Blur Shader + LOVE_POSTSHADER_BLURV:send("screen", {love.window.getWidth(), love.window.getHeight()}) + LOVE_POSTSHADER_BLURH:send("screen", {love.window.getWidth(), love.window.getHeight()}) LOVE_POSTSHADER_BLURV:send("steps", args[1] or 2.0) LOVE_POSTSHADER_BLURH:send("steps", args[2] or 2.0) @@ -85,16 +109,27 @@ love.postshader.addEffect = function(shader, ...) love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER) elseif shader == "monochrom" then -- Monochrom Shader - LOVE_POSTSHADER_MONOCHROM:send("time", love.timer.getTime()) + for i = 1, 3 do + if args[i] then + args[i] = args[i] / 255.0 + end + end + LOVE_POSTSHADER_MONOCHROM:send("tint", {args[1] or 1.0, args[2] or 1.0, args[3] or 1.0}) + LOVE_POSTSHADER_MONOCHROM:send("fudge", args[4] or 0.1) + LOVE_POSTSHADER_MONOCHROM:send("time", args[5] or love.timer.getTime()) love.graphics.setShader(LOVE_POSTSHADER_MONOCHROM) love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER) elseif shader == "scanlines" then -- Scanlines Shader - LOVE_POSTSHADER_SCANLINES:send("time", love.timer.getTime()) + LOVE_POSTSHADER_SCANLINES:send("screen", {love.window.getWidth(), love.window.getHeight()}) + LOVE_POSTSHADER_SCANLINES:send("strength", args[1] or 2.0) + LOVE_POSTSHADER_SCANLINES:send("time", args[2] or love.timer.getTime()) love.graphics.setShader(LOVE_POSTSHADER_SCANLINES) love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER) elseif shader == "tiltshift" then -- Blur Shader + LOVE_POSTSHADER_BLURV:send("screen", {love.window.getWidth(), love.window.getHeight()}) + LOVE_POSTSHADER_BLURH:send("screen", {love.window.getWidth(), love.window.getHeight()}) LOVE_POSTSHADER_BLURV:send("steps", args[1] or 2.0) LOVE_POSTSHADER_BLURH:send("steps", args[1] or 2.0) @@ -104,7 +139,7 @@ love.postshader.addEffect = function(shader, ...) love.graphics.setShader(LOVE_POSTSHADER_BLURH) love.graphics.draw(LOVE_POSTSHADER_BUFFER_BACK) - LOVE_POSTSHADER_TILT_SHIFT:send("buffer", LOVE_POSTSHADER_BUFFER_RENDER) + LOVE_POSTSHADER_TILT_SHIFT:send("imgBuffer", LOVE_POSTSHADER_BUFFER_RENDER) love.graphics.setShader(LOVE_POSTSHADER_TILT_SHIFT) love.graphics.draw(LOVE_POSTSHADER_BUFFER_BACK) end @@ -120,9 +155,16 @@ end love.postshader.draw = function() if LOVE_POSTSHADER_LAST_BUFFER then + love.graphics.setBackgroundColor(0, 0, 0) + love.graphics.setBlendMode("alpha") love.graphics.setCanvas() love.graphics.setShader() love.graphics.setColor(255, 255, 255) love.graphics.draw(LOVE_POSTSHADER_LAST_BUFFER) end +end + +love.postshader.refreshScreenSize = function() + LOVE_POSTSHADER_BUFFER_RENDER = love.graphics.newCanvas() + LOVE_POSTSHADER_BUFFER_BACK = love.graphics.newCanvas() end \ No newline at end of file diff --git a/main.lua b/main.lua index c7f14c2..e1eb714 100644 --- a/main.lua +++ b/main.lua @@ -1,714 +1,393 @@ -require "postshader" -require "light" +-- +-- EXF: Example Framework +-- +-- This should make examples easier and more enjoyable to use. +-- All examples in one application! Yaay! +-- +-- Updated by Dresenpai -function initScene() - -- physic world - physicWorld = love.physics.newWorld(0, 9.81 * 64, true) - wall1 = {} - wall1.body = love.physics.newBody(physicWorld, 400, 605, "static") - wall1.shape = love.physics.newRectangleShape(0, 0, 800, 10) - wall1.fixture = love.physics.newFixture(wall1.body, wall1.shape) +require "lib/postshader" +require "lib/light" - wall2 = {} - wall2.body = love.physics.newBody(physicWorld, -5, 300, "static") - wall2.shape = love.physics.newRectangleShape(0, 0, 10, 600) - wall2.fixture = love.physics.newFixture(wall2.body, wall2.shape) +exf = {} +exf.current = nil - wall3 = {} - wall3.body = love.physics.newBody(physicWorld, 805, 300, "static") - wall3.shape = love.physics.newRectangleShape(0, 0, 10, 600) - wall3.fixture = love.physics.newFixture(wall3.body, wall3.shape) - - wall4 = {} - wall4.body = love.physics.newBody(physicWorld, 400, -5, "static") - wall4.shape = love.physics.newRectangleShape(0, 0, 800, 10) - wall4.fixture = love.physics.newFixture(wall4.body, wall4.shape) - - phyCnt = 0 - phyLight = {} - phyBody = {} - phyShape = {} - phyFixture = {} -end +exf.available = {} function love.load() + exf.list = List:new() + exf.smallfont = love.graphics.newFont(love._vera_ttf,12) + exf.bigfont = love.graphics.newFont(love._vera_ttf, 24) + exf.list.font = exf.smallfont + + exf.bigball = love.graphics.newImage("gfx/love-big-ball.png") + + -- Find available demos. + local files = love.filesystem.getDirectoryItems("examples") + local n = 0 + + for i, v in ipairs(files) do + n = n + 1 + table.insert(exf.available, v); + local file = love.filesystem.newFile(v, love.file_read) + file:open("r") + local contents = love.filesystem.read("examples/" .. v, 100) + local s, e, c = string.find(contents, "Example: ([%a%p ]-)[\r\n]") + file:close(file) + if not c then c = "Untitled" end + local title = exf.getn(n) .. " " .. c .. " (" .. v .. ")" + exf.list:add(title, v) + end + + exf.list:done() + exf.resume() +end + +function love.update(dt) end +function love.draw() end +function love.keypressed(k) end +function love.keyreleased(k) end +function love.mousepressed(x, y, b) end +function love.mousereleased(x, y, b) end + +function exf.empty() end + +function exf.update(dt) + exf.list:update(dt) + lightMouse.setPosition(love.mouse.getX(), love.mouse.getY()) +end + +function exf.draw() love.graphics.setBackgroundColor(0, 0, 0) - love.graphics.setDefaultFilter("nearest", "nearest") - -- load image font - font = love.graphics.newImageFont("gfx/font.png", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&`'*#=[]\"") - love.graphics.setFont(font) + love.graphics.setColor(48, 156, 225) + love.graphics.rectangle("fill", 0, 0, love.window.getWidth(), love.window.getHeight()) - -- set background - quadScreen = love.graphics.newQuad(0, 0, love.window.getWidth() + 32, love.window.getHeight() + 24, 32, 24) - imgFloor = love.graphics.newImage("gfx/floor.png") - imgFloor:setWrap("repeat", "repeat") + love.graphics.setColor(255, 255, 255, 191) + love.graphics.setFont(exf.bigfont) + love.graphics.print("Examples:", 50, 50) - -- load image examples - circle = love.graphics.newImage("gfx/circle.png") - circle_normal = love.graphics.newImage("gfx/circle_normal.png") - cone = love.graphics.newImage("gfx/cone.png") - cone_large = love.graphics.newImage("gfx/cone_large.png") - cone_large_normal = love.graphics.newImage("gfx/cone_large_normal.png") - cone_normal = love.graphics.newImage("gfx/cone_normal.png") - chest = love.graphics.newImage("gfx/chest.png") - chest_normal = love.graphics.newImage("gfx/chest_normal.png") - machine = love.graphics.newImage("gfx/machine.png") - machine_normal = love.graphics.newImage("gfx/machine_normal.png") - machine_glow = love.graphics.newImage("gfx/machine_glow.png") - machine2 = love.graphics.newImage("gfx/machine2.png") - machine2_normal = love.graphics.newImage("gfx/machine2_normal.png") - machine2_glow = love.graphics.newImage("gfx/machine2_glow.png") - blopp = love.graphics.newImage("gfx/blopp.png") - tile = love.graphics.newImage("gfx/tile.png") - tile_normal = love.graphics.newImage("gfx/tile_normal.png") - tile_glow = love.graphics.newImage("gfx/tile_glow.png") - refraction_normal = love.graphics.newImage("gfx/refraction_normal.png") - water = love.graphics.newImage("gfx/water.png") - led = love.graphics.newImage("gfx/led.png") - led2 = love.graphics.newImage("gfx/led2.png") - led3 = love.graphics.newImage("gfx/led3.png") - led_normal = love.graphics.newImage("gfx/led_normal.png") - led_glow = love.graphics.newImage("gfx/led_glow.png") - led_glow2 = love.graphics.newImage("gfx/led_glow2.png") - led_glow3 = love.graphics.newImage("gfx/led_glow3.png") - ape = love.graphics.newImage("gfx/ape.png") - ape_normal = love.graphics.newImage("gfx/ape_normal.png") - ape_glow = love.graphics.newImage("gfx/ape_glow.png") - imgLight = love.graphics.newImage("gfx/light.png") + love.graphics.setFont(exf.smallfont) + love.graphics.print("Browse and click on the example you \nwant to run. To return the the example \nselection screen, press escape.", 500, 80) - -- materials - material = {} + exf.list:draw() - local files = love.filesystem.getDirectoryItems("gfx/sphere") - for i, file in ipairs(files) do - material[i] = love.graphics.newImage("gfx/sphere/" .. file) + lightWorld.update() + lightWorld.drawShadow() + + love.graphics.setColor(255, 255, 255) + love.graphics.draw(exf.bigball, 800 - 128, 600 - 128, love.timer.getTime(), 1, 1, exf.bigball:getWidth() * 0.5, exf.bigball:getHeight() * 0.5) +end + +function exf.keypressed(k) +end + +function exf.keyreleased(k) +end + +function exf.mousepressed(x, y, b) + exf.list:mousepressed(x, y, b) +end + +function exf.mousereleased(x, y, b) + exf.list:mousereleased(x, y, b) +end + +function exf.getn(n) + local s = "" + n = tonumber(n) + local r = n + if r <= 0 then error("Example IDs must be bigger than 0. (Got: " .. r .. ")") end + if r >= 10000 then error("Example IDs must be less than 10000. (Got: " .. r .. ")") end + while r < 1000 do + s = s .. "0" + r = r * 10 + end + s = s .. n + return s +end + +function exf.intable(t, e) + for k, v in ipairs(t) do + if v == e then return true end + end + return false +end + +function exf.start(item, file) + local e_id = string.sub(item, 1, 4) + local e_rest = string.sub(item, 5) + local unused1, unused2, n = string.find(item, "(%s)%.lua") + + if exf.intable(exf.available, file) then + if not love.filesystem.exists("examples/" .. file) then + print("Could not load game .. " .. file) + else + + -- Clear all callbacks. + love.load = exf.empty + love.update = exf.empty + love.draw = exf.empty + love.keypressed = exf.empty + love.keyreleased = exf.empty + love.mousepressed = exf.empty + love.mousereleased = exf.empty + + love.filesystem.load("examples/" .. file)() + exf.clear() + + --love.window.setTitle(e_rest) + + -- Redirect keypress + local o_keypressed = love.keypressed + love.keypressed = + function(k) + if k == "escape" then + exf.resume() + end + o_keypressed(k) + end + + love.load() + end + else + print("Example ".. e_id .. " does not exist.") end +end - -- light world - lightRange = 400 - lightSmooth = 1.0 +function exf.clear() + love.graphics.setBackgroundColor(0,0,0) + love.graphics.setColor(255, 255, 255) + love.graphics.setLineWidth(1) + love.graphics.setLineStyle("smooth") + --love.graphics.setLine(1, "smooth") + --love.graphics.setColorMode("replace") + love.graphics.setBlendMode("alpha") + love.mouse.setVisible(true) +end + +function exf.resume() + load = nil + love.update = exf.update + love.draw = exf.draw + love.keypressed = exf.keypressed + love.keyreleased = exf.keyreleased + love.mousepressed = exf.mousepressed + love.mousereleased = exf.mousereleased + + love.mouse.setVisible(true) + love.window.setTitle("LOVE Example Browser") + + -- create light world lightWorld = love.light.newWorld() - lightWorld.setAmbientColor(15, 15, 31) - lightWorld.setRefractionStrength(16.0) - lightWorld.setReflectionVisibility(0.75) - mouseLight = lightWorld.newLight(0, 0, 255, 191, 127, lightRange) - mouseLight.setGlowStrength(0.3) - mouseLight.setSmooth(lightSmooth) - mouseLight.z = 63 - lightDirection = 0.0 - colorAberration = 0.0 + lightWorld.setAmbientColor(127, 127, 127) - -- init physic world - initScene() + -- create light + lightMouse = lightWorld.newLight(0, 0, 255, 127, 63, 500) + lightMouse.setSmooth(2) - helpOn = false - physicOn = false - lightOn = true - gravityOn = 1 - shadowBlur = 2.0 - bloomOn = 0.25 - textureOn = true - normalOn = false - glowBlur = 1.0 - effectOn = 0.0 - - offsetX = 0.0 - offsetY = 0.0 - offsetOldX = 0.0 - offsetOldY = 0.0 - offsetChanged = false - - tileX = 0 - tileY = 0 + -- create shadow bodys + circleTest = lightWorld.newCircle(800 - 128, 600 - 128, 46) end -function love.update(dt) - love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")") - mouseLight.setPosition(love.mouse.getX(), love.mouse.getY(), 16.0 + (math.sin(lightDirection) + 1.0) * 64.0) - mx = love.mouse.getX() - my = love.mouse.getY() - lightDirection = lightDirection + dt - colorAberration = math.max(0.0, colorAberration - dt * 10.0) +function inside(mx, my, x, y, w, h) + return mx >= x and mx <= (x+w) and my >= y and my <= (y+h) +end - if love.keyboard.isDown("w") then - for i = 1, phyCnt do - if phyBody[i] then - phyBody[i]:applyForce(0, -2000) - end - end - elseif love.keyboard.isDown("s") then - for i = 1, phyCnt do - if phyBody[i] then - phyBody[i]:applyForce(0, 2000) - end - end + +---------------------- +-- List object +---------------------- + +List = {} + +function List:new() + o = {} + setmetatable(o, self) + self.__index = self + + o.items = {} + o.files = {} + + o.x = 50 + o.y = 70 + + o.width = 400 + o.height = 500 + + o.item_height = 23 + o.sum_item_height = 0 + + o.bar_size = 20 + o.bar_pos = 0 + o.bar_max_pos = 0 + o.bar_width = 15 + o.bar_lock = nil + + return o +end + +function List:add(item, file) + table.insert(self.items, item) + table.insert(self.files, file) +end + +function List:done() + self.items.n = #self.items + + -- Recalc bar size. + self.bar_pos = 0 + + local num_items = (self.height/self.item_height) + local ratio = num_items/self.items.n + self.bar_size = self.height * ratio + self.bar_max_pos = self.height - self.bar_size - 3 + + -- Calculate height of everything. + self.sum_item_height = (self.item_height+1) * self.items.n + 2 +end + +function List:hasBar() + return self.sum_item_height > self.height +end + +function List:getBarRatio() + return self.bar_pos/self.bar_max_pos +end + +function List:getOffset() + local ratio = self.bar_pos/self.bar_max_pos + return math.floor((self.sum_item_height-self.height)*ratio + 0.5) +end + +function List:update(dt) + if self.bar_lock then + local dy = math.floor(love.mouse.getY()-self.bar_lock.y+0.5) + self.bar_pos = self.bar_pos + dy + + if self.bar_pos < 0 then + self.bar_pos = 0 + elseif self.bar_pos > self.bar_max_pos then + self.bar_pos = self.bar_max_pos end - if love.keyboard.isDown("a") then - for i = 1, phyCnt do - if phyBody[i] then - phyBody[i]:applyForce(-2000, 0) - end - end - elseif love.keyboard.isDown("d") then - for i = 1, phyCnt do - if phyBody[i] then - phyBody[i]:applyForce(2000, 0) - end - end + self.bar_lock.y = love.mouse.getY() + + end +end + +function List:mousepressed(mx, my, b) + if self:hasBar() then + if b == "l" then + local x, y, w, h = self:getBarRect() + if inside(mx, my, x, y, w, h) then + self.bar_lock = { x = mx, y = my } + end end - if love.keyboard.isDown("up") then - offsetY = offsetY + dt * 200 - elseif love.keyboard.isDown("down") then - offsetY = offsetY - dt * 200 - end + local per_pixel = (self.sum_item_height-self.height)/self.bar_max_pos + local bar_pixel_dt = math.floor(((self.item_height)*3)/per_pixel + 0.5) - if love.keyboard.isDown("left") then - offsetX = offsetX + dt * 200 - elseif love.keyboard.isDown("right") then - offsetX = offsetX - dt * 200 + if b == "wd" then + self.bar_pos = self.bar_pos + bar_pixel_dt + if self.bar_pos > self.bar_max_pos then self.bar_pos = self.bar_max_pos end + elseif b == "wu" then + self.bar_pos = self.bar_pos - bar_pixel_dt + if self.bar_pos < 0 then self.bar_pos = 0 end end - - if offsetX ~= offsetOldX or offsetY ~= offsetOldY then - offsetChanged = true - for i = 2, lightWorld.getLightCount() do - lightWorld.setLightPosition(i, lightWorld.getLightX(i) + (offsetX - offsetOldX), lightWorld.getLightY(i) + (offsetY - offsetOldY)) - end - else - offsetChanged = false - end - - for i = 1, lightWorld.getLightCount() do - lightWorld.setLightDirection(i, lightDirection) end - tileX = tileX + dt * 32.0 - tileY = tileY + dt * 8.0 + if b == "l" and inside(mx, my, self.x+2, self.y+1, self.width-3, self.height-3) then + local tx, ty = mx-self.x, my + self:getOffset() - self.y + local index = math.floor((ty/self.sum_item_height)*self.items.n) + local i = self.items[index+1] + local f = self.files[index+1] + if f then + exf.start(i, f) + end + end +end - for i = 1, phyCnt do - if phyBody[i] and (phyBody[i]:isAwake() or offsetChanged) then - if offsetChanged then - phyBody[i]:setX(phyBody[i]:getX() + (offsetX - offsetOldX)) - phyBody[i]:setY(phyBody[i]:getY() + (offsetY - offsetOldY)) - end - if phyLight[i].getType() == "polygon" then - phyLight[i].setPoints(phyBody[i]:getWorldPoints(phyShape[i]:getPoints())) - elseif phyLight[i].getType() == "circle" then - phyLight[i].setPosition(phyBody[i]:getX(), phyBody[i]:getY()) - elseif phyLight[i].getType() == "image" then - phyLight[i].setPosition(phyBody[i]:getX(), phyBody[i]:getY()) - elseif phyLight[i].getType() == "refraction" then - --phyLight[i].setPosition(phyBody[i]:getX(), phyBody[i]:getY()) - end +function List:mousereleased(x, y, b) + if self:hasBar() then + if b == "l" then + self.bar_lock = nil + end + end +end + +function List:getBarRect() + return + self.x+self.width+2, self.y+1+self.bar_pos, + self.bar_width-3, self.bar_size +end + +function List:getItemRect(i) + return + self.x+2, self.y+((self.item_height+1)*(i-1)+1)-self:getOffset(), + self.width-3, self.item_height +end + +function List:draw() + love.graphics.setLineWidth(2) + love.graphics.setLineStyle("rough") + love.graphics.setFont(self.font) + + love.graphics.setColor(48, 156, 225) + + local mx, my = love.mouse.getPosition() + + -- Get interval to display. + local start_i = math.floor( self:getOffset()/(self.item_height+1) ) + 1 + local end_i = start_i+math.floor( self.height/(self.item_height+1) ) + 1 + if end_i > self.items.n then end_i = self.items.n end + + + love.graphics.setScissor(self.x, self.y, self.width, self.height) + + -- Items. + for i = start_i,end_i do + local x, y, w, h = self:getItemRect(i) + local hover = inside(mx, my, x, y, w, h) + + if hover then + love.graphics.setColor(0, 0, 0, 127) + else + love.graphics.setColor(0, 0, 0, 63) end - if phyLight[i].getType() == "refraction" then - --if math.mod(i, 2) == 0 then - phyLight[i].setNormalTileOffset(tileX, tileY) - --end - if offsetChanged then - phyLight[i].setPosition(phyLight[i].getX() + (offsetX - offsetOldX), phyLight[i].getY() + (offsetY - offsetOldY)) - end + + love.graphics.rectangle("fill", x+1, y+i+1, w-3, h) + + if hover then + love.graphics.setColor(255, 255, 255) + else + love.graphics.setColor(255, 255, 255, 127) end + + local e_id = string.sub(self.items[i], 1, 5) + local e_rest = string.sub(self.items[i], 5) + + love.graphics.print(e_id, x+10, y+i+6) --Updated y placement -- Used to change position of Example IDs + love.graphics.print(e_rest, x+50, y+i+6) --Updated y placement -- Used to change position of Example Titles end - if physicOn then - physicWorld:update(dt) - end + love.graphics.setScissor() - offsetOldX = offsetX - offsetOldY = offsetY -end + -- Bar. + if self:hasBar() then + local x, y, w, h = self:getBarRect() + local hover = inside(mx, my, x, y, w, h) -function love.draw() - -- update lightmap (don't need deltatime) - if lightOn then - lightWorld.update() - end - - -- set shader buffer - if bloomOn then - love.postshader.setBuffer("render") - end - - love.graphics.setBlendMode("alpha") - if normalOn then - love.graphics.setColor(127, 127, 255) - love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + if hover or self.bar_lock then + love.graphics.setColor(0, 0, 0, 127) else - love.graphics.setColor(255, 255, 255) - if textureOn then - love.graphics.draw(imgFloor, quadScreen, offsetX % 32 - 32, offsetY % 24 - 24) - else - love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) - end + love.graphics.setColor(0, 0, 0, 63) end + love.graphics.rectangle("fill", x, y, w, h) + end - for i = 1, phyCnt do - if phyLight[i].getType() == "refraction" then - if not normalOn then - --if math.mod(i, 2) == 0 then - love.graphics.setBlendMode("alpha") - love.graphics.setColor(255, 255, 255, 191) - love.graphics.draw(water, phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy) - --else - --love.graphics.setBlendMode("multiplicative") - --math.randomseed(i) - --love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) - --love.graphics.rectangle("fill", phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy, 128, 128) - --end - end - end - end - - -- draw lightmap shadows - if lightOn and not normalOn then - lightWorld.drawShadow() - end - - for i = 1, phyCnt do - math.randomseed(i) - love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) - if phyLight[i].getType() == "polygon" then - love.graphics.polygon("fill", phyLight[i].getPoints()) - elseif phyLight[i].getType() == "circle" then - love.graphics.circle("fill", phyLight[i].getX(), phyLight[i].getY(), phyLight[i].getRadius()) - end - end - - -- draw lightmap shine - if lightOn and not normalOn then - lightWorld.drawShine() - end - - love.graphics.setBlendMode("alpha") - for i = 1, phyCnt do - if phyLight[i].getType() == "image" then - if normalOn and phyLight[i].normal then - love.graphics.setColor(255, 255, 255) - love.graphics.draw(phyLight[i].normal, phyLight[i].x - phyLight[i].nx, phyLight[i].y - phyLight[i].ny) - elseif not phyLight[i].material then - math.randomseed(i) - love.graphics.setColor(math.random(127, 255), math.random(127, 255), math.random(127, 255)) - love.graphics.draw(phyLight[i].img, phyLight[i].x - phyLight[i].ix, phyLight[i].y - phyLight[i].iy) - end - end - end - - if not normalOn then - lightWorld.drawMaterial() - end - - -- draw pixel shadow - if lightOn and not normalOn then - lightWorld.drawPixelShadow() - end - - -- draw glow - if lightOn and not normalOn then - lightWorld.drawGlow() - end - - -- draw reflection - lightWorld.drawReflection() - - -- draw refraction - lightWorld.drawRefraction() - - love.graphics.draw(imgLight, mx - 5, (my - 5) - (16.0 + (math.sin(lightDirection) + 1.0) * 64.0)) - - -- draw help - if helpOn then - love.graphics.setBlendMode("alpha") - love.graphics.setColor(0, 0, 0, 191) - love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), 44) - love.graphics.rectangle("fill", 0, love.graphics.getHeight() - 68, 240, 68) - love.graphics.rectangle("fill", love.graphics.getWidth() - 244, love.graphics.getHeight() - 84, 244, 84) - love.graphics.setColor(0, 255, 0) - love.graphics.print("F1: Help (on)", 4 + 152 * 0, 4) - if physicOn then - love.graphics.setColor(0, 255, 0) - love.graphics.print("F2: Physic (on)", 4 + 152 * 1, 4) - else - love.graphics.setColor(255, 0, 0) - love.graphics.print("F2: Physic (off)", 4 + 152 * 1, 4) - end - if lightOn then - love.graphics.setColor(0, 255, 0) - love.graphics.print("F3: Light (on)", 4 + 152 * 2, 4) - else - love.graphics.setColor(255, 0, 0) - love.graphics.print("F3: Light (off)", 4 + 152 * 2, 4) - end - if gravityOn == 1.0 then - love.graphics.setColor(0, 255, 0) - love.graphics.print("F4: Gravity (on)", 4 + 152 * 3, 4) - else - love.graphics.setColor(255, 0, 0) - love.graphics.print("F4: Gravity (off)", 4 + 152 * 3, 4) - end - if shadowBlur >= 1.0 then - love.graphics.setColor(0, 255, 0) - love.graphics.print("F5: Shadowblur (" .. shadowBlur .. ")", 4 + 152 * 4, 4) - else - love.graphics.setColor(255, 0, 0) - love.graphics.print("F5: Shadowblur (off)", 4 + 152 * 4, 4) - end - if bloomOn > 0.0 then - love.graphics.setColor(0, 255, 0) - love.graphics.print("F6: Bloom (" .. (bloomOn * 4) .. ")", 4 + 152 * 0, 4 + 20 * 1) - else - love.graphics.setColor(255, 0, 0) - love.graphics.print("F6: Bloom (off)", 4 + 152 * 0, 4 + 20 * 1) - end - if textureOn then - love.graphics.setColor(0, 255, 0) - love.graphics.print("F7: Texture (on)", 4 + 152 * 1, 4 + 20 * 1) - else - love.graphics.setColor(255, 0, 0) - love.graphics.print("F7: Texture (off)", 4 + 152 * 1, 4 + 20 * 1) - end - if normalOn then - love.graphics.setColor(0, 255, 0) - love.graphics.print("F8: Normal (on)", 4 + 152 * 2, 4 + 20 * 1) - else - love.graphics.setColor(255, 0, 0) - love.graphics.print("F8: Normal (off)", 4 + 152 * 2, 4 + 20 * 1) - end - if glowBlur >= 1.0 then - love.graphics.setColor(0, 255, 0) - love.graphics.print("F9: Glow Blur (" .. glowBlur .. ")", 4 + 152 * 3, 4 + 20 * 1) - else - love.graphics.setColor(255, 0, 0) - love.graphics.print("F9: Glow Blur (off)", 4 + 152 * 3, 4 + 20 * 1) - end - if effectOn >= 1.0 then - love.graphics.setColor(0, 255, 0) - love.graphics.print("F10: Effects (" .. effectOn .. ")", 4 + 152 * 4, 4 + 20 * 1) - else - love.graphics.setColor(255, 0, 0) - love.graphics.print("F10: Effects (off)", 4 + 152 * 4, 4 + 20 * 1) - end - love.graphics.setColor(255, 0, 255) - love.graphics.print("F11: Clear obj.", 4 + 152 * 4, 4 + 20 * 2) - love.graphics.print("F12: Clear lights", 4 + 152 * 4, 4 + 20 * 3) - love.graphics.setColor(0, 127, 255) - love.graphics.print("WASD Keys: Move objects", 4, love.graphics.getHeight() - 20 * 3) - love.graphics.print("Arrow Keys: Move map", 4, love.graphics.getHeight() - 20 * 2) - love.graphics.print("0-9 Keys: Add object", 4, love.graphics.getHeight() - 20 * 1) - love.graphics.setColor(255, 127, 0) - love.graphics.print("M.left: Add cube", love.graphics.getWidth() - 240, love.graphics.getHeight() - 20 * 4) - love.graphics.print("M.middle: Add light", love.graphics.getWidth() - 240, love.graphics.getHeight() - 20 * 3) - love.graphics.print("M.right: Add circle", love.graphics.getWidth() - 240, love.graphics.getHeight() - 20 * 2) - love.graphics.print("M.scroll: Change smooth", love.graphics.getWidth() - 240, love.graphics.getHeight() - 20 * 1) - love.graphics.setColor(255, 127, 0) - else - love.graphics.setColor(255, 255, 255, 191) - love.graphics.print("F1: Help", 4, 4) - end - - -- draw shader - if colorAberration > 0.0 then - -- vert / horz blur - love.postshader.addEffect("blur", 2.0, 2.0) - love.postshader.addEffect("chromatic", math.sin(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * colorAberration, math.sin(lightDirection * 10.0) * -colorAberration, math.sin(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * -colorAberration) - end - - if bloomOn > 0.0 then - -- blur, strength - love.postshader.addEffect("bloom", 2.0, bloomOn) - end - - if effectOn == 1.0 then - love.postshader.addEffect("4colors", {15, 56, 15}, {48, 98, 48}, {139, 172, 15}, {155, 188, 15}) - --love.postshader.addEffect("4colors", {108, 108, 78}, {142, 139, 87}, {195, 196, 165}, {227, 230, 201}) - elseif effectOn == 2.0 then - love.postshader.addEffect("monochrom") - elseif effectOn == 3.0 then - love.postshader.addEffect("scanlines") - elseif effectOn == 4.0 then - love.postshader.addEffect("tiltshift", 4.0) - end - - love.postshader.draw() + -- Border. + love.graphics.setColor(0, 0, 0, 63) + love.graphics.rectangle("line", self.x+self.width, self.y, self.bar_width, self.height) + love.graphics.rectangle("line", self.x, self.y, self.width, self.height) end - -function love.mousepressed(x, y, c) - if c == "m" then - -- add light - local r = lightWorld.getLightCount() % 3 - local light - - if r == 0 then - light = lightWorld.newLight(x, y, 31, 127, 63, lightRange) - elseif r == 1 then - light = lightWorld.newLight(x, y, 127, 63, 31, lightRange) - else - light = lightWorld.newLight(x, y, 31, 63, 127, lightRange) - end - light.setSmooth(lightSmooth) - light.setGlowStrength(0.3) - elseif c == "l" then - -- add rectangle - math.randomseed(love.timer.getTime()) - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newPolygon() - phyBody[phyCnt] = love.physics.newBody(physicWorld, x, y, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, math.random(32, 64), math.random(32, 64)) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif c == "r" then - -- add circle - math.randomseed(love.timer.getTime()) - cRadius = math.random(8, 32) - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newCircle(x, y, cRadius) - phyBody[phyCnt] = love.physics.newBody(physicWorld, x, y, "dynamic") - phyShape[phyCnt] = love.physics.newCircleShape(0, 0, cRadius) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif c == "wu" then - if lightSmooth < 4.0 then - lightSmooth = lightSmooth * 1.1 - mouseLight.setSmooth(lightSmooth) - end - elseif c == "wd" then - if lightSmooth > 0.5 then - lightSmooth = lightSmooth / 1.1 - mouseLight.setSmooth(lightSmooth) - end - end -end - -function love.keypressed(k, u) - -- debug options - if k == "f1" then - helpOn = not helpOn - elseif k == "f2" then - physicOn = not physicOn - elseif k == "f3" then - lightOn = not lightOn - elseif k == "f4" then - gravityOn = 1 - gravityOn - physicWorld:setGravity(0, gravityOn * 9.81 * 64) - elseif k == "f5" then - shadowBlur = math.max(1, shadowBlur * 2.0) - if shadowBlur > 8.0 then - shadowBlur = 0.0 - end - lightWorld.setBlur(shadowBlur) - elseif k == "f6" or k == "b" then - bloomOn = math.max(0.25, bloomOn * 2.0) - if bloomOn > 1.0 then - bloomOn = 0.0 - end - elseif k == "f7" then - textureOn = not textureOn - elseif k == "f8" then - normalOn = not normalOn - elseif k == "f9" then - glowBlur = glowBlur + 1.0 - if glowBlur > 8.0 then - glowBlur = 0.0 - end - lightWorld.setGlowStrength(glowBlur) - elseif k == "f10" then - effectOn = effectOn + 1.0 - if effectOn > 4.0 then - effectOn = 0.0 - end - elseif k == "f11" then - physicWorld:destroy() - lightWorld.clearBodys() - initScene() - elseif k == "f12" then - lightWorld.clearLights() - mouseLight = lightWorld.newLight(0, 0, 255, 191, 127, lightRange) - mouseLight.setGlowStrength(0.3) - mouseLight.setSmooth(lightSmooth) - elseif k == "1" then - -- add image - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(circle, mx, my) - phyLight[phyCnt].setNormalMap(circle_normal) - phyLight[phyCnt].setShadowType("circle", 16) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 32) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif k == "2" then - local r = lightWorld.getBodyCount() % 2 - if r == 0 then - -- add image - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(cone, mx, my, 24, 12, 12, 16) - phyLight[phyCnt].setNormalMap(cone_normal) - phyLight[phyCnt].setShadowType("circle", 12, 0, -8) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 24, 32) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif r == 1 then - -- add image - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(chest, mx, my, 32, 24, 16, 0) - phyLight[phyCnt].setNormalMap(chest_normal) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 24) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - end - elseif k == "3" then - -- add image - local r = lightWorld.getBodyCount() % #material - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(ape, mx, my, 160, 128, 80, 64) - phyLight[phyCnt].setNormalMap(ape_normal) - if r == 3 then - phyLight[phyCnt].setGlowMap(ape_glow) - end - phyLight[phyCnt].setMaterial(material[r + 1]) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 24) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - phyLight[phyCnt].setShadowType("image", 0, -16, 0.0) - elseif k == "4" then - -- add glow image - local r = lightWorld.getBodyCount() % 5 - if r == 0 then - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(machine, mx, my, 32, 24, 16, 0) - phyLight[phyCnt].setNormalMap(machine_normal) - phyLight[phyCnt].setGlowMap(machine_glow) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 24) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif r == 1 then - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(machine2, mx, my, 24, 12, 12, -4) - phyLight[phyCnt].setNormalMap(machine2_normal) - phyLight[phyCnt].setGlowMap(machine2_glow) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 24, 32) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif r == 2 then - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(led, mx, my, 32, 6, 16, -8) - phyLight[phyCnt].setNormalMap(led_normal) - phyLight[phyCnt].setGlowMap(led_glow) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 6) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif r == 3 then - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(led2, mx, my, 32, 6, 16, -8) - phyLight[phyCnt].setNormalMap(led_normal) - phyLight[phyCnt].setGlowMap(led_glow2) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 6) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif r == 4 then - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(led3, mx, my, 32, 6, 16, -8) - phyLight[phyCnt].setNormalMap(led_normal) - phyLight[phyCnt].setGlowMap(led_glow3) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 6) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - end - elseif k == "5" then - -- add image - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(cone_large, mx, my, 24, 128, 12, 64) - phyLight[phyCnt].setNormalMap(cone_large_normal) - phyLight[phyCnt].setShadowType("image", 0, -6, 0.0) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 24, 32) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif k == "6" then - -- add image - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(blopp, mx, my, 42, 16, 21, 0) - phyLight[phyCnt].generateNormalMapGradient("gradient", "gradient") - phyLight[phyCnt].setAlpha(0.5) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 42, 29) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif k == "7" then - -- add image - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newImage(tile, mx, my) - phyLight[phyCnt].setHeightMap(tile_normal, 2.0) - phyLight[phyCnt].setGlowMap(tile_glow) - phyLight[phyCnt].setShadow(false) - phyLight[phyCnt].reflective = false - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 64, 64) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif k == "8" then - -- add rectangle - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newPolygon() - phyLight[phyCnt].setAlpha(0.5) - phyLight[phyCnt].setGlowStrength(1.0) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - math.randomseed(love.timer.getTime()) - phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, math.random(32, 64), math.random(32, 64)) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - math.randomseed(phyCnt) - phyLight[phyCnt].setGlowColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) - math.randomseed(phyCnt) - phyLight[phyCnt].setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) - elseif k == "9" then - -- add circle - math.randomseed(love.timer.getTime()) - cRadius = math.random(8, 32) - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newCircle(mx, my, cRadius) - phyLight[phyCnt].setAlpha(0.5) - phyLight[phyCnt].setGlowStrength(1.0) - math.randomseed(phyCnt) - phyLight[phyCnt].setGlowColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) - math.randomseed(phyCnt) - phyLight[phyCnt].setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) - phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") - phyShape[phyCnt] = love.physics.newCircleShape(0, 0, cRadius) - phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) - phyFixture[phyCnt]:setRestitution(0.5) - elseif k == "0" then - phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newRefraction(refraction_normal, mx, my) - phyLight[phyCnt].setReflection(true) - elseif k == "l" then - -- add light - local r = lightWorld.getLightCount() % 3 - local light - - if r == 0 then - light = lightWorld.newLight(mx, my, 31, 127, 63, lightRange) - elseif r == 1 then - light = lightWorld.newLight(mx, my, 127, 63, 31, lightRange) - else - light = lightWorld.newLight(mx, my, 31, 63, 127, lightRange) - end - light.setSmooth(lightSmooth) - light.setGlowStrength(0.3) - math.randomseed(love.timer.getTime()) - light.setAngle(math.random(1, 5) * 0.1 * math.pi) - elseif k == "c" then - if colorAberration == 0.0 then - colorAberration = 3.0 - end - end -end \ No newline at end of file diff --git a/shader/monochrom.glsl b/shader/monochrom.glsl index 43297bd..d4bc55b 100644 --- a/shader/monochrom.glsl +++ b/shader/monochrom.glsl @@ -1,4 +1,6 @@ extern float time = 0.0; +extern vec3 tint = vec3(1.0, 1.0, 1.0); +extern float fudge = 0.1; float rand(vec2 position, float seed) { return fract(sin(dot(position.xy,vec2(12.9898, 78.233))) * seed); @@ -6,6 +8,6 @@ float rand(vec2 position, float seed) { vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ vec4 pixel = Texel(texture, texture_coords); - - return vec4(vec3((pixel.r + pixel.g + pixel.b) / 3.0) + (rand(texture_coords, time) - 0.5) * 0.1, 1.0); + float intensity = (pixel.r + pixel.g + pixel.b) / 3.0 + (rand(texture_coords, time) - 0.5) * fudge; + return vec4(intensity * tint.r, intensity * tint.g, intensity * tint.b, 1.0); } \ No newline at end of file diff --git a/shader/scanlines.glsl b/shader/scanlines.glsl index 9fa370c..0f677aa 100644 --- a/shader/scanlines.glsl +++ b/shader/scanlines.glsl @@ -1,22 +1,24 @@ extern vec2 screenHeight = vec2(800.0, 600.0); +extern float strength = 2.0; extern float time = 0.0; vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ vec2 pSize = 1.0 / screenHeight; float brightness = 1.0; - float offsetX = sin(texture_coords.y * 10.0 + time * 2.0) * pSize.x; + float offsetX = sin(texture_coords.y * 10.0 + time * strength) * pSize.x; + float corner = 500.0; if(texture_coords.x < 0.5) { if(texture_coords.y < 0.5) { - brightness = min(texture_coords.x * texture_coords.y * 100.0, 1.0); + brightness = min(texture_coords.x * texture_coords.y * corner, 1.0); } else { - brightness = min(texture_coords.x * (1.0 - texture_coords.y) * 100.0, 1.0); + brightness = min(texture_coords.x * (1.0 - texture_coords.y) * corner, 1.0); } } else { if(texture_coords.y < 0.5) { - brightness = min((1.0 - texture_coords.x) * texture_coords.y * 100.0, 1.0); + brightness = min((1.0 - texture_coords.x) * texture_coords.y * corner, 1.0); } else { - brightness = min((1.0 - texture_coords.x) * (1.0 - texture_coords.y) * 100.0, 1.0); + brightness = min((1.0 - texture_coords.x) * (1.0 - texture_coords.y) * corner, 1.0); } } float red = Texel(texture, vec2(texture_coords.x + offsetX, texture_coords.y + pSize.y * 0.5)).r; diff --git a/shader/tilt_shift.glsl b/shader/tilt_shift.glsl index d0df84f..4fb3e00 100644 --- a/shader/tilt_shift.glsl +++ b/shader/tilt_shift.glsl @@ -1,12 +1,12 @@ -extern Image buffer; +extern Image imgBuffer; vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ vec4 pixel = Texel(texture, texture_coords); - vec4 pixel2 = Texel(buffer, texture_coords); + vec4 pixelBuffer = Texel(imgBuffer, texture_coords); if(texture_coords.y > 0.5) { - return vec4(pixel.rgb * (texture_coords.y - 0.5) * 2.0 + pixel2.rgb * (1.0 - texture_coords.y) * 2.0, 1.0); + return vec4(pixel.rgb * (texture_coords.y - 0.5) * 2.0 + pixelBuffer.rgb * (1.0 - texture_coords.y) * 2.0, 1.0); } else { - return vec4(pixel.rgb * (0.5 - texture_coords.y) * 2.0 + pixel2.rgb * texture_coords.y * 2.0, 1.0); + return vec4(pixel.rgb * (0.5 - texture_coords.y) * 2.0 + pixelBuffer.rgb * texture_coords.y * 2.0, 1.0); } } \ No newline at end of file