267 lines
5.7 KiB
Lua
267 lines
5.7 KiB
Lua
|
--
|
||
|
-- pixwerx - bare rendering engine binding usage
|
||
|
--
|
||
|
|
||
|
-- we need everything
|
||
|
pw.script:load_all()
|
||
|
|
||
|
print("executable path:",pw.path.get().executable_path)
|
||
|
print("resource paths:",pw.path.get().resource_paths)
|
||
|
|
||
|
for k,v in pairs(pw.path.get().resource_paths) do
|
||
|
print(k,v)
|
||
|
end
|
||
|
|
||
|
|
||
|
local img = pw.image()
|
||
|
if not img:create(pw.size(512,512),pw.pixel_layout.rgb8) then
|
||
|
print("image couldnt be created")
|
||
|
else
|
||
|
|
||
|
-- generate some noise
|
||
|
img:generate_noise()
|
||
|
|
||
|
-- for debugging
|
||
|
pw.image_io.get():write("test.png",img,0)
|
||
|
|
||
|
end
|
||
|
|
||
|
-- create a window (remember windows are invisible by default)
|
||
|
local w = pw.window.new()
|
||
|
|
||
|
-- set title
|
||
|
w.title = "pixwerx - bare rendering"
|
||
|
|
||
|
-- set size
|
||
|
w.size = pw.size(640,480)
|
||
|
|
||
|
-- move window
|
||
|
w.position = pw.point(100,100)
|
||
|
|
||
|
-- create a new geometry
|
||
|
local g = pw.geometry()
|
||
|
|
||
|
g.primitive_topology = pw.primitive_topology_type.triangle_list -- meh
|
||
|
|
||
|
-- create texture coordinates
|
||
|
g.texture_coordinates = { {
|
||
|
{ 0.0, 0.0 },
|
||
|
{ 1.0, 1.0 },
|
||
|
{ 1.0, 0.0 },
|
||
|
{ 0.0, 1.0 }
|
||
|
} }
|
||
|
|
||
|
z = -5.0
|
||
|
s = 1
|
||
|
|
||
|
-- indices
|
||
|
g.indices = {
|
||
|
0, 1, 2, -- triangle #1
|
||
|
2, 3, 0 -- triangle #2
|
||
|
}
|
||
|
|
||
|
print(g.indices,#g.indices)
|
||
|
|
||
|
|
||
|
-- geometry can only build with indexed facesets
|
||
|
g.vertices = {
|
||
|
{ -s,-s, z },
|
||
|
{ s,-s, z },
|
||
|
{ s, s, z },
|
||
|
{ -s, s, z }
|
||
|
}
|
||
|
|
||
|
-- 0 --- 3
|
||
|
-- | \ |
|
||
|
-- 1 --- 2
|
||
|
|
||
|
g:compute_normals()
|
||
|
|
||
|
|
||
|
local mm = pw.matrix4x4.identity
|
||
|
local mv = pw.matrix4x4()
|
||
|
local mp = pw.matrix4x4()
|
||
|
|
||
|
local s = pw.shader()
|
||
|
|
||
|
s:set_source(pw.shader_type.vertex,[[
|
||
|
#version 400
|
||
|
|
||
|
layout (location = 0) in vec3 vertices;
|
||
|
layout (location = 1) in vec3 normals;
|
||
|
layout (location = 2) in vec2 texture_coords;
|
||
|
|
||
|
uniform mat4 model;
|
||
|
uniform mat4 view;
|
||
|
uniform mat4 projection;
|
||
|
|
||
|
|
||
|
out vec2 tex_c;
|
||
|
|
||
|
void main() {
|
||
|
tex_c = texture_coords;
|
||
|
gl_Position = projection * view * model * vec4(vertices, 1.0);
|
||
|
}
|
||
|
]])
|
||
|
|
||
|
s:set_source(pw.shader_type.fragment,[[
|
||
|
#version 400
|
||
|
|
||
|
uniform vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
|
||
|
uniform sampler2D tex_color;
|
||
|
|
||
|
in vec2 tex_c;
|
||
|
|
||
|
out vec4 frag_color;
|
||
|
|
||
|
void main() {
|
||
|
frag_color = texture(tex_color,tex_c) * color;
|
||
|
}
|
||
|
]])
|
||
|
|
||
|
-- check if the shader can be compiled and linked
|
||
|
if not s:build() then
|
||
|
print("Error!")
|
||
|
end
|
||
|
|
||
|
-- the renderer for a geometry
|
||
|
local renderer = pw.renderer()
|
||
|
|
||
|
-- camera position
|
||
|
local cam_pos = pw.vector3(0,0,0)
|
||
|
|
||
|
-- model position
|
||
|
local model_pos = pw.vector3(0,0,0)
|
||
|
|
||
|
|
||
|
-- create new context (should move into a scene later)
|
||
|
local ctx = pw.context()
|
||
|
|
||
|
-- create a texture
|
||
|
local tx = pw.texture()
|
||
|
|
||
|
-- create texture from an image
|
||
|
tx:create(img)
|
||
|
|
||
|
-- unload it - would only make sense for static textures
|
||
|
-- img:release()
|
||
|
|
||
|
-- set function to
|
||
|
w.on_resize = function(self)
|
||
|
-- use client_size to resize the viewport
|
||
|
ctx:set_viewport(pw.rectangle(pw.point(0,0),self.client_size:cast_to_float()))
|
||
|
end
|
||
|
|
||
|
|
||
|
-- setup a lua callback function as callback
|
||
|
w.on_update = function(self)
|
||
|
|
||
|
-- we set the clear color
|
||
|
ctx.clearcolor = pw.color(pw.mathf.ping_pong(pw.time.now,1.0),0,1,1)
|
||
|
ctx:clear()
|
||
|
|
||
|
-- set view matrix with look_at - view matrix is moving the world - hence inverse!
|
||
|
mv = pw.matrixtransform.look_at(cam_pos,cam_pos + pw.vector3.forward,pw.vector3.up).inverse
|
||
|
|
||
|
-- compute aspect ratio from canvas size
|
||
|
aspect_ratio = self.client_size.width / self.client_size.height
|
||
|
|
||
|
-- create a view frustum for a perspective projection
|
||
|
mp = pw.matrixtransform.perspective_projection(math.rad(45),aspect_ratio,0.2,100)
|
||
|
|
||
|
--
|
||
|
-- this code is raw rendering mode
|
||
|
--
|
||
|
|
||
|
-- just some toying around
|
||
|
local color_red = pw.mathf.ping_pong(pw.time.now,1.0)
|
||
|
local color_green = pw.mathf.ping_pong(pw.time.now + 1,1.0)
|
||
|
local color_blue = 1.0 - pw.mathf.ping_pong(pw.time.now,1.0)
|
||
|
-- color is currently still a vector4
|
||
|
local cl = pw.vector4( color_red, color_green, color_blue, 1.0 )
|
||
|
|
||
|
|
||
|
img:generate_noise()
|
||
|
tx:update(img)
|
||
|
|
||
|
-- bind the shader
|
||
|
s:use()
|
||
|
|
||
|
-- update the uniforms, currently the slow path
|
||
|
s:set_uniform_mat4("model",mm)
|
||
|
s:set_uniform_mat4("view",mv)
|
||
|
s:set_uniform_mat4("projection",mp)
|
||
|
s:set_uniform_vec4("color",cl)
|
||
|
|
||
|
-- specific to our shader
|
||
|
s:set_uniform_int("tex_color",0)
|
||
|
|
||
|
-- bind the texture
|
||
|
tx:bind()
|
||
|
|
||
|
-- update renderer from geometry
|
||
|
renderer:update(g)
|
||
|
|
||
|
-- draw
|
||
|
renderer:draw()
|
||
|
|
||
|
local e = ctx:get_error()
|
||
|
if e ~= 0 then
|
||
|
print("OpenGL error",e)
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
-- before entering the update loop make the window visible
|
||
|
w.visible = true
|
||
|
|
||
|
-- some fluffyness
|
||
|
local speed = 0
|
||
|
|
||
|
-- main update loop
|
||
|
while w:update() do
|
||
|
|
||
|
-- only check if get a new input
|
||
|
if pw.input.get().has_input then
|
||
|
|
||
|
|
||
|
-- somehow works
|
||
|
if pw.input.get().input_string == 'f' then
|
||
|
w.fullscreen = not w.fullscreen
|
||
|
end
|
||
|
|
||
|
-- keycode for quit
|
||
|
if pw.input.get().input_string == 'q' then
|
||
|
break
|
||
|
end
|
||
|
|
||
|
-- just to quickly modify speed
|
||
|
local move_step = 0.05
|
||
|
|
||
|
-- camera
|
||
|
if pw.input.get().input_string == 'w' then
|
||
|
cam_pos.z = cam_pos.z - move_step
|
||
|
elseif pw.input.get().input_string == 's' then
|
||
|
cam_pos.z = cam_pos.z + move_step
|
||
|
elseif pw.input.get().input_string == 'a' then
|
||
|
cam_pos.x = cam_pos.x - move_step
|
||
|
elseif pw.input.get().input_string == 'd' then
|
||
|
cam_pos.x = cam_pos.x + move_step
|
||
|
elseif pw.input.get().input_string == 'z' then
|
||
|
cam_pos.y = cam_pos.y + move_step
|
||
|
elseif pw.input.get().input_string == 'x' then
|
||
|
cam_pos.y = cam_pos.y - move_step
|
||
|
end
|
||
|
|
||
|
-- just some debugging
|
||
|
print(cam_pos.x,cam_pos.y,cam_pos.z)
|
||
|
|
||
|
end
|
||
|
|
||
|
-- just to check
|
||
|
if pw.input:get().mouse_button == 1 then
|
||
|
print(pw.input:get().mouse_position.x,pw.input:get().mouse_position.y,w.client_size.width,w.client_size.height)
|
||
|
end
|
||
|
|
||
|
end
|