a working version with no error but still some bugs around texturing
This commit is contained in:
parent
2d8244386a
commit
68d4610470
16 changed files with 473 additions and 110 deletions
|
@ -42,7 +42,7 @@ vector3 vector3_from_lua_table(sol::table t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void register_core_function(sol::state&,sol::table& ns)
|
void register_core_function(sol::state& lua,sol::table& ns)
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef real_t Scalar;
|
typedef real_t Scalar;
|
||||||
|
@ -114,7 +114,7 @@ void register_core_function(sol::state&,sol::table& ns)
|
||||||
|
|
||||||
|
|
||||||
ns.new_usertype<size>("size"
|
ns.new_usertype<size>("size"
|
||||||
, sol::constructors<size(),size(Scalar,Scalar)>()
|
, sol::call_constructor,sol::constructors<size(),size(Scalar,Scalar)>()
|
||||||
, "width",&size::width
|
, "width",&size::width
|
||||||
, "height",&size::height
|
, "height",&size::height
|
||||||
, "cast_to_float",&size::cast<float>
|
, "cast_to_float",&size::cast<float>
|
||||||
|
@ -174,15 +174,24 @@ void register_core_function(sol::state&,sol::table& ns)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ns.new_usertype<image>("image"
|
auto image_type = ns.new_usertype<image>("image"
|
||||||
, sol::constructors<image()>()
|
, sol::constructors<image()>()
|
||||||
,"create",&image::create
|
,"create",&image::create
|
||||||
,"size",sol::readonly_property(&image::size)
|
,"size",sol::readonly_property(&image::size)
|
||||||
|
,"generate_noise",&image::generate_noise
|
||||||
,"change_count",sol::property(&image::change_count,&image::set_change_count)
|
,"change_count",sol::property(&image::change_count,&image::set_change_count)
|
||||||
).new_enum<false>("layout"
|
);
|
||||||
|
|
||||||
|
image_type.create_named("pixel_layout"
|
||||||
,"rgb8", image::RGB8
|
,"rgb8", image::RGB8
|
||||||
,"rgb32", image::RGBA8
|
,"rgb32", image::RGBA8
|
||||||
,"gray", image::LUM);
|
,"gray", image::LUM
|
||||||
|
);
|
||||||
|
|
||||||
|
// image_type["layout"] = lua.create_table_with(
|
||||||
|
// "rgb8", image::RGB8
|
||||||
|
// ,"rgb32", image::RGBA8
|
||||||
|
// ,"gray", image::LUM);
|
||||||
|
|
||||||
|
|
||||||
ns.new_usertype<rectangle>("rectangle"
|
ns.new_usertype<rectangle>("rectangle"
|
||||||
|
|
|
@ -30,8 +30,12 @@ void register_visual_function(sol::state&,sol::table &ns)
|
||||||
,"set_source",&shader::set_source
|
,"set_source",&shader::set_source
|
||||||
,"set_uniforms",&shader::set_uniforms
|
,"set_uniforms",&shader::set_uniforms
|
||||||
,"set_uniform_float",&shader::set_uniform<float>
|
,"set_uniform_float",&shader::set_uniform<float>
|
||||||
|
,"set_uniform_uint",&shader::set_uniform<uint32_t>
|
||||||
|
,"set_uniform_int",&shader::set_uniform<int32_t>
|
||||||
,"set_uniform_mat4",&shader::set_uniform<matrix4x4&>
|
,"set_uniform_mat4",&shader::set_uniform<matrix4x4&>
|
||||||
,"set_uniform_vec4",&shader::set_uniform<vector4&>
|
,"set_uniform_vec4",&shader::set_uniform<vector4&>
|
||||||
|
,"set_uniform_texture",&shader::set_uniform<texture&>
|
||||||
|
|
||||||
).new_enum<false>("shader_type"
|
).new_enum<false>("shader_type"
|
||||||
,"fragment",shader::code_type::fragment
|
,"fragment",shader::code_type::fragment
|
||||||
,"vertex",shader::code_type::vertex
|
,"vertex",shader::code_type::vertex
|
||||||
|
@ -60,14 +64,19 @@ void register_visual_function(sol::state&,sol::table &ns)
|
||||||
,"blit",&framebuffer::blit);
|
,"blit",&framebuffer::blit);
|
||||||
|
|
||||||
ns.new_usertype<texture>("texture"
|
ns.new_usertype<texture>("texture"
|
||||||
,sol::constructors<texture(),texture(texture::image_ref,texture::data_layout)>()
|
,sol::constructors<texture()>()
|
||||||
,"image",sol::property(&texture::set_image,&texture::image)
|
,"create",&texture::create
|
||||||
|
,"update",&texture::update
|
||||||
|
,"bind",&texture::bind
|
||||||
|
,"unbind",&texture::unbind
|
||||||
|
,"native_handle",&texture::native_handle
|
||||||
);
|
);
|
||||||
|
|
||||||
ns.new_usertype<context>("context"
|
ns.new_usertype<context>("context"
|
||||||
,sol::constructors<context()>()
|
,sol::constructors<context()>()
|
||||||
,"clear",&context::clear
|
,"clear",&context::clear
|
||||||
,"set_viewport",&context::set_viewport
|
,"set_viewport",&context::set_viewport
|
||||||
|
,"get_error",&context::get_error
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,9 @@ public:
|
||||||
HDR
|
HDR
|
||||||
};
|
};
|
||||||
|
|
||||||
image(const size& s, pixel_layout t, void *ptr = nullptr);
|
image(const size& s, pixel_layout t, const void *ptr = nullptr);
|
||||||
|
|
||||||
bool create(const size& s, pixel_layout t, void *ptr = nullptr);
|
bool create(const size& s, pixel_layout t, const void *ptr = nullptr);
|
||||||
|
|
||||||
void release(bool release_memory = false);
|
void release(bool release_memory = false);
|
||||||
|
|
||||||
|
@ -63,10 +63,9 @@ public:
|
||||||
|
|
||||||
static uint32_t bytes_per_pixel(pixel_layout t);
|
static uint32_t bytes_per_pixel(pixel_layout t);
|
||||||
|
|
||||||
typedef shared_ptr<image> ptr;
|
|
||||||
|
|
||||||
::pw::size size() const;
|
::pw::size size() const;
|
||||||
|
|
||||||
|
void generate_noise();
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
::pw::size _size;
|
::pw::size _size;
|
||||||
|
|
|
@ -1,35 +1,51 @@
|
||||||
#include "pw/core/image.hpp"
|
#include "pw/core/image.hpp"
|
||||||
|
#include "pw/core/debug.hpp"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
image::image(const ::pw::size &s, image::pixel_layout t, void *ptr)
|
image::image(const ::pw::size &s, image::pixel_layout t, const void *ptr)
|
||||||
{
|
{
|
||||||
this->create(s,t,ptr);
|
if (!this->create(s,t,ptr)) {
|
||||||
|
debug::w() << __PRETTY_FUNCTION__ << " create failed";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool image::create(const ::pw::size &s, image::pixel_layout t, void *ptr)
|
bool image::create(const ::pw::size &s,
|
||||||
|
image::pixel_layout t,
|
||||||
|
const void *ptr)
|
||||||
{
|
{
|
||||||
size_t n = bytes_per_pixel(t) * s.area();
|
size_t n = bytes_per_pixel(t) * s.area();
|
||||||
|
_size = s;
|
||||||
|
_layout = t;
|
||||||
|
|
||||||
if (ptr != nullptr) {
|
if (ptr != nullptr) {
|
||||||
|
|
||||||
auto a = reinterpret_cast<image::data_t*>(ptr);
|
const auto a = reinterpret_cast<const image::data_t*>(ptr);
|
||||||
|
|
||||||
_data.assign(a,a + n);
|
_data.assign(a,a + n);
|
||||||
_size = s;
|
|
||||||
_layout = t;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
_data.resize(n);
|
_data.resize(n);
|
||||||
_size = ::pw::size(0,0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !_data.empty();
|
return !_data.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void image::generate_noise()
|
||||||
|
{
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937_64 gen(rd());
|
||||||
|
std::uniform_int_distribution<std::uint8_t> dis;
|
||||||
|
|
||||||
|
std::for_each(_data.begin(),_data.end(),[&](auto& v) {v = static_cast<std::byte>(dis(gen)); });
|
||||||
|
|
||||||
|
|
||||||
|
_change_count++;
|
||||||
|
}
|
||||||
|
|
||||||
void image::release(bool release_memory)
|
void image::release(bool release_memory)
|
||||||
{
|
{
|
||||||
_data.clear();
|
_data.clear();
|
||||||
|
@ -48,6 +64,8 @@ uint32_t image::bytes_per_pixel(image::pixel_layout t)
|
||||||
return 1 * sizeof(data_t);
|
return 1 * sizeof(data_t);
|
||||||
case pw::image::DEPTH:
|
case pw::image::DEPTH:
|
||||||
return 1 * sizeof(float);
|
return 1 * sizeof(float);
|
||||||
|
default:
|
||||||
|
debug::w() << __PRETTY_FUNCTION__ << " unhandled pixel_layout";
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::numeric_limits<uint32_t>::max();
|
return std::numeric_limits<uint32_t>::max();
|
||||||
|
|
|
@ -3,6 +3,7 @@ set(scripts_demo
|
||||||
${CMAKE_SOURCE_DIR}/src/scripts/demos/simple_000.lua
|
${CMAKE_SOURCE_DIR}/src/scripts/demos/simple_000.lua
|
||||||
${CMAKE_SOURCE_DIR}/src/scripts/demos/simple_001.lua
|
${CMAKE_SOURCE_DIR}/src/scripts/demos/simple_001.lua
|
||||||
${CMAKE_SOURCE_DIR}/src/scripts/demos/simple_002.lua
|
${CMAKE_SOURCE_DIR}/src/scripts/demos/simple_002.lua
|
||||||
|
${CMAKE_SOURCE_DIR}/src/scripts/demos/simple_003.lua
|
||||||
)
|
)
|
||||||
|
|
||||||
set(scripts_test
|
set(scripts_test
|
||||||
|
|
229
src/scripts/demos/simple_003.lua
Normal file
229
src/scripts/demos/simple_003.lua
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
--
|
||||||
|
-- pixwerx - bare rendering engine binding usage
|
||||||
|
--
|
||||||
|
|
||||||
|
-- we need everything
|
||||||
|
pw.script:load_all()
|
||||||
|
|
||||||
|
print(pw.path.get().executable_path)
|
||||||
|
print(pw.path.get().resource_path)
|
||||||
|
|
||||||
|
local img = pw.image.new()
|
||||||
|
if not img:create(pw.size(64,64),pw.pixel_layout.rgb8) then
|
||||||
|
print("image couldnt be created")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- generate some noise
|
||||||
|
img:generate_noise()
|
||||||
|
|
||||||
|
-- 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.new(100,100)
|
||||||
|
|
||||||
|
-- create a new geometry
|
||||||
|
local g = pw.geometry:new()
|
||||||
|
|
||||||
|
g.primitive_topology = pw.primitive_topology_type.triangle_list -- meh
|
||||||
|
|
||||||
|
z = -5.0
|
||||||
|
s = 1
|
||||||
|
|
||||||
|
-- geometry can only build with indexed facesets
|
||||||
|
g.vertices:add(pw.vector3:new(-s, s, z)) -- 0
|
||||||
|
g.vertices:add(pw.vector3:new(-s,-s, z)) -- 1
|
||||||
|
g.vertices:add(pw.vector3:new( s,-s, z)) -- 2
|
||||||
|
g.vertices:add(pw.vector3:new( s, s, z)) -- 3
|
||||||
|
|
||||||
|
-- 0 --- 3
|
||||||
|
-- | \ |
|
||||||
|
-- 1 --- 2
|
||||||
|
|
||||||
|
g.indices:add(0)
|
||||||
|
g.indices:add(1)
|
||||||
|
g.indices:add(2)
|
||||||
|
|
||||||
|
g.indices:add(2)
|
||||||
|
g.indices:add(3)
|
||||||
|
g.indices:add(0)
|
||||||
|
|
||||||
|
|
||||||
|
local mm = pw.matrix4x4:new()
|
||||||
|
local mv = pw.matrix4x4:new()
|
||||||
|
local mp = pw.matrix4x4:new()
|
||||||
|
|
||||||
|
local s = pw.shader:new()
|
||||||
|
|
||||||
|
s:set_source(pw.shader_type.vertex,[[
|
||||||
|
#version 400
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
in vec3 vertex_p;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = projection * view * model * vec4(vertex_p, 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;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_color = texture(tex_color,vec2(1.0,1.0));
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
-- 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:new()
|
||||||
|
|
||||||
|
if not renderer:create(g) then
|
||||||
|
print("couldn't create renderer")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- camera position
|
||||||
|
local cam_pos = pw.vector3:new(0,0,0)
|
||||||
|
|
||||||
|
local model_pos = pw.vector3:new(0,0,0)
|
||||||
|
|
||||||
|
|
||||||
|
local ctx = pw.context:new()
|
||||||
|
|
||||||
|
local tx = pw.texture:new()
|
||||||
|
tx:create(img)
|
||||||
|
|
||||||
|
w.on_resize = function(self)
|
||||||
|
-- use client_size to resize the viewport
|
||||||
|
ctx:set_viewport(pw.rectangle:new(pw.point:new(0,0),self.client_size:cast_to_float()))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- setup a lua callback function as callback
|
||||||
|
w.on_update = function(self)
|
||||||
|
|
||||||
|
-- set identity on model matrix
|
||||||
|
mm:set_identity()
|
||||||
|
|
||||||
|
-- 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(1.3,aspect_ratio,0.2,100)
|
||||||
|
|
||||||
|
-- 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)
|
||||||
|
local cl = pw.vector4:new( color_red, color_green, color_blue, 1.0 )
|
||||||
|
|
||||||
|
img:generate_noise()
|
||||||
|
|
||||||
|
tx:update(img)
|
||||||
|
|
||||||
|
|
||||||
|
-- print(img.change_count)
|
||||||
|
|
||||||
|
-- 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)
|
||||||
|
|
||||||
|
s:set_uniform_texture("tex_color",tx)
|
||||||
|
|
||||||
|
|
||||||
|
tx:bind()
|
||||||
|
|
||||||
|
-- draw
|
||||||
|
renderer:draw()
|
||||||
|
|
||||||
|
tx:unbind()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
-- 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("elapsed",t.elapsed)
|
||||||
|
t:reset()
|
||||||
|
print(pw.input:get().mouse_position.x,pw.input:get().mouse_position.y,w.client_size.width,w.client_size.height)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -8,8 +8,7 @@ namespace pw {
|
||||||
|
|
||||||
class display {
|
class display {
|
||||||
public:
|
public:
|
||||||
|
using list = std::vector<display>;
|
||||||
typedef std::vector<display> list;
|
|
||||||
|
|
||||||
static const list& all() { return _displays; }
|
static const list& all() { return _displays; }
|
||||||
|
|
||||||
|
@ -18,9 +17,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
friend class window;
|
friend class window;
|
||||||
|
|
||||||
std::string _name;
|
std::string _name;
|
||||||
|
|
||||||
static list _displays;
|
static list _displays;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Why? LLVM does not adhere to C++17
|
// Why? LLVM does not adhere to C++17
|
||||||
//#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ public:
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
u_int32_t get_error() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct impl;
|
struct impl;
|
||||||
std::unique_ptr<impl> _impl;
|
std::unique_ptr<impl> _impl;
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace pw {
|
||||||
class geometry;
|
class geometry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Connects mesh data with the render backend
|
* @brief builds a renderer for geometry
|
||||||
*/
|
*/
|
||||||
class renderer {
|
class renderer {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -32,6 +32,8 @@ public:
|
||||||
bool ready() const;
|
bool ready() const;
|
||||||
|
|
||||||
shader& set_uniform_at_location(int location,float v);
|
shader& set_uniform_at_location(int location,float v);
|
||||||
|
shader& set_uniform_at_location(int location, uint32_t v);
|
||||||
|
shader &set_uniform_at_location(int location, int32_t v);
|
||||||
shader& set_uniform_at_location(int location,matrix4x4f const &v);
|
shader& set_uniform_at_location(int location,matrix4x4f const &v);
|
||||||
shader& set_uniform_at_location(int location,vector4f const &v);
|
shader& set_uniform_at_location(int location,vector4f const &v);
|
||||||
shader& set_uniform_at_location(int location,texture const &t);
|
shader& set_uniform_at_location(int location,texture const &t);
|
||||||
|
|
|
@ -33,16 +33,10 @@ public:
|
||||||
wrap_clamp_to_repeat
|
wrap_clamp_to_repeat
|
||||||
};
|
};
|
||||||
|
|
||||||
using image_ref = shared_ptr<::pw::image>;
|
|
||||||
|
|
||||||
texture();
|
texture();
|
||||||
texture(image_ref i,data_layout s);
|
texture(const image& i,data_layout s);
|
||||||
~texture();
|
~texture();
|
||||||
|
|
||||||
|
|
||||||
void set_image(image_ref i);
|
|
||||||
image_ref image() const { return _image; }
|
|
||||||
|
|
||||||
void set_shape(data_layout s);
|
void set_shape(data_layout s);
|
||||||
data_layout shape() const { return _shape; }
|
data_layout shape() const { return _shape; }
|
||||||
|
|
||||||
|
@ -50,12 +44,17 @@ public:
|
||||||
wrap_mode wrap() const { return _wrap; }
|
wrap_mode wrap() const { return _wrap; }
|
||||||
|
|
||||||
uint32_t native_handle() const;
|
uint32_t native_handle() const;
|
||||||
uint32_t native_sampler_handle() const;
|
|
||||||
|
bool create(const image &i);
|
||||||
|
void update(const image &i);
|
||||||
|
|
||||||
|
void bind();
|
||||||
|
void unbind();
|
||||||
|
|
||||||
|
bool valid() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
image_ref _image;
|
|
||||||
|
|
||||||
data_layout _shape = data_layout::shape_2d;
|
data_layout _shape = data_layout::shape_2d;
|
||||||
wrap_mode _wrap = wrap_mode::wrap_clamp_to_edge;
|
wrap_mode _wrap = wrap_mode::wrap_clamp_to_edge;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,12 @@ struct context::impl {
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t get_error() const
|
||||||
|
{
|
||||||
|
return glGetError();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
context::context()
|
context::context()
|
||||||
|
@ -54,6 +60,11 @@ void context::clear()
|
||||||
_impl->clear();
|
_impl->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u_int32_t context::get_error() const
|
||||||
|
{
|
||||||
|
return _impl->get_error();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,12 +71,16 @@ struct renderer::impl {
|
||||||
// stop binding
|
// stop binding
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
// get errors
|
// get errors
|
||||||
auto error = glGetError();
|
auto error = glGetError();
|
||||||
if (error != GL_NO_ERROR) {
|
if (error != GL_NO_ERROR) {
|
||||||
debug::e() << __PRETTY_FUNCTION__ << " GL error: " << error;
|
debug::e() << __PRETTY_FUNCTION__ << " GL error: " << error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return ready();
|
return ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +96,7 @@ struct renderer::impl {
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
|
@ -102,15 +107,18 @@ struct renderer::impl {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
glBindVertexArray(_vao);
|
glBindVertexArray(_vao);
|
||||||
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
#if 1
|
||||||
auto error = glGetError();
|
auto error = glGetError();
|
||||||
if (error != GL_NO_ERROR)
|
if (error != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
debug::e() << "GL error: " << error;
|
debug::e() << __PRETTY_FUNCTION__ << " OpenGL error: " << error;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLint get_mode(vertex_array::)
|
// GLint get_mode(vertex_array::)
|
||||||
|
|
|
@ -49,6 +49,8 @@ struct shader::impl
|
||||||
case shader::code_type::fragment:
|
case shader::code_type::fragment:
|
||||||
shader_type = GL_FRAGMENT_SHADER;
|
shader_type = GL_FRAGMENT_SHADER;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
debug::w() << " unknown shader type";
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint shaderId = glCreateShader(shader_type);
|
GLuint shaderId = glCreateShader(shader_type);
|
||||||
|
@ -175,9 +177,20 @@ struct shader::impl
|
||||||
glUniform1f(location,v);
|
glUniform1f(location,v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bind(int location,const uint32_t& i)
|
||||||
|
{
|
||||||
|
glUniform1ui(location,i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(int location,const int32_t& i)
|
||||||
|
{
|
||||||
|
glUniform1i(location,i);
|
||||||
|
}
|
||||||
|
|
||||||
void bind(int location,const texture& v)
|
void bind(int location,const texture& v)
|
||||||
{
|
{
|
||||||
glUniform1d(location,v.native_sampler_handle());
|
this->bind(location,(int)v.native_handle());
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -198,10 +211,22 @@ bool shader::ready() const
|
||||||
}
|
}
|
||||||
|
|
||||||
shader &shader::set_uniform_at_location(int location, float v)
|
shader &shader::set_uniform_at_location(int location, float v)
|
||||||
|
{
|
||||||
|
_impl->bind(location,v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
shader &shader::set_uniform_at_location(int location, uint32_t v)
|
||||||
{
|
{
|
||||||
_impl->bind(location,v); return *this;
|
_impl->bind(location,v); return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shader &shader::set_uniform_at_location(int location, int32_t v)
|
||||||
|
{
|
||||||
|
_impl->bind(location,v); return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
shader &shader::set_uniform_at_location(int location, vector4f const &v)
|
shader &shader::set_uniform_at_location(int location, vector4f const &v)
|
||||||
{
|
{
|
||||||
_impl->bind(location,v); return *this;
|
_impl->bind(location,v); return *this;
|
||||||
|
@ -212,6 +237,12 @@ shader &shader::set_uniform_at_location(int location, matrix4x4f const &v)
|
||||||
_impl->bind(location,v); return *this;
|
_impl->bind(location,v); return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
shader &shader::set_uniform_at_location(int location, texture const &v)
|
||||||
|
{
|
||||||
|
_impl->bind(location,v); return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool shader::build()
|
bool shader::build()
|
||||||
{
|
{
|
||||||
return _impl->build();
|
return _impl->build();
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "glad/glad.h"
|
#include "glad/glad.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,8 +11,9 @@ struct texture::impl {
|
||||||
|
|
||||||
texture &_host;
|
texture &_host;
|
||||||
|
|
||||||
GLuint _texture_id;
|
uint32_t _texture_id {0};
|
||||||
GLuint _texture_sampler;
|
uint32_t _texture_sampler {0};
|
||||||
|
uint64_t _change_count { std::numeric_limits<uint64_t>::max()};
|
||||||
|
|
||||||
impl() = delete;
|
impl() = delete;
|
||||||
|
|
||||||
|
@ -24,67 +27,101 @@ struct texture::impl {
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint gl_shape() {
|
bool valid() const {
|
||||||
switch (_host.shape()) {
|
return glIsTexture(_texture_id) > 0;
|
||||||
case data_layout::shape_1d:
|
|
||||||
return GL_TEXTURE_1D;
|
|
||||||
case data_layout::shape_2d:
|
|
||||||
return GL_TEXTURE_2D;
|
|
||||||
case data_layout::shape_3d:
|
|
||||||
return GL_TEXTURE_3D;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug::e() << __PRETTY_FUNCTION__ << " unknown texture layout";
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind()
|
void bind()
|
||||||
{
|
{
|
||||||
glBindTexture(gl_shape(), _texture_id);
|
glBindTexture(GL_TEXTURE_2D, _texture_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unbind()
|
void unbind()
|
||||||
{
|
{
|
||||||
glBindTexture(gl_shape(), 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_sampler()
|
void update(const class image& i)
|
||||||
{
|
{
|
||||||
bind();
|
if (_change_count != i.change_count())
|
||||||
|
{
|
||||||
|
this->bind();
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
|
||||||
|
i.size().width,i.size().height,
|
||||||
|
GL_RGB,GL_UNSIGNED_BYTE,
|
||||||
|
i.data());
|
||||||
|
|
||||||
|
auto error = glGetError();
|
||||||
|
if (error != GL_NO_ERROR) {
|
||||||
|
debug::e() << __PRETTY_FUNCTION__ << " " << __LINE__ << " GL error: " << error;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->unbind();
|
||||||
|
|
||||||
|
_change_count = i.change_count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool create(const class image& i)
|
||||||
|
{
|
||||||
|
if (i.size().area() == 0)
|
||||||
|
{
|
||||||
|
debug::w() << __PRETTY_FUNCTION__ << " empty image";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint format = GL_RGB;
|
||||||
|
|
||||||
|
glGenTextures(1, &_texture_id);
|
||||||
|
glActiveTexture(GL_TEXTURE0 + 0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D,_texture_id);
|
||||||
|
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D,0,format,
|
||||||
|
i.size().width,i.size().height,
|
||||||
|
0,format,GL_UNSIGNED_BYTE,
|
||||||
|
i.data()
|
||||||
|
);
|
||||||
|
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
// debug::e() << __PRETTY_FUNCTION__ << " " << __LINE__ << " GL error: " << glGetError();
|
||||||
|
|
||||||
|
|
||||||
|
// create sampler
|
||||||
|
|
||||||
|
#if 0
|
||||||
glGenSamplers(1, &_texture_sampler);
|
glGenSamplers(1, &_texture_sampler);
|
||||||
|
glBindSampler(0,_texture_sampler);
|
||||||
|
|
||||||
glSamplerParameteri(_texture_sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glSamplerParameteri(_texture_sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glSamplerParameteri(_texture_sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glSamplerParameteri(_texture_sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
// glSamplerParameteri(_texture_sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
// glSamplerParameteri(_texture_sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||||
glSamplerParameteri(_texture_sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glSamplerParameteri(_texture_sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glSamplerParameteri(_texture_sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glSamplerParameteri(_texture_sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
#endif
|
||||||
|
glBindTexture(GL_TEXTURE_2D,0);
|
||||||
|
|
||||||
unbind();
|
// debug::d() << "\t" << " _texture_id " << _texture_id;
|
||||||
|
// debug::d() << "\t" << "_texture_sampler " << _texture_sampler;
|
||||||
|
|
||||||
|
|
||||||
|
// get errors
|
||||||
|
auto error = glGetError();
|
||||||
|
if (error != GL_NO_ERROR) {
|
||||||
|
debug::e() << __PRETTY_FUNCTION__ << " " << __LINE__ << " GL error: " << error;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
void create()
|
|
||||||
{
|
|
||||||
|
|
||||||
auto i = _host._image;
|
|
||||||
|
|
||||||
glGenTextures(1, &_texture_id);
|
|
||||||
glBindTexture(gl_shape(),_texture_id);
|
|
||||||
|
|
||||||
GLuint format = GL_RGBA;
|
|
||||||
|
|
||||||
glTexImage2D(gl_shape(),0,format,i->size().width,i->size().height,0,format,GL_UNSIGNED_BYTE,i->data());
|
|
||||||
|
|
||||||
glGenerateMipmap(gl_shape());
|
|
||||||
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,24 +143,39 @@ texture::texture()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
texture::texture(image_ref i, texture::data_layout s)
|
texture::texture(const image &i, texture::data_layout s)
|
||||||
{
|
{
|
||||||
texture();
|
texture();
|
||||||
set_image(i);
|
this->create(i);
|
||||||
set_shape(s);
|
|
||||||
|
|
||||||
_impl->create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
texture::~texture()
|
texture::~texture()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void texture::set_image(image_ref i)
|
bool texture::create(const image& i)
|
||||||
{
|
{
|
||||||
_image = i;
|
return _impl->create(i);
|
||||||
|
}
|
||||||
|
|
||||||
_impl->create();
|
void texture::update(const image &i)
|
||||||
|
{
|
||||||
|
_impl->update(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture::bind()
|
||||||
|
{
|
||||||
|
_impl->bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture::unbind()
|
||||||
|
{
|
||||||
|
_impl->unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool texture::valid() const
|
||||||
|
{
|
||||||
|
return _impl->valid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void texture::set_shape(data_layout s)
|
void texture::set_shape(data_layout s)
|
||||||
|
@ -141,9 +193,5 @@ uint32_t texture::native_handle() const
|
||||||
return _impl->_texture_id;
|
return _impl->_texture_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t texture::native_sampler_handle() const
|
|
||||||
{
|
|
||||||
return _impl->_texture_sampler;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue