From 70424c88194f5d74c38c60c4d8313ab5132d025d Mon Sep 17 00:00:00 2001
From: Hartmut Seichter <hartmut@technotecture.com>
Date: Sun, 24 Feb 2019 22:57:06 +0100
Subject: [PATCH] some more work on the call stack of the visual component

---
 src/core/include/pw/core/image.hpp       | 17 +++++--
 src/core/include/pw/core/mesh.hpp        | 16 +++---
 src/core/src/image.cpp                   | 16 +++---
 src/io/src/image_io.cpp                  |  8 +--
 src/scene/include/pw/scene/node.hpp      |  2 +-
 src/scene/src/node.cpp                   |  2 +-
 src/visual/CMakeLists.txt                |  2 +
 src/visual/include/pw/visual/shader.hpp  |  7 ++-
 src/visual/include/pw/visual/texture.hpp |  5 +-
 src/visual/src/pass.cpp                  | 12 +++++
 src/visual/src/pipeline.cpp              | 21 +++++---
 src/visual/src/shader.cpp                | 62 +++++++++++++++---------
 src/visual/src/target.cpp                |  8 +++
 src/visual/src/texture.cpp               | 10 ++++
 src/visual/src/vertex_array.cpp          |  3 ++
 15 files changed, 136 insertions(+), 55 deletions(-)
 create mode 100644 src/visual/src/pass.cpp
 create mode 100644 src/visual/src/target.cpp

diff --git a/src/core/include/pw/core/image.hpp b/src/core/include/pw/core/image.hpp
index cb8cd03..555c09c 100644
--- a/src/core/include/pw/core/image.hpp
+++ b/src/core/include/pw/core/image.hpp
@@ -33,20 +33,27 @@ public:
 
     image() = default;
 
+	using data_t = std::byte;
+
     enum pixel_layout {
         RGB8,
         RGBA8,
-        LUM
+		LUM,
+		DEPTH,
+		HDR
     };
 
     image(const sizei& s, pixel_layout t, void *ptr = nullptr);
 
     bool create(const sizei& s, pixel_layout t, void *ptr = nullptr);
 
-    void destroy(bool release_memory = false);
+	void release(bool release_memory = false);
 
-	const uint8_t *data() const { return _data.data(); }
-	uint8_t *data() { return _data.data(); }
+	const data_t *data() const { return _data.data(); }
+	data_t *data() { return _data.data(); }
+
+	const float *data_float() const { return reinterpret_cast<const float*>(_data.data()); }
+	float *data_float() { return reinterpret_cast<float*>(_data.data());}
 
     pixel_layout layout() const;
     void set_layout(const pixel_layout &layout);
@@ -66,7 +73,7 @@ protected:
     pixel_layout _layout;
     uint64_t _change_count;
 
-    std::vector<uint8_t> _data;
+	std::vector<data_t> _data;
 
 };
 
diff --git a/src/core/include/pw/core/mesh.hpp b/src/core/include/pw/core/mesh.hpp
index 73d8103..0cbf446 100644
--- a/src/core/include/pw/core/mesh.hpp
+++ b/src/core/include/pw/core/mesh.hpp
@@ -33,10 +33,13 @@ namespace pw {
 class mesh {
 public:
 
-	typedef std::vector<int32_t> indexarray_t;
-	typedef std::vector<real_t> valuearray_t;
-	typedef std::vector<vector3> vertex3array_t;
-	typedef std::vector<vector2> vertex2array_t;
+	using index_t = unsigned int ;
+
+	using valuearray_t = std::vector<real_t> ;
+	using indexarray_t = std::vector<index_t> ;
+
+	using vertex2array_t = std::vector<vector2> ;
+	using vertex3array_t = std::vector<vector3> ;
 
 	enum topology_type {
 		triangles,
@@ -56,6 +59,9 @@ public:
 	void set_vertices(const vertex3array_t& v);
 	const vertex3array_t& vertices() const { return _vertices; }
 
+	void set_normals(const mesh::vertex3array_t &v);
+	const mesh::vertex3array_t& normals() const;
+
 	void set_topology(topology_type t) { _topology = t; }
 	topology_type topology() { return _topology; }
 
@@ -67,8 +73,6 @@ public:
 
 	void compute_normals();
 
-	void set_normals(const mesh::vertex3array_t &v);
-	const mesh::vertex3array_t& normals() const;
 
 protected:
 
diff --git a/src/core/src/image.cpp b/src/core/src/image.cpp
index 4cd44db..97cef24 100644
--- a/src/core/src/image.cpp
+++ b/src/core/src/image.cpp
@@ -11,11 +11,11 @@ image::image(const sizei &s, image::pixel_layout t, void *ptr)
 
 bool image::create(const sizei &s, image::pixel_layout t, void *ptr)
 {
-    auto n = bytes_per_pixel(t) * s.area();
+	size_t n = bytes_per_pixel(t) * s.area();
 
     if (ptr != nullptr) {
 
-        auto a = reinterpret_cast<uint8_t*>(ptr);
+		auto a = reinterpret_cast<image::data_t*>(ptr);
 
         _data.assign(a,a + n);
 		_size = s;
@@ -23,14 +23,14 @@ bool image::create(const sizei &s, image::pixel_layout t, void *ptr)
 
     } else {
 
-        _data.resize(n,0);
+		_data.resize(n);
 		_size = sizei(0,0);
     }
 
     return !_data.empty();
 }
 
-void image::destroy(bool release_memory)
+void image::release(bool release_memory)
 {
     _data.clear();
 
@@ -41,11 +41,13 @@ uint32_t image::bytes_per_pixel(image::pixel_layout t)
 {
     switch (t) {
     case pw::image::RGB8:
-        return 3;
+		return 3 * sizeof(data_t);
     case pw::image::RGBA8:
-        return 4;
+		return 4 * sizeof(data_t);
     case pw::image::LUM:
-        return 1;
+		return 1 * sizeof(data_t);
+	case pw::image::DEPTH:
+		return 1 * sizeof(float);
     }
 
     return std::numeric_limits<uint32_t>::max();
diff --git a/src/io/src/image_io.cpp b/src/io/src/image_io.cpp
index 92d41af..f90981c 100644
--- a/src/io/src/image_io.cpp
+++ b/src/io/src/image_io.cpp
@@ -18,8 +18,7 @@ struct image_io::impl
     image read_impl(const std::string& uri,uint32_t flags)
     {
         int x,y,n;
-
-        unsigned char *data = stbi_load(uri.c_str(), &x, &y, &n, 4);
+		auto data = stbi_load(uri.c_str(), &x, &y, &n, 4);
 
         if (data) {
 
@@ -30,7 +29,10 @@ struct image_io::impl
 			stbi_image_free(data);
 
             return r;
-        }
+		} else {
+
+			debug::e() << stbi_failure_reason();
+		}
 
         return image();
     }
diff --git a/src/scene/include/pw/scene/node.hpp b/src/scene/include/pw/scene/node.hpp
index 4b96895..6b2466b 100644
--- a/src/scene/include/pw/scene/node.hpp
+++ b/src/scene/include/pw/scene/node.hpp
@@ -44,7 +44,7 @@ public:
 
 	friend class component;
 
-    typedef shared_ptr<node> ref;
+	typedef shared_ptr<node> ref;
 	typedef std::vector<ref> ref_array;
 
 	typedef node *ptr;
diff --git a/src/scene/src/node.cpp b/src/scene/src/node.cpp
index bfe57b1..6aeb1d7 100644
--- a/src/scene/src/node.cpp
+++ b/src/scene/src/node.cpp
@@ -52,7 +52,7 @@ void node::remove_child(ref child_node)
          it != _children.end();
          it++)
     {
-        if (child_node == *it) it = _children.erase(it);
+		if (child_node == *it) it = _children.erase(it);
     }
 //    auto it = _children.end();
 
diff --git a/src/visual/CMakeLists.txt b/src/visual/CMakeLists.txt
index 9fe9742..1c566c0 100644
--- a/src/visual/CMakeLists.txt
+++ b/src/visual/CMakeLists.txt
@@ -9,7 +9,9 @@ set(hdrs
 set(srcs
 	src/shader.cpp
 	src/context.cpp
+	src/pass.cpp
 	src/pipeline.cpp
+	src/target.cpp
 	src/texture.cpp
 	src/vertex_array.cpp
 	)
diff --git a/src/visual/include/pw/visual/shader.hpp b/src/visual/include/pw/visual/shader.hpp
index e54e2d5..a11681b 100644
--- a/src/visual/include/pw/visual/shader.hpp
+++ b/src/visual/include/pw/visual/shader.hpp
@@ -51,10 +51,13 @@ public:
     void use();
 
 	using uniform_t = std::variant<bool,int,float,double,vector2f,vector3f,vector4f,matrix4x4f>;
+	using uniform_entry_t = std::tuple<std::string,uniform_t,int>;
 
-	using uniform_set = std::map<std::string,uniform_t>;
+	using uniform_cache_t = std::vector<uniform_entry_t>;
 
-	void set_uniforms(uniform_set s);
+	void set_uniforms(uniform_cache_t c);
+
+	unsigned int native_handle() const;
 
 protected:
 
diff --git a/src/visual/include/pw/visual/texture.hpp b/src/visual/include/pw/visual/texture.hpp
index 3f59c67..f92beb1 100644
--- a/src/visual/include/pw/visual/texture.hpp
+++ b/src/visual/include/pw/visual/texture.hpp
@@ -8,7 +8,7 @@
 namespace pw {
 
 class texture {
-
+public:
 	enum class data_type {
 		color,
 		normal
@@ -51,6 +51,9 @@ class texture {
 
 	void generate_mipmaps();
 
+
+	unsigned int native_handle() const;
+	unsigned int native_sampler_handle() const;
 protected:
 
 	shared_ptr<image> _image;
diff --git a/src/visual/src/pass.cpp b/src/visual/src/pass.cpp
new file mode 100644
index 0000000..c4be354
--- /dev/null
+++ b/src/visual/src/pass.cpp
@@ -0,0 +1,12 @@
+//
+// a pass combines meshes, states and targets
+//
+
+namespace pw {
+
+
+class pass {
+	virtual void submit();
+};
+
+}
diff --git a/src/visual/src/pipeline.cpp b/src/visual/src/pipeline.cpp
index ffbe7ee..f54f6ac 100644
--- a/src/visual/src/pipeline.cpp
+++ b/src/visual/src/pipeline.cpp
@@ -126,6 +126,9 @@ struct triangle_renderer
 	void draw()
 	{
 
+		// input needed here -
+		// model view projection
+
 		shader_p.use();
 
 		auto v_col = ping_pong(static_cast<float>(time::now()),1.0f);
@@ -150,6 +153,9 @@ struct triangle_renderer
 #endif
 
 
+		// now bind textures
+
+
 #if 1
 		auto proj_mat = matrix_transform<float>::orthographic_projection(1.3,1.0,
 																		 0.2f,100.f);
@@ -161,19 +167,22 @@ struct triangle_renderer
 																		0.2f,1000.f);
 
 #endif
+
+
+#if 0
 		// highly inefficient - should be cached -
 		shader_p.set("input_color",col);
 		shader_p.set("model",model_mat);
 		shader_p.set("view",view_mat);
 		shader_p.set("projection",proj_mat);
 
-#if 0
+#else
 		// new version with ...
-		shader::uniform_set us;
-		us["input_color"] = col;
-		us["model"] = model_mat;
-		us["view"] = view_mat;
-		us["projection"] = proj_mat;
+		shader::uniform_cache_t us;
+		us.push_back(std::make_tuple("input_color",col,-1));
+		us.push_back(std::make_tuple("model",model_mat,-1));
+		us.push_back(std::make_tuple("view",view_mat,-1));
+		us.push_back(std::make_tuple("projection",proj_mat,-1));
 
 		shader_p.set_uniforms(us);
 
diff --git a/src/visual/src/shader.cpp b/src/visual/src/shader.cpp
index ddb29e4..f4d077c 100644
--- a/src/visual/src/shader.cpp
+++ b/src/visual/src/shader.cpp
@@ -6,8 +6,6 @@
 
 namespace pw {
 
-// TODO: move this to a separate implementation
-
 struct shader::impl
 {
 	shader& _shader;
@@ -69,12 +67,12 @@ struct shader::impl
 
 				glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &log_length);
 
-				std::unique_ptr<char[]> log_buffer(new char[log_length]);
+				std::vector<char> log_buffer(static_cast<size_t>(log_length));
 
-				glGetShaderInfoLog(shaderId, log_length, &log_length, log_buffer.get());
+				glGetShaderInfoLog(shaderId, log_length, &log_length, log_buffer.data());
 
 				// TODO - handle errors!
-				debug::e() << log_buffer.get();
+				debug::e() << log_buffer.data();
 
 				return false;
 			}
@@ -110,12 +108,12 @@ struct shader::impl
 			glGetProgramiv(_shader_program, GL_INFO_LOG_LENGTH, &log_length);
 
 			/* The maxLength includes the NULL character */
-			std::unique_ptr<char []> info_log(new char[log_length]);
+			std::vector<char> info_log(static_cast<size_t>(log_length));
 
 			/* Notice that glGetProgramInfoLog, not glGetShaderInfoLog. */
-			glGetProgramInfoLog(_shader_program, log_length, &log_length, info_log.get());
+			glGetProgramInfoLog(_shader_program, log_length, &log_length, info_log.data());
 
-			debug::e() << info_log.get();
+			debug::e() << info_log.data();
 
 			/* Handle the error in an appropriate way such as displaying a message or writing to a log file. */
 			/* In this simple program, we'll just leave */
@@ -186,6 +184,11 @@ bool shader::ready() const
 	return _impl->is_valid();
 }
 
+shader &shader::set(int location, float v)
+{
+	_impl->bind(location,v); return *this;
+}
+
 shader &shader::set(int location, const vector4f &v)
 {
 	_impl->bind(location,v); return *this;
@@ -206,29 +209,42 @@ void shader::use()
 	_impl->use();
 }
 
-void shader::set_uniforms(shader::uniform_set s)
+void shader::set_uniforms(uniform_cache_t c)
 {
-	for (auto& u : s) {
-//		std::visit(
-//					[u](auto&& arg){
-//						std::cout << u.first << " " << typeid(arg).name() << std::endl;
-//					},
-//			u.second);
+	for (auto& u : c) {
+		// get name
+		std::string name = std::get<0>(u);
+		// get location
+		GLint loc = std::get<2>(u);
 
-		std::tuple<std::string,int,uniform_t> uuu;
+		// if lower 0 check for location
+		if (loc < 0) {
+			loc = _impl->uniform_location(name);
+			std::get<2>(u) = loc; // cache location
+		}
+
+		auto var = std::get<1>(u);
+
+		std::visit([this,loc](auto&& arg) {
 
-		std::visit([u](auto&& arg) {
 			using T = std::decay_t<decltype(arg)>;
-			if constexpr (std::is_same_v<T, vector4f>)
-//					set(arg);
-				std::cout << "vec4f with type " << typeid(arg).name() << " " << serialize::matrix(arg) << '\n';
-			else
-				std::cout << "can't" << std::endl;
-		}, u.second);
 
+			if constexpr ((std::is_same_v<T, vector4f>) ||
+				(std::is_same_v<T, matrix4x4f>) ||
+				(std::is_same_v<T, float>) ) {
+					set(loc, std::forward<T>(arg));
+			} else {
+				std::cout << "can't" << std::endl;
+			}
+		}, var);
 	}
 }
 
+unsigned int shader::native_handle() const
+{
+	return _impl->_shader_program;
+}
+
 int shader::uniform_location(const std::string &name) const
 {
 	return _impl->uniform_location(name);
diff --git a/src/visual/src/target.cpp b/src/visual/src/target.cpp
new file mode 100644
index 0000000..81284dd
--- /dev/null
+++ b/src/visual/src/target.cpp
@@ -0,0 +1,8 @@
+
+//
+// receives render command results such as a framebuffer, g-buffer or the like
+//
+
+namespace pw {
+
+}
diff --git a/src/visual/src/texture.cpp b/src/visual/src/texture.cpp
index 6cfc4d9..d997e5f 100644
--- a/src/visual/src/texture.cpp
+++ b/src/visual/src/texture.cpp
@@ -107,5 +107,15 @@ void texture::generate_mipmaps()
 	_impl->generate_mipmaps();
 }
 
+unsigned int texture::native_handle() const
+{
+	return _impl->_texture_id;
+}
+
+unsigned int texture::native_sampler_handle() const
+{
+	return _impl->_texture_sampler;
+}
+
 
 }
diff --git a/src/visual/src/vertex_array.cpp b/src/visual/src/vertex_array.cpp
index ee0fe91..0d0511d 100644
--- a/src/visual/src/vertex_array.cpp
+++ b/src/visual/src/vertex_array.cpp
@@ -12,7 +12,10 @@ namespace pw {
 struct vertex_array::impl {
 
 	GLuint _vao = 0;
+
+
 	std::vector<GLuint> _vbos;
+
 	GLint _mesh_elements = {0};
 
 	impl()