From 1a94259666a0d98e98e6999f19cf07475b618e65 Mon Sep 17 00:00:00 2001
From: chai <chaifix@163.com>
Date: Tue, 25 Feb 2020 23:41:30 +0800
Subject: *camera

---
 src/example/03_texture/03_texture.c |  2 +-
 src/extend/camera.c                 | 67 +++++++++++++++++++++++++------------
 src/extend/camera.h                 | 24 ++++++++-----
 src/extend/transform.h              |  6 ++--
 src/main.c                          | 41 ++++++++++++-----------
 src/shaders/common.c                | 12 ++++++-
 src/shaders/common.h                | 15 ++++++++-
 src/shaders/pbr.c                   | 11 ++++--
 8 files changed, 120 insertions(+), 58 deletions(-)

diff --git a/src/example/03_texture/03_texture.c b/src/example/03_texture/03_texture.c
index 352ea9c..c09efe0 100644
--- a/src/example/03_texture/03_texture.c
+++ b/src/example/03_texture/03_texture.c
@@ -100,7 +100,7 @@ void onupdate_texture(void*data) {
 }
 
 void ondraw_texture(void*data) {
-	ssr_clearcolor(0xff202020);
+	ssr_clearcolor(0);
 	ssr_cleardepth();
 	ssr_clearstencil(0);
 /*
diff --git a/src/extend/camera.c b/src/extend/camera.c
index e580b79..15bcc58 100644
--- a/src/extend/camera.c
+++ b/src/extend/camera.c
@@ -1,31 +1,38 @@
+#include "../shaders/common.h"
+#include "../core/device.h"
 #include "camera.h"
 
-// A unity editor style camera
 
-void camera_init(Camera* cam, wog_Window* wnd) {
+Camera* camera_create(wog_Window* wnd, CameraConfig* config) {
+	Camera* cam = ssrM_new(Camera);
+	
 	cam->is_viewdirty = cam->is_projdirty = TRUE;
 
 	// camera local = world
 	cam->transform.parent = NULL ;
-	cam->transform.localposition = vec3_make(0, 0, 800);
+	cam->transform.localposition = config->position;
 	cam->transform.localscale = vec3_make(1, 1, 1);
-	cam->transform.localrotation = quat_make(0, 0, 0);
+	quat_fromeuler(&config->euler, &cam->transform.localrotation);
 
-	cam->near = 1; 
-	cam->far = 5500;
-	cam->aspect = 600/480.f;
-	cam->fov = 60;
-	cam->zoom_speed = 4000;
+	cam->near = config->near; 
+	cam->far = config->far;
+	cam->aspect = config->aspect;
+	cam->fov = config->fov;
+	cam->zoom_speed = config->zoom_speed;
 
 	cam->look_around = FALSE;
 	cam->move_around = FALSE;
-	cam->rotate_sensitivity.x = 5;
-	cam->rotate_sensitivity.y = 5;
-	cam->move_sensitivity.x = 150;
-	cam->move_sensitivity.y = 150;
-	cam->euler.yaw = cam->euler.pitch = cam->euler.roll = 0;
-
+	cam->rotate_sensitivity = config->rotate_sensitivity;
+	cam->move_sensitivity = config->move_sensitivity;
+	cam->euler = cam->euler;
 	cam->wnd = wnd;
+
+	return cam;
+}
+
+void camera_destroy(Camera* cam) {
+	if(cam == NULL) return ;
+	ssrM_free(cam);
 }
 
 void camera_getmatrix(Camera* cam, Mat4* view, Mat4* proj) {
@@ -35,21 +42,21 @@ void camera_getmatrix(Camera* cam, Mat4* view, Mat4* proj) {
 
 void camera_getviewmatrix(Camera* cam, Mat4* out) {
 	if (!cam->is_viewdirty) {
-		if (out)*out = cam->view_matrix;
+		if (out)*out = cam->cached_view_matrix;
 		return;
 	}
-	transform_getinvmatrixnoscale(&cam->transform, &cam->view_matrix);
-	if(out) *out = cam->view_matrix;
+	transform_getinvmatrixnoscale(&cam->transform, &cam->cached_view_matrix);
+	if(out) *out = cam->cached_view_matrix;
 	cam->is_viewdirty = FALSE;
 }
 
 void camera_getprojmatrix(Camera* cam, Mat4* out) {
 	if (!cam->is_projdirty) {
-		if (out)*out = cam->proj_matrix;
+		if (out)*out = cam->cached_proj_matrix;
 		return;
 	}
-	mat4_setperspective(cam->fov, cam->aspect, cam->near, cam->far, &cam->proj_matrix);
-	if(out) *out = cam->proj_matrix;
+	mat4_setperspective(cam->fov, cam->aspect, cam->near, cam->far, &cam->cached_proj_matrix);
+	if(out) *out = cam->cached_proj_matrix;
 	cam->is_projdirty = FALSE;
 }
 
@@ -123,4 +130,20 @@ void camera_onupdate(Camera* cam, float dt) {
 		_onlookaround(cam, dt);
 	if (cam->move_around)
 		_onmovearound(cam, dt);
-}
\ No newline at end of file
+}
+
+void camera_ondraw(Camera* cam) {
+	/*set vp matrix*/
+	ssr_matrixmode(MATRIX_PROJECTION);
+	camera_getprojmatrix(&cam, NULL);
+	ssr_loadmatrix(&cam->cached_proj_matrix);
+	ssr_matrixmode(MATRIX_VIEW);
+	camera_getviewmatrix(&cam, NULL);
+	ssr_loadmatrix(&cam->cached_view_matrix);
+	ssr_matrixmode(MATRIX_MODEL);
+	/*set builtin variables*/
+	_proj_params.x = cam->near;
+	_proj_params.y = cam->far;
+	_proj_params.z = cam->fov;
+	_proj_params.w = cam->aspect;
+}
diff --git a/src/extend/camera.h b/src/extend/camera.h
index e43efe6..98e3e5a 100644
--- a/src/extend/camera.h
+++ b/src/extend/camera.h
@@ -2,22 +2,22 @@
 #define _SOFTSHADEROOM_CAMERA_H_
 
 #include "../math/math.h"
-#include "transform.h"
-#include "../extern/wog.h"
 #include "../extern/wog.h"
+#include "transform.h"
 
 #undef near 
 #undef far
 
-typedef struct  {
+// A unity editor style camera
+typedef struct Camera {
 	Transform transform;
 	float fov, aspect, near, far;
 	/*matrix*/
-	Mat4 view_matrix; /*or WorldToCameraMatrix*/
-	Mat4 proj_matrix;
+	Mat4 cached_view_matrix; /*or WorldToCameraMatrix*/
+	Mat4 cached_proj_matrix;
 	bool is_viewdirty, is_projdirty;
 	/*operations*/
-	float zoom_speed; 
+	float zoom_speed;
 	Vec2 rotate_sensitivity;
 	Vec2 move_sensitivity;
 	Euler euler;
@@ -29,12 +29,16 @@ typedef struct  {
 	wog_Window* wnd;
 } Camera;
 
-typedef struct CameraConfig {
+typedef struct {
+	Vec3 position;
+	Euler euler;
 	float fov, aspect, near, far;
-	Vec3 pos; 
+	Vec2 rotate_sensitivity, move_sensitivity; 
+	float zoom_speed;
 }CameraConfig;
 
-void camera_init(Camera* cam, wog_Window* wnd);
+Camera* camera_create(wog_Window* wnd, CameraConfig* config);
+void camera_destroy(Camera* cam);
 
 void camera_setposition(float x, float y, float z);
 
@@ -46,4 +50,6 @@ void camera_getmatrix(Mat4* view, Mat4* proj);
 void camera_getviewmatrix(Camera* cam, Mat4* view);
 void camera_getprojmatrix(Camera* cam, Mat4* proj);
 
+void camera_ondraw(Camera* cam);
+
 #endif
\ No newline at end of file
diff --git a/src/extend/transform.h b/src/extend/transform.h
index 330c023..cef4344 100644
--- a/src/extend/transform.h
+++ b/src/extend/transform.h
@@ -12,9 +12,9 @@ typedef struct Transform {
 	Quat localrotation;
 	/*global*/
 	Transform* parent;
-	Vec3 position;
-	Vec3 scale; 
-	Quat rotation;
+	Vec3 cached_position;
+	Vec3 cached_scale;
+	Quat cached_rotation;
 } Transform;
 
 void transform_translate(Transform* trans, Vec3* v);
diff --git a/src/main.c b/src/main.c
index 292d663..9f0a017 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5,10 +5,11 @@
 #include "ssr.h"
 #include "example/example.h"
 #include "extern/wog.h"
+#include "shaders/common.h"
 #include "extend/camera.h"
 
-#define SCREEN_WIDTH 600
-#define SCREEN_HEIGHT 480
+#define SCREEN_WIDTH 600.f
+#define SCREEN_HEIGHT 480.f
 
 typedef void(*F)(void*);
 
@@ -38,22 +39,28 @@ int main(int argc, char* argv[]) {
 	};
 	ssr_init(&config);
 	SETEXAMPLE(EXAMPLECUR);
-	onload(NULL);
-	wog_show(wnd);
 	/*set up global camera*/
-	Camera cam;
-	camera_init(&cam, wnd);
+	CameraConfig cam_config = { /*default camera setting*/
+		{0, 700, 0},
+		{0, 0, 0},
+		60, SCREEN_WIDTH / SCREEN_HEIGHT, 0.1, 2000,
+		5, 150,
+		4000,
+	};
+	onload(&cam_config);
+	Camera* camera = camera_create(wnd, &cam_config);
+	wog_show(wnd);
 	/* main loop */
 	uint prev = wog_tick();
 	uint dt = 0;
-	float _dt = 0;
+	float _dt = 0, _duration;
 	uint frame_count = 0;
 	uint time_stamp = 0;
 	wog_Event e;
 	while (1) {
 		/*handle events*/
 		while (wog_pollEvent(wnd, &e)) {
-			camera_onevent(&cam, &e, _dt);
+			camera_onevent(&camera, &e, _dt);
 			if (e.type == WOG_ECLOSE) {
 				goto quit;
 			} else {
@@ -71,22 +78,17 @@ int main(int argc, char* argv[]) {
 			time_stamp -= 1000;
 			frame_count = 0;
 		}
+
+		_time.x = _dt;
+		_time.y = prev / 1000.f;
 	
 		/*update*/
 		_dt = dt / 1000.f;
-		camera_onupdate(&cam, _dt);
+		camera_onupdate(&camera, _dt);
 		onupdate(&_dt);
-
-		/*set vp matrix*/
-		ssr_matrixmode(MATRIX_PROJECTION);
-		camera_getprojmatrix(&cam, NULL);
-		ssr_loadmatrix(&cam.proj_matrix);
-		ssr_matrixmode(MATRIX_VIEW);
-		camera_getviewmatrix(&cam, NULL);
-		ssr_loadmatrix(&cam.view_matrix);
-		ssr_matrixmode(MATRIX_MODEL);
-
+		
 		/*draw*/
+		camera_ondraw(camera);
 		ondraw(NULL);
 
 		ssr_present();
@@ -95,6 +97,7 @@ int main(int argc, char* argv[]) {
 	}
 	
 	quit:
+	camera_destroy(camera);
 	wog_destroyWindow(wnd);
 
 	return 0;
diff --git a/src/shaders/common.c b/src/shaders/common.c
index 3b58524..411c7e4 100644
--- a/src/shaders/common.c
+++ b/src/shaders/common.c
@@ -1,6 +1,9 @@
 #include "common.h"
 
-Vec3 normal_from_color(Color32 c32) {
+Vec4 _proj_params;
+Vec2 _time;
+
+Vec3 unpacknormal(Color32 c32) {
 	Vec3 normal = {
 		c32.r * 2 - 1,
 		c32.g * 2 - 1,
@@ -25,4 +28,11 @@ Vec2 texsize(Texture* texture) {
 	return size;
 }
 
+float linear01depth(float depth) {
+	float n = _proj_params.x, f = _proj_params.y;
+	return n / ((n-f)*depth + f);
+}
 
+float lineareyedepth(float depth) {
+	return _proj_params.y * linear01depth(depth);
+}
\ No newline at end of file
diff --git a/src/shaders/common.h b/src/shaders/common.h
index 7e0ca5f..36f80c0 100644
--- a/src/shaders/common.h
+++ b/src/shaders/common.h
@@ -25,12 +25,22 @@
 #define _mvp_matrix (uniforms->mvp)
 #define _it_model_matrix /*inverse-transpose model matrix if needed*/
 
+// near 
+// far 
+// fov
+// aspect
+Vec4 _proj_params;
+
+// dt 
+// duration
+Vec2 _time;
+
 /************************************************************************/
 /* functions                                                            */
 /************************************************************************/
 
 /*shader built in functions*/
-Vec3 normal_from_color(Color32 c32);
+Vec3 unpacknormal(Color32 c32);
 
 Mat4 mat4(Vec4* c1, Vec4* c2, Vec4* c3, Vec4* c4);
 Mat3 mat3(Vec3* c1, Vec3* c2, Vec3* c3);
@@ -62,4 +72,7 @@ out_v3->x = color.x * 2 - 1; \
 out_v3->y = color.y * 2 - 1; \
 out_v3->z = color.z * 2 - 1; 
 
+float linear01depth(float depth);
+float lineareyedepth(float depth);
+
 #endif
\ No newline at end of file
diff --git a/src/shaders/pbr.c b/src/shaders/pbr.c
index 6db3d68..666f758 100644
--- a/src/shaders/pbr.c
+++ b/src/shaders/pbr.c
@@ -15,7 +15,7 @@
 #define _rough            reg_num_00
 #define _world_pos        reg_v3_00
 #define _depth_pos        reg_v3_01
-#define _clip_pos         reg_v4_00
+#define _clip_pos         reg_v2_01
 #define _world_normal     reg_v3_02 
 #define _world_tangent    reg_v3_03
 #define _world_bitangent  reg_v3_04
@@ -34,6 +34,8 @@ static void vert(UniformCollection* uniforms, VertexShaderIn* in, Vec4* clipcoor
 	//*rough = 1 - vec3_dot(&worldnormal, light);
 	//*vnormal = in->vertex->normal;
 	*_texcoord = in->vertex->texcoord;
+	_clip_pos->x = clipcoord->z;
+	_clip_pos->y = clipcoord->w;
 }
 
 static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color32* color) {
@@ -46,11 +48,15 @@ static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color32* col
 	//(*color).a = 1;
 	//return 1;
 	//float rough = 1- vec3_dot(&in->normal, light);
+	float depth = _clip_pos->x / _clip_pos->y;
+	depth = (depth + 1) / 2;
+	depth = linear01depth(depth);
 	Color32 c = tex2d(_albedo_tex, _texcoord);
 	//Color32 nc = tex2d(noramltex, in->texcoord);
 	//vec3_scale(&c, roughness, &c);
 	color32_saturate(&c);
 	*color = c;
+	vec3_scale(color, 1 - depth, color);
 	return 1;
 }
 
@@ -64,5 +70,6 @@ Program ssr_built_in_shader_pbr = {
 	//VARYING_V3_04 |
 	//VARYING_V4_00 |
 	VARYING_V2_00 | 
-	VARYING_V3_05
+	VARYING_V3_05 | 
+	VARYING_V2_01 
 };
-- 
cgit v1.1-26-g67d0