From 9d48adb46b85ec77045a18cea282966e2db7286d Mon Sep 17 00:00:00 2001 From: "jiangzhi.xie" Date: Sat, 7 Sep 2019 19:36:40 +0800 Subject: [PATCH] Fix colors --- examples/complex.lua | 100 +++++++++++++------------- examples/hump.lua | 6 +- lib/body.lua | 98 +++++++++++++------------ lib/init.lua | 27 ++++--- lib/light.lua | 22 ++++-- lib/normal_map.lua | 50 +++++++------ lib/postshader.lua | 8 ++- lib/shaders/postshaders/phosphor.glsl | 23 +++--- lib/util.lua | 16 +++-- main.lua | 4 +- 10 files changed, 194 insertions(+), 160 deletions(-) diff --git a/examples/complex.lua b/examples/complex.lua index c0566c4..9c1f483 100644 --- a/examples/complex.lua +++ b/examples/complex.lua @@ -96,7 +96,7 @@ function love.load() shadowBlur = 2.0 }) - mouseLight = lightWorld:newLight(0, 0, 255, 191, 127, lightRange) + mouseLight = lightWorld:newLight(0, 0, 1, 191/ 255, 0.5, lightRange) mouseLight:setGlowStrength(0.3) mouseLight:setSmooth(lightSmooth) mouseLight.z = 63 @@ -162,19 +162,19 @@ function love.update(dt) tileX = tileX + dt * 32.0 tileY = tileY + dt * 8.0 - for i = 1, phyCnt do - if phyLight[i]:getType() == "refraction" then - phyLight[i]:setNormalTileOffset(tileX, tileY) - end + for i = 1, phyCnt do + if phyLight[i]:getType() == "refraction" then + phyLight[i]:setNormalTileOffset(tileX, tileY) + end end -- draw shader if colorAberration > 0.0 then -- vert / horz blur lightWorld.post_shader:addEffect("blur", 2.0, 2.0) - lightWorld.post_shader:addEffect("chromatic_aberration", - {math.sin(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * colorAberration}, - {math.cos(lightDirection * 10.0) * colorAberration, math.sin(lightDirection * 10.0) * -colorAberration}, + lightWorld.post_shader:addEffect("chromatic_aberration", + {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}) else lightWorld.post_shader:removeEffect("blur") @@ -199,10 +199,10 @@ function love.draw() lightWorld:draw(function(l, t, w, h, s) love.graphics.setBlendMode("alpha") if normalOn then - love.graphics.setColor(127, 127, 255) + love.graphics.setColor(0.5, 0.5, 1) love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) else - love.graphics.setColor(255, 255, 255) + love.graphics.setColor(1, 1, 1) if textureOn then love.graphics.draw(imgFloor, quadScreen, 0,0) else @@ -214,7 +214,7 @@ function love.draw() if phyLight[i]:getType() == "refraction" then if not normalOn then love.graphics.setBlendMode("alpha") - love.graphics.setColor(255, 255, 255, 191) + love.graphics.setColor(1, 1, 1, 191/255) love.graphics.draw(water, phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy) end end @@ -224,20 +224,22 @@ function love.draw() for i = 1, phyCnt do if phyLight[i]:getType() == "polygon" then math.randomseed(i) - love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + love.graphics.setColor(math.random(), math.random(), math.random()) love.graphics.polygon("fill", phyLight[i]:getPoints()) elseif phyLight[i]:getType() == "circle" then math.randomseed(i) - love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + love.graphics.setColor(math.random(), math.random(), math.random()) local cx, cy = phyLight[i]:getPosition() love.graphics.circle("fill", cx, cy, phyLight[i]:getRadius()) elseif phyLight[i]:getType() == "image" then if normalOn and phyLight[i].normal then - love.graphics.setColor(255, 255, 255) + love.graphics.setColor(1, 1, 1) 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.setColor( + math.random(127, 255) / 255, math.random(127, 255)/ 255, math.random(127, 255) / 255 + ) love.graphics.draw(phyLight[i].img, phyLight[i].x - phyLight[i].ix, phyLight[i].y - phyLight[i].iy) end end @@ -254,65 +256,65 @@ function love.draw() 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.setColor(0, 1, 0) love.graphics.print("F1: Help (on)", 4 + 152 * 0, 4) if shadowBlur >= 1.0 then - love.graphics.setColor(0, 255, 0) + love.graphics.setColor(0, 1, 0) love.graphics.print("F5: Shadowblur (" .. shadowBlur .. ")", 4 + 152 * 4, 4) else - love.graphics.setColor(255, 0, 0) + love.graphics.setColor(1, 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.setColor(0, 1, 0) love.graphics.print("F6: Bloom (" .. (bloomOn * 4) .. ")", 4 + 152 * 0, 4 + 20 * 1) else - love.graphics.setColor(255, 0, 0) + love.graphics.setColor(1, 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.setColor(0, 1, 0) love.graphics.print("F7: Texture (on)", 4 + 152 * 1, 4 + 20 * 1) else - love.graphics.setColor(255, 0, 0) + love.graphics.setColor(1, 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.setColor(0, 1, 0) love.graphics.print("F8: Normal (on)", 4 + 152 * 2, 4 + 20 * 1) else - love.graphics.setColor(255, 0, 0) + love.graphics.setColor(1, 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.setColor(0, 1, 0) love.graphics.print("F9: Glow Blur (" .. glowBlur .. ")", 4 + 152 * 3, 4 + 20 * 1) else - love.graphics.setColor(255, 0, 0) + love.graphics.setColor(1, 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.setColor(0, 1, 0) love.graphics.print("F10: Effects (" .. effectOn .. ")", 4 + 152 * 4, 4 + 20 * 1) else - love.graphics.setColor(255, 0, 0) + love.graphics.setColor(1, 0, 0) love.graphics.print("F10: Effects (off)", 4 + 152 * 4, 4 + 20 * 1) end - love.graphics.setColor(255, 0, 255) + love.graphics.setColor(1, 0, 1) 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.setColor(0, 0.5, 1) 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.setColor(1, 0.5, 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) + love.graphics.setColor(1, 0.5, 0) else - love.graphics.setColor(255, 255, 255, 191) + love.graphics.setColor(1, 1, 1, 191/255) love.graphics.print("F1: Help", 4, 4) end end @@ -324,11 +326,11 @@ function love.mousepressed(x, y, c) local light if r == 0 then - light = lightWorld:newLight(x, y, 31, 127, 63, lightRange) + light = lightWorld:newLight(x, y, 31/ 255, 0.5, 63/ 255, lightRange) elseif r == 1 then - light = lightWorld:newLight(x, y, 127, 63, 31, lightRange) + light = lightWorld:newLight(x, y, 0.5, 63/255, 31/255, lightRange) else - light = lightWorld:newLight(x, y, 31, 63, 127, lightRange) + light = lightWorld:newLight(x, y, 31/255, 63/255, 127/255, lightRange) end light:setSmooth(lightSmooth) light:setGlowStrength(0.3) @@ -424,7 +426,7 @@ function love.keypressed(k, u) initScene() elseif k == "f12" then lightWorld:clearLights() - mouseLight = lightWorld:newLight(0, 0, 255, 191, 127, lightRange) + mouseLight = lightWorld:newLight(0, 0, 1, 191/255, 0.5, lightRange) mouseLight:setGlowStrength(0.3) mouseLight:setSmooth(lightSmooth) elseif k == "1" then @@ -498,7 +500,7 @@ function love.keypressed(k, u) phyCnt = phyCnt + 1 phyLight[phyCnt] = lightWorld:newImage(blopp, mx, my, 42, 16, 21, 0) phyLight[phyCnt]:generateNormalMapGradient("gradient", "gradient") - phyLight[phyCnt]:setAlpha(255 * 0.5) + phyLight[phyCnt]:setAlpha(0.5) elseif k == "7" then -- add image phyCnt = phyCnt + 1 @@ -517,24 +519,24 @@ function love.keypressed(k, u) mx+w, my+h, mx, my+h ) - phyLight[phyCnt]:setAlpha(255 * 0.5) + 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)) + phyLight[phyCnt]:setGlowColor(math.random(), math.random(), math.random()) math.randomseed(phyCnt) - phyLight[phyCnt]:setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + phyLight[phyCnt]:setColor(math.random(), math.random(), math.random()) 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(255 * 0.5) + 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)) + phyLight[phyCnt]:setGlowColor(math.random(), math.random(), math.random()) math.randomseed(phyCnt) - phyLight[phyCnt]:setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + phyLight[phyCnt]:setColor(math.random(), math.random(), math.random()) elseif k == "0" then phyCnt = phyCnt + 1 phyLight[phyCnt] = lightWorld:newRefraction(refraction_normal, mx, my) @@ -545,11 +547,11 @@ function love.keypressed(k, u) local light if r == 0 then - light = lightWorld:newLight(mx, my, 31, 127, 63, lightRange) + light = lightWorld:newLight(mx, my, 31/255, 127 / 255, 63 / 255, lightRange) elseif r == 1 then - light = lightWorld:newLight(mx, my, 127, 63, 31, lightRange) + light = lightWorld:newLight(mx, my, 127 / 255, 63 / 255, 31 / 255, lightRange) else - light = lightWorld:newLight(mx, my, 31, 63, 127, lightRange) + light = lightWorld:newLight(mx, my, 31 / 255, 63 / 255, 127 / 255, lightRange) end light:setSmooth(lightSmooth) light:setGlowStrength(0.3) @@ -559,9 +561,9 @@ function love.keypressed(k, u) local light if r == 0 then - light = lightWorld:newLight(mx, my, 31, 127, 63, lightRange) + light = lightWorld:newLight(mx, my, 31/255, 127/255, 63/255, lightRange) elseif r == 1 then - light = lightWorld:newLight(mx, my, 127, 63, 31, lightRange) + light = lightWorld:newLight(mx, my, 127/255, 63/255, 31/255, lightRange) else light = lightWorld:newLight(mx, my, 31, 63, 127, lightRange) end diff --git a/examples/hump.lua b/examples/hump.lua index 04b69cd..c95628d 100644 --- a/examples/hump.lua +++ b/examples/hump.lua @@ -70,13 +70,13 @@ end function love.draw() cam:attach() lightWorld:draw(function() - love.graphics.setColor(255, 255, 255) + love.graphics.setColor(1, 1, 1) love.graphics.rectangle("fill", -x/scale, -y/scale, love.graphics.getWidth()/scale, love.graphics.getHeight()/scale) - love.graphics.setColor(63, 255, 127) + love.graphics.setColor(63/ 255, 1, 0.5) local cx, cy = circleTest:getPosition() love.graphics.circle("fill", cx, cy, circleTest:getRadius()) love.graphics.polygon("fill", rectangleTest:getPoints()) - love.graphics.setColor(255, 255, 255) + love.graphics.setColor(1, 1, 1) love.graphics.draw(image, 64 - image:getWidth() * 0.5, 64 - image:getHeight() * 0.5) end) cam:detach() diff --git a/lib/body.lua b/lib/body.lua index 52a12c8..c35d806 100644 --- a/lib/body.lua +++ b/lib/body.lua @@ -20,9 +20,9 @@ local function new(id, type, ...) obj.green = 1.0 obj.blue = 1.0 obj.alpha = 1.0 - obj.glowRed = 255 - obj.glowGreen = 255 - obj.glowBlue = 255 + obj.glowRed = 1 + obj.glowGreen = 1 + obj.glowBlue = 1 obj.glowStrength = 0.0 obj.tileX = 0 obj.tileY = 0 @@ -31,7 +31,7 @@ local function new(id, type, ...) obj.rotation = 0 obj.scalex = 1 obj.scaley = 1 - + obj.castsNoShadow = false obj.visible = true obj.is_on_screen = true @@ -41,10 +41,10 @@ local function new(id, type, ...) obj.y = args[2] or 0 circle_canvas = love.graphics.newCanvas(args[3]*2, args[3]*2) - util.drawto(circle_canvas, 0, 0, 1, function() - love.graphics.circle('fill', args[3], args[3], args[3]) + util.drawto(circle_canvas, 0, 0, 1, false, function() + love.graphics.circle('fill', args[3], args[3], args[3]) end) - obj.img = love.graphics.newImage(circle_canvas:newImageData()) + obj.img = love.graphics.newImage(circle_canvas:newImageData()) obj.imgWidth = obj.img:getWidth() obj.imgHeight = obj.img:getHeight() obj.ix = obj.imgWidth * 0.5 @@ -130,13 +130,13 @@ function body:refresh() end function body:has_changed() - return self:position_changed() or - self:rotation_changed() or + return self:position_changed() or + self:rotation_changed() or self:scale_changed() end function body:position_changed() - return self.old_x ~= self.x or + return self.old_x ~= self.x or self.old_y ~= self.y end @@ -157,12 +157,12 @@ end function body:newGrid(frameWidth, frameHeight, imageWidth, imageHeight, left, top, border) return anim8.newGrid( - frameWidth, frameHeight, - imageWidth or self.img:getWidth(), imageHeight or self.img:getHeight(), + frameWidth, frameHeight, + imageWidth or self.img:getWidth(), imageHeight or self.img:getHeight(), left, top, border ) end --- frameWidth, frameHeight, imageWidth, imageHeight, left, top, border +-- frameWidth, frameHeight, imageWidth, imageHeight, left, top, border function body:addAnimation(name, frames, durations, onLoop) self.animations[name] = anim8.newAnimation(frames, durations, onLoop) @@ -193,7 +193,7 @@ function body:update(dt) local frame = self.animation.frames[self.animation.position] _,_,self.width, self.height = frame:getViewport() self.imgWidth, self.imgHeight = self.width, self.height - self.normalWidth, self.normalHeight = self.width, self.height + self.normalWidth, self.normalHeight = self.width, self.height self.ix, self.iy = self.imgWidth * 0.5,self.imgHeight * 0.5 self.nx, self.ny = self.ix, self.iy self.animation:update(dt) @@ -286,10 +286,14 @@ function body:setNormalOffset(nx, ny) end -- set glow color -function body:setGlowColor(red, green, blue) - self.glowRed = red - self.glowGreen = green - self.glowBlue = blue +function body:setGlowColor(r, g, b) + if r > 1 then r = r / 255 end + if g > 1 then g = r / 255 end + if b > 1 then b = r / 255 end + + self.glowRed = r + self.glowGreen = g + self.glowBlue = b end -- set glow alpha @@ -337,8 +341,8 @@ function body:setPoints(...) self.y = self.y + (self.height * 0.5) local poly_canvas = love.graphics.newCanvas(self.width, self.height) - util.drawto(poly_canvas, 0, 0, 1, function() - love.graphics.polygon('fill', self.unit_data) + util.drawto(poly_canvas, 0, 0, 1, false, function() + love.graphics.polygon('fill', self.unit_data) end) --normalize points to be around the center x y @@ -347,14 +351,14 @@ function body:setPoints(...) end if not self.img then - self.img = love.graphics.newImage(poly_canvas:newImageData()) + self.img = love.graphics.newImage(poly_canvas:newImageData()) self.imgWidth = self.img:getWidth() self.imgHeight = self.img:getHeight() self.ix = self.imgWidth * 0.5 self.iy = self.imgHeight * 0.5 self:generateNormalMapFlat("top") end - --wrapping with polygon normals causes edges to show + --wrapping with polygon normals causes edges to show --also we do not need wrapping for this default normal map self.normal:setWrap("clamp", "clamp") self.shadowType = "polygon" @@ -377,10 +381,14 @@ function body:setShine(b) end -- set glass color -function body:setColor(red, green, blue) - self.red = red - self.green = green - self.blue = blue +function body:setColor(r, g, b) + if r > 1 then r = r / 255 end + if g > 1 then g = r / 255 end + if b > 1 then b = r / 255 end + + self.red = r + self.green = g + self.blue = b end -- set glass alpha @@ -544,7 +552,7 @@ function body:isVisible() end function body:inLightRange(light) - local l, t, w = light.x - light.range, light.y - light.range, light.range*2 + local l, t, w = light.x - light.range, light.y - light.range, light.range*2 return self:inRange(l,t,w,w,1) end @@ -557,7 +565,7 @@ function body:inRange(l, t, w, h, s) local sh = (self.height * self.scaley) radius = (sw > sh and sw or sh) end - + local bx, by, bw, bh = self.x - radius, self.y - radius, radius * 2, radius * 2 return self.visible and (bx+bw) > (l/s) and bx < (l+w)/s and (by+bh) > (t/s) and by < (t+h)/s @@ -569,7 +577,7 @@ end function body:drawNormal() if not self.refraction and not self.reflection and self.normalMesh then - love.graphics.setColor(255, 255, 255) + love.graphics.setColor(1, 1, 1) if self.type == 'animation' then self.animation:draw(self.normal, self.x, self.y, self.rotation, self.scalex, self.scaley, self.nx, self.ny) else @@ -579,7 +587,9 @@ function body:drawNormal() end function body:drawGlow() - love.graphics.setColor(self.glowRed * self.glowStrength, self.glowGreen * self.glowStrength, self.glowBlue * self.glowStrength) + love.graphics.setColor( + self.glowRed * self.glowStrength, self.glowGreen * self.glowStrength, self.glowBlue * self.glowStrength + ) if self.type == "circle" then love.graphics.circle("fill", self.x, self.y, self.radius * self.scalex) @@ -590,7 +600,7 @@ function body:drawGlow() love.graphics.setShader(self.glowShader) self.glowShader:send("glowImage", self.glow) self.glowShader:send("glowTime", love.timer.getTime() * 0.5) - love.graphics.setColor(255, 255, 255) + love.graphics.setColor(1, 1, 1) else love.graphics.setColor(0, 0, 0) end @@ -607,7 +617,7 @@ end function body:drawRefraction() if self.refraction and self.normal then - love.graphics.setColor(255, 255, 255) + love.graphics.setColor(1, 1, 1) if self.tileX == 0.0 and self.tileY == 0.0 then love.graphics.draw(self.normal, self.x, self.y, self.rotation, self.scalex, self.scaley, self.nx, self.ny) else @@ -633,12 +643,12 @@ end function body:drawReflection() if self.reflection and self.normal then - love.graphics.setColor(255, 0, 0) + love.graphics.setColor(1, 0, 0) self.normalMesh:setVertices(self.normalVert) love.graphics.draw(self.normalMesh, self.x, self.y, self.rotation, self.scalex, self.scaley, self.nx, self.ny) end if self.reflective and self.img then - love.graphics.setColor(0, 255, 0) + love.graphics.setColor(0, 1, 0) if self.type == 'animation' then self.animation:draw(self.img, self.x, self.y, self.rotation, self.scalex, self.scaley, self.ix, self.iy) else @@ -657,7 +667,7 @@ end function body:drawMaterial() if self.material and self.normal then love.graphics.setShader(self.materialShader) - love.graphics.setColor(255, 255, 255) + love.graphics.setColor(1, 1, 1) self.materialShader:send("material", self.material) if self.type == 'animation' then self.animation:draw(self.normal, self.x, self.y, self.rotation, self.scalex, self.scaley, self.nx, self.ny) @@ -678,7 +688,7 @@ function body:drawShadow(light) if self.castsNoShadow or (self.zheight - light.z) > 0 then return end - + love.graphics.setColor(self.red, self.green, self.blue, self.alpha) if self.shadowType == "polygon" then self:drawPolyShadow(light) @@ -695,7 +705,7 @@ function body:drawPolyShadow(light) local lightPosition = vector(light.x, light.y) local lh = lightPosition * self.zheight - local height_diff = (self.zheight - light.z) + local height_diff = (self.zheight - light.z) if height_diff == 0 then -- prevent inf height_diff = -0.001 end @@ -707,8 +717,8 @@ function body:drawPolyShadow(light) if vector(startToEnd.y, -startToEnd.x) * (vertex - lightPosition) > 0 then local point1 = (lh - (vertex * light.z))/height_diff local point2 = (lh - (nextVertex * light.z))/height_diff - love.graphics.polygon("fill", - vertex.x, vertex.y, point1.x, point1.y, + love.graphics.polygon("fill", + vertex.x, vertex.y, point1.x, point1.y, point2.x, point2.y, nextVertex.x, nextVertex.y) end end @@ -720,7 +730,7 @@ function body:drawCircleShadow(light) local selfPos = vector(self.x - self.ox, self.y - self.oy) local lightPosition = vector(light.x, light.y) local lh = lightPosition * self.zheight - local height_diff = (self.zheight - light.z) + local height_diff = (self.zheight - light.z) local radius = self.radius * self.scalex if height_diff == 0 then -- prevent inf height_diff = -0.001 @@ -733,15 +743,15 @@ function body:drawCircleShadow(light) selfPos.y + math.cos(angle) * radius) local point3 = (lh - (point1 * light.z))/height_diff local point4 = (lh - (point2 * light.z))/height_diff - + local shadow_radius = point3:dist(point4)/2 local circleCenter = (point3 + point4)/2 if lightPosition:dist(selfPos) <= radius then love.graphics.circle("fill", circleCenter.x, circleCenter.y, shadow_radius) else - love.graphics.polygon("fill", point1.x, point1.y, - point2.x, point2.y, + love.graphics.polygon("fill", point1.x, point1.y, + point2.x, point2.y, point4.x, point4.y, point3.x, point3.y) if lightPosition:dist(circleCenter) < light.range then -- dont draw circle if way off screen @@ -757,7 +767,7 @@ function body:drawCircleShadow(light) end function body:drawImageShadow(light) - local height_diff = (light.z - self.zheight) + local height_diff = (light.z - self.zheight) if height_diff <= 0.1 then -- prevent shadows from leaving thier person like peter pan. height_diff = 0.1 end diff --git a/lib/init.lua b/lib/init.lua index 96433f0..cf58879 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -59,6 +59,7 @@ local function new(options) options = options or {} for k, v in pairs(options) do obj[k] = v end + for i, v in ipairs(obj.ambient) do if v > 1 then obj.ambient[i] = v / 255 end end local world = setmetatable(obj, light_world) world:refreshScreenSize() @@ -94,8 +95,8 @@ function light_world:update(dt) end function light_world:draw(cb) - util.drawto(self.render_buffer, self.l, self.t, self.s, function() - cb( self.l,self.t,self.w,self.h,self.s) + util.drawto(self.render_buffer, self.l, self.t, self.s, false, function() + cb(self.l,self.t,self.w,self.h,self.s) _ = self.disableMaterial or self:drawMaterial( self.l,self.t,self.w,self.h,self.s) self:drawShadows( self.l,self.t,self.w,self.h,self.s) _ = self.disableGlow or self:drawGlow( self.l,self.t,self.w,self.h,self.s) @@ -103,6 +104,7 @@ function light_world:draw(cb) _ = self.disableReflection or self:drawReflection( self.l,self.t,self.w,self.h,self.s) end) self.post_shader:drawWith(self.render_buffer, self.l, self.t, self.s) + -- love.graphics.draw(self.shadow_buffer) end -- draw normal shading @@ -110,7 +112,7 @@ function light_world:drawShadows(l,t,w,h,s) love.graphics.setCanvas( self.normalMap ) love.graphics.clear() love.graphics.setCanvas() - util.drawto(self.normalMap, l, t, s, function() + util.drawto(self.normalMap, l, t, s, false, function() for i = 1, #self.bodies do if self.bodies[i]:isVisible() then self.bodies[i]:drawNormal() @@ -132,7 +134,7 @@ function light_world:drawShadows(l,t,w,h,s) love.graphics.clear() love.graphics.setCanvas() - util.drawto(self.shadowMap, l, t, s, function() + util.drawto(self.shadowMap, l, t, s, true, function() --I dont know if it uses both or just calls both love.graphics.stencil(function() local angle = light.direction - (light.angle / 2.0) @@ -157,8 +159,8 @@ function light_world:drawShadows(l,t,w,h,s) end) -- draw scene for this light using normals and shadowmap - self.shadowShader:send('lightColor', {light.red / 255.0, light.green / 255.0, light.blue / 255.0}) - self.shadowShader:send("lightPosition", {(light.x + l/s) * s, (light.y + t/s) * s, (light.z * 10) / 255.0}) + self.shadowShader:send('lightColor', {light.red, light.green, light.blue}) + self.shadowShader:send("lightPosition", {(light.x + l/s) * s, (light.y + t/s) * s, (light.z * 10) / 255}) self.shadowShader:send('lightRange',light.range * s) self.shadowShader:send("lightSmooth", light.smooth) self.shadowShader:send("lightGlow", {1.0 - light.glowSize, light.glowStrength}) @@ -174,7 +176,7 @@ function light_world:drawShadows(l,t,w,h,s) end -- add in ambient color - util.drawto(self.shadow_buffer, l, t, s, function() + util.drawto(self.shadow_buffer, l, t, s, false, function() love.graphics.setBlendMode("add") love.graphics.setColor({self.ambient[1], self.ambient[2], self.ambient[3]}) love.graphics.rectangle("fill", -l/s, -t/s, w/s,h/s) @@ -211,7 +213,7 @@ function light_world:drawGlow(l,t,w,h,s) love.graphics.setCanvas( self.glowMap ) love.graphics.clear() love.graphics.setCanvas() - util.drawto(self.glowMap, l, t, s, function() + util.drawto(self.glowMap, l, t, s, false, function() for i = 1, #self.bodies do if self.bodies[i]:isVisible() and self.bodies[i].glowStrength > 0.0 then has_glow = true @@ -231,7 +233,7 @@ function light_world:drawRefraction(l,t,w,h,s) love.graphics.setCanvas( self.refractionMap ) love.graphics.clear() love.graphics.setCanvas() - util.drawto(self.refractionMap, l, t, s, function() + util.drawto(self.refractionMap, l, t, s, false, function() for i = 1, #self.bodies do if self.bodies[i]:isVisible() then self.bodies[i]:drawRefraction() @@ -250,7 +252,7 @@ function light_world:drawReflection(l,t,w,h,s) love.graphics.setCanvas( self.reflectionMap ) love.graphics.clear() love.graphics.setCanvas() - util.drawto(self.reflectionMap, l, t, s, function() + util.drawto(self.reflectionMap, l, t, s, false, function() for i = 1, #self.bodies do if self.bodies[i]:isVisible() then self.bodies[i]:drawReflection() @@ -282,7 +284,10 @@ end function light_world:setScale(s) self.s = s end function light_world:clearLights() self.lights = {} end function light_world:clearBodies() self.bodies = {} end -function light_world:setAmbientColor(red, green, blue) self.ambient = {red, green, blue} end +function light_world:setAmbientColor(red, green, blue) + self.ambient = {red, green, blue} + for i, v in ipairs(self.ambient) do if v > 1 then self.ambient[i] = v / 255 end end +end function light_world:setShadowBlur(blur) self.shadowBlur = blur end function light_world:setGlowStrength(strength) self.glowBlur = strength end function light_world:setRefractionStrength(strength) self.refractionStrength = strength end diff --git a/lib/light.lua b/lib/light.lua index e81c7c0..1cc068a 100644 --- a/lib/light.lua +++ b/lib/light.lua @@ -5,15 +5,19 @@ local light = {} light.__index = light local function new(x, y, r, g, b, range) + if r and r > 1 then r = r / 255 end + if g and g > 1 then g = g / 255 end + if b and b > 1 then b = b / 255 end + local obj = { direction = 0, angle = math.pi * 2.0, x = x or 0, y = y or 0, z = 1, - red = r or 255, - green = g or 255, - blue = b or 255, + red = r or 1, + green = g or 1, + blue = b or 1, range = range or 300, smooth = 1.0, glowSize = 0.1, @@ -55,10 +59,14 @@ function light:getPosition() end -- set color -function light:setColor(red, green, blue) - self.red = red - self.green = green - self.blue = blue +function light:setColor(r, g, b) + if r > 1 then r = r / 255 end + if g > 1 then g = g / 255 end + if b > 1 then b = b / 255 end + + self.red = r + self.green = g + self.blue = b end -- get range diff --git a/lib/normal_map.lua b/lib/normal_map.lua index eecc833..172fe2c 100644 --- a/lib/normal_map.lua +++ b/lib/normal_map.lua @@ -1,7 +1,7 @@ local normal_map = {} function normal_map.fromHeightMap(heightMap, strength) - local imgData = heightMap:getData() + local imgData = normal_map.getImgData(heightMap) local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight()) local red, green, blue, alpha local x, y @@ -31,14 +31,14 @@ function normal_map.fromHeightMap(heightMap, strength) y = i + m - 1 end - local red, green, blue, alpha = imgData:getPixel(x, y) - matrix[l][m] = red + local r, _g, _b, _a = imgData:getPixel(x, y) + matrix[l][m] = r end end - red = (255 + ((matrix[1][2] - matrix[2][2]) + (matrix[2][2] - matrix[3][2])) * strength) / 2.0 - green = (255 + ((matrix[2][2] - matrix[1][1]) + (matrix[2][3] - matrix[2][2])) * strength) / 2.0 - blue = 192 + red = (1 + ((matrix[1][2] - matrix[2][2]) + (matrix[2][2] - matrix[3][2])) * strength) / 2.0 + green = (1 + ((matrix[2][2] - matrix[1][1]) + (matrix[2][3] - matrix[2][2])) * strength) / 2.0 + blue = 192/255 imgData2:setPixel(k, i, red, green, blue) end @@ -48,20 +48,20 @@ function normal_map.fromHeightMap(heightMap, strength) end function normal_map.generateFlat(img, mode) - local imgData = love.image.newImageData(img:getWidth(), img:getHeight()) + local imgData = normal_map.getImgData(img) local imgNormalData = love.image.newImageData(img:getWidth(), img:getHeight()) local color if mode == "top" then - color = {127, 127, 255} + color = {0.5, 0.5, 1} elseif mode == "front" then - color = {127, 0, 127} + color = {0.5, 0, 0.5} elseif mode == "back" then - color = {127, 255, 127} + color = {0.5, 1, 0.5} elseif mode == "left" then - color = {31, 0, 223} + color = {31/255, 0, 223/255} elseif mode == "right" then - color = {223, 0, 127} + color = {223/255, 0, 0.5} end for i = 0, img:getHeight() - 1 do @@ -78,7 +78,7 @@ function normal_map.generateGradient(img, horizontalGradient, verticalGradient) horizontalGradient = horizontalGradient or "gradient" verticalGradient = verticalGradient or horizontalGradient - local imgData = img:getData() + local imgData = normal_map.getImgData(img) local imgWidth, imgHeight = img:getWidth(), img:getHeight() local imgNormalData = love.image.newImageData(imgWidth, imgHeight) local dx = 255.0 / imgWidth @@ -94,23 +94,23 @@ function normal_map.generateGradient(img, horizontalGradient, verticalGradient) if horizontalGradient == "gradient" then nx = i * dx elseif horizontalGradient == "inverse" then - nx = 255 - i * dx + nx = 1 - i * dx else - nx = 127 + nx = 0.5 end if verticalGradient == "gradient" then - ny = 127 - k * dy * 0.5 - nz = 255 - k * dy * 0.5 + ny = 0.5 - k * dy * 0.5 + nz = 1 - k * dy * 0.5 elseif verticalGradient == "inverse" then - ny = 127 + k * dy * 0.5 - nz = 127 - k * dy * 0.25 + ny = 0.5 + k * dy * 0.5 + nz = 0.5 - k * dy * 0.25 else - ny = 255 - nz = 127 + ny = 1 + nz = 0.5 end - imgNormalData:setPixel(i, k, nx, ny, nz, 255) + imgNormalData:setPixel(i, k, nx, ny, nz, 1) end end end @@ -118,4 +118,10 @@ function normal_map.generateGradient(img, horizontalGradient, verticalGradient) return love.graphics.newImage(imgNormalData) end +function normal_map.getImgData(img) + local canvas = love.graphics.newCanvas(img:getWidth(), img:getHeight()) + canvas:renderTo(function() love.graphics.draw(img, 0, 0) end) + return canvas:newImageData() +end + return normal_map diff --git a/lib/postshader.lua b/lib/postshader.lua index 6a589d5..6942560 100644 --- a/lib/postshader.lua +++ b/lib/postshader.lua @@ -32,7 +32,7 @@ local shaders = {} for i,v in ipairs(files) do local name = _PACKAGE.."/shaders/postshaders".."/"..v - if love.filesystem.getInfo(name).type == "file" then + if love.filesystem.getInfo(name).type == "file" and string.sub(v, 1, 1) ~= '.' then local str = love.filesystem.read(name) local effect = util.loadShader(name) local defs = {} @@ -94,7 +94,9 @@ function post_shader:drawBloom(canvas, args) util.process(self.back_buffer, {shader = shaders['blurh'][1]}) util.process(self.back_buffer, {shader = shaders['contrast'][1]}) util.process(canvas, {shader = shaders['contrast'][1]}) - util.drawCanvasToCanvas(self.back_buffer, canvas, {blendmode = "add", color = {255, 255, 255, (args[2] or 0.25) * 255}}) + util.drawCanvasToCanvas(self.back_buffer, canvas, { + blendmode = "add", color = {1, 1, 1, (args[2] or 0.25)} + }) end function post_shader:drawBlur(canvas, args) @@ -151,7 +153,7 @@ function post_shader:drawShader(shaderName, canvas, args) end function process_tint(r, g, b) - return (r and r/255.0 or 1.0), (g and g/255.0 or 1.0), (b and b/255.0 or 1.0) + return (r or 1.0), (g or 1.0), (b or 1.0) end function process_palette(palette) diff --git a/lib/shaders/postshaders/phosphor.glsl b/lib/shaders/postshaders/phosphor.glsl index d2c1264..55d13e9 100644 --- a/lib/shaders/postshaders/phosphor.glsl +++ b/lib/shaders/postshaders/phosphor.glsl @@ -34,7 +34,7 @@ // Uncomment to only draw every third pixel, which highlights the shape // of individual (remaining) spots. -//#define DEBUG +// #define DEBUG // Uncomment one of these to choose a gamma correction method. // If none are uncommented, no gamma correction is done. @@ -62,7 +62,6 @@ vec4 A_IN = vec4( 12.0/(InputGamma+1.0)-3.0 ); vec4 B_IN = vec4(1.0) - A_IN; vec4 A_OUT = vec4(6.0 - 15.0 * OutputGamma / 2.0 / (OutputGamma+1.0)); vec4 B_OUT = vec4(1.0) - A_OUT; -uniform Image _tex0_; #define GAMMA_IN(color) ( (A_IN + B_IN * color) * color * color ) #define GAMMA_OUT(color) ( A_OUT * sqrt(color) + B_OUT * sqrt( sqrt(color) ) ) @@ -79,25 +78,26 @@ vec4 B_IN = vec4(1.0) - A_IN; #endif #ifdef DEBUG -vec4 grid_color( vec2 coords ) +vec4 grid_color(Image tex, vec2 coords ) { vec2 snes = floor( coords * love_ScreenSize.xy ); - if ( (mod(snes.x, 3.0) == 0.0) && (mod(snes.y, 3.0) == 0.0) ) - return texture2D(_tex0_, coords); - else + if ( (mod(snes.x, 3.0) == 0.0) && (mod(snes.y, 3.0) == 0.0) ) { + return texture2D(tex, coords); + } else { return vec4(0.0); + } } -#define TEX2D(coords) GAMMA_IN( grid_color( coords ) ) +#define TEX2D(tex, coords) GAMMA_IN( grid_color(tex, coords) ) #else // DEBUG -#define TEX2D(coords) GAMMA_IN( texture2D(_tex0_, coords) ) +#define TEX2D(tex, coords) GAMMA_IN( texture2D(tex, coords) ) #endif // DEBUG vec2 onex = vec2( 1.0/love_ScreenSize.x, 0.0 ); vec2 oney = vec2( 0.0, 1.0/love_ScreenSize.y ); -vec4 effect(vec4 vcolor, Image texture, highp vec2 texCoord, vec2 pixel_coords) +vec4 effect(vec4 vcolor, Image tex, highp vec2 texCoord, vec2 pixel_coords) { highp vec2 coords = (texCoord * love_ScreenSize.xy); highp vec2 pixel_start = floor(coords); @@ -124,9 +124,8 @@ vec4 effect(vec4 vcolor, Image texture, highp vec2 texCoord, vec2 pixel_coords) if (vweight !=0.0 ) { for ( i = -1.0; i<=1.0; i++ ) { pixel = TEX2D( - texture_coords - + i * onex - + j * oney + tex, + texture_coords + i * onex + j * oney ); /* Evaluate the distance (in x) from diff --git a/lib/util.lua b/lib/util.lua index d4fad45..5eef986 100644 --- a/lib/util.lua +++ b/lib/util.lua @@ -11,9 +11,11 @@ end function util.drawCanvasToCanvas(canvas, other_canvas, options) options = options or {} - util.drawto(other_canvas, 0, 0, 1, function() - if options["blendmode"] then - love.graphics.setBlendMode(options["blendmode"], "premultiplied") + util.drawto(other_canvas, 0, 0, 1, options['stencil'] or options['istencil'] and true or false, function() + if options["blendmode"] == 'multiply' then + love.graphics.setBlendMode(options["blendmode"], 'premultiplied') + elseif options["blendmode"] then + love.graphics.setBlendMode(options["blendmode"]) end if options["shader"] then love.graphics.setShader(options["shader"]) @@ -29,7 +31,7 @@ function util.drawCanvasToCanvas(canvas, other_canvas, options) if options["color"] then love.graphics.setColor(unpack(options["color"])) else - love.graphics.setColor(255,255,255) + love.graphics.setColor(1,1,1) end if love.graphics.getCanvas() ~= canvas then love.graphics.draw(canvas,0,0) @@ -47,11 +49,11 @@ function util.drawCanvasToCanvas(canvas, other_canvas, options) end) end -function util.drawto(canvas, x, y, scale, cb) +function util.drawto(canvas, x, y, scale, stencil, cb) local last_buffer = love.graphics.getCanvas() love.graphics.push() love.graphics.origin() - love.graphics.setCanvas({canvas,stencil = true}) + love.graphics.setCanvas({ canvas, stencil = stencil }) love.graphics.translate(x, y) love.graphics.scale(scale) cb() @@ -60,7 +62,6 @@ function util.drawto(canvas, x, y, scale, cb) end function util.loadShader(name) - print("loading:", name) local shader = "" local externInit = {} for line in love.filesystem.lines(name) do @@ -97,4 +98,5 @@ function util.loadShader(name) return effect end + return util diff --git a/main.lua b/main.lua index f4aba07..feeca4f 100644 --- a/main.lua +++ b/main.lua @@ -121,7 +121,7 @@ function exf.start(item, file) local unused1, unused2, n = string.find(item, "(%s)%.lua") if exf.intable(exf.available, file) then - if not love.filesystem.exists("examples/" .. file) then + if not love.filesystem.getInfo("examples/" .. file) then print("Could not load game .. " .. file) else @@ -337,7 +337,7 @@ function List:draw() love.graphics.setLineStyle("rough") love.graphics.setFont(self.font) - love.graphics.setColor(48/255, 156/255, 1) + love.graphics.setColor(48/255, 156/255, 225 / 255) local mx, my = love.mouse.getPosition()