From 7bdeedd394e4b51d4c2ef4a0dd0470ed0492ac5f Mon Sep 17 00:00:00 2001 From: sanine-a Date: Sun, 8 Nov 2020 19:59:16 -0600 Subject: add Shader and SpatialShader --- demo/MeshInstance.lua | 10 ++----- demo/Node.lua | 18 ++++++++++-- demo/Shader.lua | 53 ++++++++++++++++++++++++++++++++++++ demo/SpatialShader.lua | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ demo/main.lua | 48 +++----------------------------- 5 files changed, 149 insertions(+), 54 deletions(-) create mode 100644 demo/Shader.lua create mode 100644 demo/SpatialShader.lua diff --git a/demo/MeshInstance.lua b/demo/MeshInstance.lua index a3e6da2..b12edba 100644 --- a/demo/MeshInstance.lua +++ b/demo/MeshInstance.lua @@ -8,14 +8,8 @@ setmetatable(MeshInstance.prototype, { __index = Node.prototype}) MeshInstance.prototype.draw = function(self, camera, shader) local shader = shader or self.shader - honey.shader.set_mat4(shader, 'model', self.transform.array) - honey.shader.set_mat4(shader, 'view', camera.view.array) - honey.shader.set_mat4(shader, 'projection', camera.projection.array) - honey.mesh.draw(self.mesh, shader) - - for _, child in ipairs(self.children) do - child:draw(camera) - end + shader:setCamera(camera) + shader:drawMesh(self) end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/demo/Node.lua b/demo/Node.lua index ffb2aa5..300679c 100644 --- a/demo/Node.lua +++ b/demo/Node.lua @@ -25,10 +25,24 @@ Node.prototype.updateTransform = function(self) end end -Node.prototype.draw = function(self, camera, shader) +Node.prototype.updateCascade = function(self, dt) + if self.update then + self:update(dt) + end + self:updateTransform() + for _, child in ipairs(self.children) do + child:updateCascade(dt) + end +end + +Node.prototype.drawCascade = function(self, camera, shader) + if self.draw then + self:draw(camera, shader) + end + -- do not draw base nodes, but recursively draw children. for _, child in ipairs(self.children) do - child:draw(camera, shader) + child:drawCascade(camera, shader) end end diff --git a/demo/Shader.lua b/demo/Shader.lua new file mode 100644 index 0000000..494bd53 --- /dev/null +++ b/demo/Shader.lua @@ -0,0 +1,53 @@ +local Shader = {} + +Shader.prototype = {} + +Shader.prototype.setInteger = function(self, uniform, integer) + honey.shader.set_int(self.program, uniform, integer) +end + +Shader.prototype.setFloat = function(self, uniform, float) + honey.shader.set_float(self.program, uniform, float) +end + +Shader.prototype.setVec3 = function(self, uniform, vector) + honey.shader.set_vec3(self.program, uniform, vector.array) +end + +Shader.prototype.setVec4 = function(self, uniform, vector) + honey.shader.set_vec4(self.program, uniform, vector.array) +end + +Shader.prototype.setMat3 = function(self, uniform, matrix) + honey.shader.set_mat3(self.program, uniform, matrix.array) +end + +Shader.prototype.setMat4 = function(self, uniform, matrix) + honey.shader.set_mat4(self.program, uniform, matrix.array) +end + +Shader.prototype.drawMesh = function(self, mesh) + honey.mesh.draw(mesh.mesh, self.program) +end + +Shader.prototype.delete = function(self) + honey.shader.delete(self.program) +end + +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Shader.mt = {} +Shader.mt.__index = Shader.prototype + +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Shader.new = function(vertexCode, fragmentCode) + local shader = {} + shader.program = honey.shader.new(vertexCode, fragmentCode) + + setmetatable(shader, Shader.mt) + + return shader +end + +return Shader diff --git a/demo/SpatialShader.lua b/demo/SpatialShader.lua new file mode 100644 index 0000000..4a9f979 --- /dev/null +++ b/demo/SpatialShader.lua @@ -0,0 +1,74 @@ +local Shader = require('Shader') + +local VertexCode = [[ +#version 330 core + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec2 uv; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +out vec3 Position; +out vec3 Normal; +out vec2 UV; + +void main() +{ + gl_Position = projection * view * model * vec4(position.xyz, 1); + Position = gl_Position.xyz; + Normal = normal; + UV = uv; +} ]] + +local FragmentCode = [[ +#version 330 core + +in vec3 Position; +in vec3 Normal; +in vec2 UV; + +uniform sampler2D albedo; + +out vec4 color; + +void main() +{ + color = vec4(texture(albedo, UV).xyz, 1); +} ]] + +local SpatialShader = {} + +SpatialShader.prototype = {} +setmetatable(SpatialShader.prototype, { __index = Shader.prototype }) + +SpatialShader.prototype.setCamera = function(self, camera) + self:setMat4('view', camera.view) + self:setMat4('projection', camera.projection) +end + +SpatialShader.prototype.drawMesh = function(self, mesh) + self:setMat4('model', mesh.transform) + honey.texture.use(self.albedo, 0) + honey.mesh.draw(mesh.mesh, self.program) +end + +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SpatialShader.mt = {} +SpatialShader.mt.__index = SpatialShader.prototype + +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SpatialShader.new = function(albedo) + local spatialshader = Shader.new(VertexCode, FragmentCode) + spatialshader.albedo = albedo + + setmetatable(spatialshader, SpatialShader.mt) + + return spatialshader +end + +return SpatialShader diff --git a/demo/main.lua b/demo/main.lua index e8d3cac..aa91acd 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -2,6 +2,7 @@ local Vector = require('Vector') local Matrix = require('Matrix') local FPSCamera = require('FPSCamera') local Node = require('Node') +local SpatialShader = require('SpatialShader') local ScreenQuad = require('ScreenQuad') local MeshInstance = require('MeshInstance') FPSCamera.movement_speed = 5 @@ -14,51 +15,12 @@ honey.input.key.bind(honey.input.key.f, function(action) if action == 1 then buf local tex = honey.texture.new() honey.texture.load(tex, 'checkerboard.png', false) -local vertex_shader = [[ -#version 330 core - -layout(location = 0) in vec3 position; -layout(location = 1) in vec3 normal; -layout(location = 2) in vec2 uv; - -uniform mat4 model; -uniform mat4 view; -uniform mat4 projection; - -out vec3 Position; -out vec3 Normal; -out vec2 UV; - -void main() -{ - gl_Position = projection * view * model * vec4(position.xyz, 1); - Position = gl_Position.xyz; - Normal = normal; - UV = uv; -} ]] -local fragment_shader = [[ -#version 330 core - -in vec3 Position; -in vec3 Normal; -in vec2 UV; - -uniform float time; -uniform sampler2D tex; - -out vec4 color; - -void main() { - //vec2 texture_coords = UV + (time * vec2(100,100)); - color = vec4(texture(tex, UV).xyz, 1); -} ]] - local sceneRoot = Node.new(nil, Vector.Vec3.new(), Vector.Vec3.new(), Vector.Vec3.new{1,1,1}) -local shader = honey.shader.new(vertex_shader, fragment_shader) +local shader = SpatialShader.new(tex) local suzanne = MeshInstance.new(sceneRoot, Vector.Vec3.new{0,0,-3}, Vector.Vec3.new{0,math.pi,0}, @@ -81,7 +43,6 @@ local plane2 = MeshInstance.new(suzanne, suzanne.update = function(self, dt) local angle = dt * math.pi self:yaw(angle) - self:updateTransform() end local total_frames = 0 @@ -92,7 +53,7 @@ honey.window.set_size(640, 480) function honey.update(dt) total_time = total_time + dt FPSCamera:update(dt) - suzanne:update(dt) + sceneRoot:updateCascade(dt) if total_time > 1 then print('FPS: '..tostring(total_frames/total_time)) total_time = 0 @@ -101,8 +62,7 @@ function honey.update(dt) end function draw_suzanne() - honey.texture.use(tex, 0) - sceneRoot:draw(FPSCamera) + sceneRoot:drawCascade(FPSCamera) end function honey.draw() -- cgit v1.2.1