From 372d77e436d21312ef1a0df622964751716963a3 Mon Sep 17 00:00:00 2001
From: chai <chaifix@163.com>
Date: Wed, 26 Feb 2020 22:52:19 +0800
Subject: *misc

---
 src/core/clip.c                     |  2 +-
 src/core/device.c                   |  6 +--
 src/core/limits.h                   |  2 +-
 src/core/rasterizer.c               | 20 +++++----
 src/core/shader.c                   | 15 ++++---
 src/core/shader.h                   | 10 ++---
 src/example/03_texture/03_texture.c | 44 ++++++--------------
 src/example/example.h               |  5 ++-
 src/extend/camera.c                 | 24 ++++++++---
 src/extend/light.c                  |  0
 src/extend/light.h                  | 25 +++++++++++
 src/extend/scene.c                  |  5 +++
 src/extend/scene.h                  | 17 ++++++++
 src/extend/transform.h              | 14 ++++---
 src/extern/wog.c                    |  4 +-
 src/extern/wog.h                    | 72 ++++++++++++++++++++++++++++++++
 src/gizmo/gizmo.c                   | 83 +++++++++++++++++++++++++++++++++++++
 src/gizmo/gizmo.h                   | 12 +++++-
 src/main.c                          | 66 +++++++++++++++++++++--------
 src/shaders/common.c                |  1 +
 src/shaders/common.h                |  6 +++
 src/shaders/pbr.c                   |  2 +-
 22 files changed, 346 insertions(+), 89 deletions(-)
 create mode 100644 src/extend/light.c
 create mode 100644 src/extend/light.h
 create mode 100644 src/extend/scene.c
 create mode 100644 src/extend/scene.h
 create mode 100644 src/gizmo/gizmo.c

(limited to 'src')

diff --git a/src/core/clip.c b/src/core/clip.c
index 48c376d..eb42fb7 100644
--- a/src/core/clip.c
+++ b/src/core/clip.c
@@ -190,7 +190,7 @@ static bool clip_against_plane(
 	, byte* dst_data[]
 	, uint prim_vcount/*minimum number of primitive vertices*/
 ) {
-	bool varying = varying_flag & VARYING_ANY;
+	bool varying = (varying_flag & VARYING_ANY) != 0;
 	int idx = 0;
 	ClippedVert *prev, *curr;
 	uint previ, curri;
diff --git a/src/core/device.c b/src/core/device.c
index 70ae11f..6b2bb7c 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -22,7 +22,7 @@ typedef struct {
 } VertexAttr;
 
 static struct {
-	Mat4 matrices[3][MATRIXDEPTH];
+	Mat4 matrices[3][MATRIX_DEPTH];
 	uint matrix_top[3];
 	ssr_MatrixMode matrix_mode;
 
@@ -155,13 +155,13 @@ void ssr_loadidentity() {
 }
 
 void ssr_pushmatrix() {
-	ssr_assert(MATRIXTOP < MATRIXDEPTH - 1);
+	ssr_assert(MATRIXTOP < MATRIX_DEPTH - 1);
 	++MATRIXTOP;
 	MATRIX = MATRIXSTACK[MATRIXTOP - 1];
 }
 
 void ssr_popmatrix() {
-	MATRIXTOP = clamp(--MATRIXTOP, 0, MATRIXDEPTH - 1);
+	MATRIXTOP = clamp(--MATRIXTOP, 0, MATRIX_DEPTH - 1);
 }
 
 /*http://warmcat.org/chai/blog/?p=559*/
diff --git a/src/core/limits.h b/src/core/limits.h
index 4ef0b75..229f535 100644
--- a/src/core/limits.h
+++ b/src/core/limits.h
@@ -1,6 +1,6 @@
 #ifndef _SOFTSHADEROOM_LIMITS_H_
 #define _SOFTSHADEROOM_LIMITS_H_
 
-#define MATRIXDEPTH 32
+#define MATRIX_DEPTH 32
 
 #endif
\ No newline at end of file
diff --git a/src/core/rasterizer.c b/src/core/rasterizer.c
index d6a9fc1..d926cb0 100644
--- a/src/core/rasterizer.c
+++ b/src/core/rasterizer.c
@@ -237,15 +237,15 @@ void ssrR_line(
 ) {
 	ssr_assert(CA && CB && program && uniforms);
 
-	Vec3 SA, SB;
-	vec4_dividew(CA, &SA); ssrU_viewport(&SA, &SA);
-	vec4_dividew(CB, &SB); ssrU_viewport(&SB, &SB);
+	Vec4 SA, SB;
+	vec4_dividewnoz(CA, &SA); ssrU_viewport(&SA, &SA);
+	vec4_dividewnoz(CB, &SB); ssrU_viewport(&SB, &SB);
 
 	FragmentShader frag_shader = program->fragmentshader;
 	
 	int x0 = SA.x, y0 = SA.y;
 	int x1 = SB.x, y1 = SB.y;
-	float wA = 1 / CA->w, wB = 1 / CB->w;
+	float wA = SA.w, wB = SB.w;
 	float zA = SA.z, zB = SB.z;
 	
 	bool steep = FALSE;
@@ -262,6 +262,8 @@ void ssrR_line(
 		swapf(zA, zB);
 	}
 
+	float inv_wA = 1 / wA, inv_wB = 1 / wB;
+
 	bool depth_test = ssr_isenable(ENABLE_DEPTHTEST);
 	bool blend = ssr_isenable(ENABLE_BLEND);
 	bool write_depth = ssr_isenable(ENABLE_WRITEDEPTH);
@@ -274,15 +276,15 @@ void ssrR_line(
 
 #define discardif(condition) if(condition) continue
 
-	float t, depth;
+	float t, z, w, depth;
 	Vec2 c;
 	int x, y, px, py;
 	for (x = x0; x <= x1; ++x) {
 		t = (x - x0) / (float)(x1 - x0);
 		y = y0 + (y1 - y0)*t;
 		/*caculate center*/
-		c.x = (1 - t) * wA;
-		c.y = t * wB;
+		c.x = (1 - t) * inv_wA;
+		c.y = t * inv_wB;
 		discardif(compare(c.x+c.y, 0));
 		c.x /= (c.x + c.y);
 		t = 1 - c.x;
@@ -295,7 +297,9 @@ void ssrR_line(
 			py = y; 
 		}
 		if (depth_test) {
-			ssrS_lerpnum(t, &zA, &zB, &depth);
+			ssrS_lerpnum(t, &zA, &zB, &z);
+			ssrS_lerpnum(t, &wA, &wB, &w);
+			depth = z / w;
 			pass_depth_test = ssr_testdepth(px, py, depth);
 		}
 		if (stencil_test) {
diff --git a/src/core/shader.c b/src/core/shader.c
index 899a160..b523df7 100644
--- a/src/core/shader.c
+++ b/src/core/shader.c
@@ -267,35 +267,40 @@ Vec4* ssrS_bcpvec4(Vec3* bc, Vec4* A, Vec4* B, Vec4* C, Vec4* out) {
 	return out;
 }
 
-void ssrS_lerpnum(float t, float* A, float* B, float* out) {
+float* ssrS_lerpnum(float t, float* A, float* B, float* out) {
 	*out = lerp(*A, *B, t);
+	return out;
 }
 
-void ssrS_lerpcolor(float t, Color A, Color B, Color* out) {
+Color* ssrS_lerpcolor(float t, Color A, Color B, Color* out) {
 	*out = ssr_color(
 		lerp(COLOR_R(A), COLOR_R(B), t),
 		lerp(COLOR_G(A), COLOR_G(B), t),
 		lerp(COLOR_B(A), COLOR_B(B), t),
 		lerp(COLOR_A(A), COLOR_A(B), t)
 	);
+	return out;
 }
 
-void ssrS_lerpvec2(float t, Vec2* A, Vec2* B, Vec2* out) {
+Vec2* ssrS_lerpvec2(float t, Vec2* A, Vec2* B, Vec2* out) {
 	out->x = lerp(A->x, B->x, t);
 	out->y = lerp(A->y, B->y, t);
+	return out;
 }
 
-void ssrS_lerpvec3(float t, Vec3* A, Vec3* B, Vec3* out) {
+Vec3* ssrS_lerpvec3(float t, Vec3* A, Vec3* B, Vec3* out) {
 	out->x = lerp(A->x, B->x, t);
 	out->y = lerp(A->y, B->y, t);
 	out->z = lerp(A->z, B->z, t);
+	return out;
 }
 
-void ssrS_lerpvec4(float t, Vec4* A, Vec4* B, Vec4* out) {
+Vec4* ssrS_lerpvec4(float t, Vec4* A, Vec4* B, Vec4* out) {
 	out->x = lerp(A->x, B->x, t);
 	out->y = lerp(A->y, B->y, t);
 	out->z = lerp(A->z, B->z, t);
 	out->w = lerp(A->w, B->w, t);
+	return out;
 }
 
 static Color32 _out_color[RENDER_TARGET_COUNT];
diff --git a/src/core/shader.h b/src/core/shader.h
index 26606b8..70b4ce9 100644
--- a/src/core/shader.h
+++ b/src/core/shader.h
@@ -113,11 +113,11 @@ Vec2*  ssrS_bcpvec2(Vec3* bc, Vec2* A, Vec2* B, Vec2* C, Vec2* out);
 Vec3* ssrS_bcpvec3(Vec3* bc, Vec3* A, Vec3* B, Vec3* C, Vec3* out);
 Vec4* ssrS_bcpvec4(Vec3* bc, Vec4* A, Vec4* B, Vec4* C, Vec4* out);
 
-void ssrS_lerpcolor(float t, Color A, Color B, Color* out);
-void ssrS_lerpnum(float t, float* A, float* B, float* out);
-void ssrS_lerpvec2(float t, Vec2* A, Vec2* B, Vec2* out);
-void ssrS_lerpvec3(float t, Vec3* A, Vec3* B, Vec3* out);
-void ssrS_lerpvec4(float t, Vec4* A, Vec4* B, Vec4* out);
+Color* ssrS_lerpcolor(float t, Color A, Color B, Color* out);
+float* ssrS_lerpnum(float t, float* A, float* B, float* out);
+Vec2* ssrS_lerpvec2(float t, Vec2* A, Vec2* B, Vec2* out);
+Vec3* ssrS_lerpvec3(float t, Vec3* A, Vec3* B, Vec3* out);
+Vec4* ssrS_lerpvec4(float t, Vec4* A, Vec4* B, Vec4* out);
 
 typedef enum {
 	REGTYPE_NUM = 1,
diff --git a/src/example/03_texture/03_texture.c b/src/example/03_texture/03_texture.c
index c09efe0..b390825 100644
--- a/src/example/03_texture/03_texture.c
+++ b/src/example/03_texture/03_texture.c
@@ -41,16 +41,7 @@ static Texture* cyborg_albedo;
 static Mesh* cyborg_mesh;
 
 void onload_texture(void* data) {
-	//ssr_matrixmode(MATRIX_PROJECTION);
-	//ssr_loadidentity();
-	//ssr_perspective(90, ssr_getaspect(), 0.1, 10);
-	//ssr_ortho(-5, 5, -4, 4, 0.1, 10);
-
-	ssr_bindvertices(verts, 8, cube, 12);
-	ssr_useprogram(&ssr_built_in_shader_pbr);
-	ssr_enable(ENABLE_BACKFACECULL | ENABLE_DEPTHTEST | ENABLE_WRITEDEPTH | ENABLE_BLEND);
-
-	ssr_setblendfunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA);
+	CameraConfig* conf = (CameraConfig*)data; 
 
 	mech_albedo = texture_loadfromfile("res/dieselpunk/mech_basecolor.tga");
 	mech_normal = texture_loadfromfile("res/dieselpunk/mech_normal.tga");
@@ -67,40 +58,30 @@ void onload_texture(void* data) {
 }
 
 void onevent_texture(void* data) {
+	wog_Event* e = (wog_Event*)data;
 }
 
-static float _t = 0;
-static Quat q;
-
 void onupdate_texture(void*data) {
-	uint dt = *(uint*)data;
-	_t += dt / 1000.f;
-
-	//ssr_matrixmode(MATRIX_VIEW);
-	//ssr_loadidentity();
-	//float distance = 2;
-	//Vec3 p = { 0, 0, 10 }, target = { 0, 0, 0 };
-	////Vec3 p = { 0, 0, 700}, target = { 0, 0, 0 };
-	//ssr_lookat(&p, &target, &vec3up);
-
 	ssr_matrixmode(MATRIX_MODEL);
 	ssr_loadidentity();
-	//ssr_translate(0, 0, -700);
-	//ssr_rotate(_t * 10, 0, 1, 0);
 	
 	Vec3 light = {1, 0, 0};
 	ssr_setuniformvec3(0, &light);
 
 	Mat4 world2object;
 	ssr_getm(&world2object);
-	//mat4_invertgeneral3d(&world2object, &world2object);
-	//mat4_transpose(&world2object, &world2object); // transpose it
 
 	ssr_setuniformmat4(0, &world2object);
 }
 
 void ondraw_texture(void*data) {
-	ssr_clearcolor(0);
+	ssr_bindvertices(verts, 8, cube, 12);
+	ssr_useprogram(&ssr_built_in_shader_pbr);
+	ssr_enable(ENABLE_BACKFACECULL | ENABLE_DEPTHTEST | ENABLE_WRITEDEPTH | ENABLE_BLEND);
+
+	ssr_setblendfunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA);
+
+	ssr_clearcolor(0xff202020);
 	ssr_cleardepth();
 	ssr_clearstencil(0);
 /*
@@ -108,6 +89,7 @@ void ondraw_texture(void*data) {
 	ssr_setstencilfunc(STENCILFUNC_ALWAYS, 1, 0xff);
 	ssr_setstencilop(STENCILOP_KEEP, STENCILOP_KEEP, STENCILOP_REPLACE);
 */
+
 	/*render mech*/
 	ssr_setuniformtex(0, mech_albedo);
 	ssr_setuniformtex(1, mech_normal);
@@ -129,8 +111,8 @@ void ondraw_texture(void*data) {
 	ssr_bindvertices(ground_mesh->vertices, ground_mesh->vert_count, ground_mesh->triangles, ground_mesh->tris_count);
 	ssr_draw(PRIMITIVE_TRIANGLE);
 
+	//ssr_setuniformtex(0, cyborg_albedo);
+	//ssr_bindvertices(cyborg_mesh->vertices, cyborg_mesh->vert_count, cyborg_mesh->triangles, cyborg_mesh->tris_count);
+	//ssr_draw(PRIMITIVE_TRIANGLE);
 
-		//ssr_setuniformtex(0, cyborg_albedo);
-		//ssr_bindvertices(cyborg_mesh->vertices, cyborg_mesh->vert_count, cyborg_mesh->triangles, cyborg_mesh->tris_count);
-		//ssr_draw(PRIMITIVE_TRIANGLE);
 }
diff --git a/src/example/example.h b/src/example/example.h
index bcf9ebc..8e2874d 100644
--- a/src/example/example.h
+++ b/src/example/example.h
@@ -3,7 +3,8 @@
 
 #include "../ssr.h"
 #include "../util/type.h"
-//#include "SDL2/SDL.h"
+#include "../extend/camera.h"
+#include "../gizmo/gizmo.h"
 
 #define EXAMPLE(i)\
 extern void onload_##i(void*);\
@@ -11,7 +12,7 @@ extern void onevent_##i(void*);\
 extern void onupdate_##i(void*);\
 extern void ondraw_##i(void*);
 
-#define EXAMPLECUR       texture
+#define CURRENT_EXAMPLE       texture
 
 /*All examples*/
 
diff --git a/src/extend/camera.c b/src/extend/camera.c
index 6426193..6b4c0d1 100644
--- a/src/extend/camera.c
+++ b/src/extend/camera.c
@@ -15,6 +15,8 @@ typedef struct Camera {
 	Vec2 rotate_sensitivity;
 	Vec2 move_sensitivity;
 	Euler euler;
+	bool speedup;
+	float speedupv;
 	/*events*/
 	bool look_around;
 	Vec2 mouse_prev;
@@ -39,12 +41,14 @@ Camera* camera_create(wog_Window* wnd, CameraConfig* config) {
 	cam->aspect = config->aspect;
 	cam->fov = config->fov;
 	cam->zoom_speed = config->zoom_speed;
+	cam->speedup = FALSE;
+	cam->speedupv = 10;
 
 	cam->look_around = FALSE;
 	cam->move_around = FALSE;
 	cam->rotate_sensitivity = config->rotate_sensitivity;
 	cam->move_sensitivity = config->move_sensitivity;
-	cam->euler = cam->euler;
+	cam->euler = config->euler;
 	cam->wnd = wnd;
 
 	return cam;
@@ -84,7 +88,7 @@ static void _onwheelscroll(Camera* cam, int wheel, float dt) {
 	Quat rot; transform_getrotation(&cam->transform, &rot);
 	Vec3 forward = {0,0,-1};
 	quat_applytovec3(&rot, &forward, &forward);
-	vec3_scale(&forward, cam->zoom_speed * wheel * dt, &forward);
+	vec3_scale(&forward, cam->zoom_speed * wheel * dt * (cam->speedup ? cam->speedupv : 1), &forward);
 	vec3_plus(&forward, &cam->transform.localposition, &cam->transform.localposition);
 	cam->is_viewdirty = TRUE;
 }
@@ -96,8 +100,8 @@ static void _onlookaround(Camera* cam,float dt) {
 	int x, y; 
 	wog_getMouse(cam->wnd, &x, &y);
 	float dx = cam->mouse_prev.x - x, dy = y - cam->mouse_prev.y;
-	angle.x = dy * cam->rotate_sensitivity.y * dt;
-	angle.y = dx * cam->rotate_sensitivity.x * dt;
+	angle.x = dy * cam->rotate_sensitivity.y * dt * (cam->speedup ? cam->speedupv : 1);
+	angle.y = dx * cam->rotate_sensitivity.x * dt * (cam->speedup ? cam->speedupv : 1);
 	cam->euler.pitch -= angle.x;
 	cam->euler.yaw += angle.y;
 	//printf("%f    %f\n", cam->euler.pitch, cam->euler.yaw);
@@ -111,8 +115,8 @@ static void _onmovearound(Camera* cam, float dt) {
 	int x, y;
 	wog_getMouse(cam->wnd, &x, &y);
 	Vec3 dd = { cam->mouse_prev.x - x, y - cam->mouse_prev.y , 0};
-	dd.x *= cam->move_sensitivity.x * dt;
-	dd.y *= cam->move_sensitivity.y * dt;
+	dd.x *= cam->move_sensitivity.x * dt * (cam->speedup ? cam->speedupv : 1);
+	dd.y *= cam->move_sensitivity.y * dt * (cam->speedup ? cam->speedupv : 1);
 	quat_applytovec3(&cam->transform.localrotation, &dd, &dd);
 	//printf("%f   %f   %f\n", dd.x, dd.y, dd.z);
 	vec3_plus(&cam->transform.localposition, &dd, &cam->transform.localposition);
@@ -143,6 +147,14 @@ void camera_onevent(Camera* cam, wog_Event* e, float dt) {
 		if (e->button == WOG_MOUSE_MIDDLE)
 			cam->move_around = FALSE;
 	}
+	else if (e->type == WOG_EKEYDOWN) {
+		if (!cam->speedup && e->key == VK_SHIFT)
+			cam->speedup = TRUE;
+	}
+	else if (e->type == WOG_EKEYUP) {
+		if (e->key == VK_SHIFT)
+			cam->speedup = FALSE;
+	}
 }
 
 void camera_onupdate(Camera* cam, float dt) {
diff --git a/src/extend/light.c b/src/extend/light.c
new file mode 100644
index 0000000..e69de29
diff --git a/src/extend/light.h b/src/extend/light.h
new file mode 100644
index 0000000..410dd72
--- /dev/null
+++ b/src/extend/light.h
@@ -0,0 +1,25 @@
+#ifndef _SOFTSHADEROOM_LIGHT_H_
+#define _SOFTSHADEROOM_LIGHT_H_
+
+#include "../math/math.h"
+#include "../core/texture.h"
+#include "transform.h"
+
+typedef enum {
+	LIGHT_POINT, 
+	LIGHT_DIRECTION,
+	LIGHT_SPOT,
+} LightMode;
+
+typedef struct {
+	Transform transform;
+	LightMode mode;
+	Color32 color;
+	float range;
+} Light;
+
+// LUT for lights
+Texture* light_attenuation_tex;
+Texture* light_cookie_tex;
+
+#endif
\ No newline at end of file
diff --git a/src/extend/scene.c b/src/extend/scene.c
new file mode 100644
index 0000000..1723928
--- /dev/null
+++ b/src/extend/scene.c
@@ -0,0 +1,5 @@
+#include "scene.h"
+
+Scene scene;
+
+
diff --git a/src/extend/scene.h b/src/extend/scene.h
new file mode 100644
index 0000000..9c30115
--- /dev/null
+++ b/src/extend/scene.h
@@ -0,0 +1,17 @@
+#ifndef _SOFTSHADEROOM_SCENE_H_
+#define _SOFTSHADEROOM_SCENE_H_
+
+#include "light.h"
+#include "camera.h"
+
+#define LIGHT_LIMIT 4
+
+typedef struct {
+	Camera* main_camera;
+	Light lights[LIGHT_LIMIT]; int light_count;
+} Scene;
+
+// singleton
+extern Scene scene;
+
+#endif
\ No newline at end of file
diff --git a/src/extend/transform.h b/src/extend/transform.h
index cef4344..f9d650c 100644
--- a/src/extend/transform.h
+++ b/src/extend/transform.h
@@ -1,11 +1,11 @@
-#include "../math/math.h"
+#ifndef _SOFTSHADEROOM_TRANSFORM_H_
+#define _SOFTSHADEROOM_TRANSFORM_H_
 
+#include "../math/math.h"
 
 typedef struct Transform Transform;
-/*
-** TransformҪע�ⰴ scale -> rotation -> position ˳�����
-*/
-typedef struct Transform {
+
+struct Transform {
 	/*local*/
 	Vec3 localposition;
 	Vec3 localscale;
@@ -15,7 +15,7 @@ typedef struct Transform {
 	Vec3 cached_position;
 	Vec3 cached_scale;
 	Quat cached_rotation;
-} Transform;
+};
 
 void transform_translate(Transform* trans, Vec3* v);
 
@@ -30,3 +30,5 @@ void transform_setdirty(Transform* trans);
 void transform_getinvmatrixnoscale(Transform* transform, Mat4* worldToLocal); 
 
 void transform_localtoworlddir(Transform* trans, Vec3* dir, Vec3* out);
+
+#endif
\ No newline at end of file
diff --git a/src/extern/wog.c b/src/extern/wog.c
index 04a84c7..0578439 100644
--- a/src/extern/wog.c
+++ b/src/extern/wog.c
@@ -86,7 +86,8 @@ void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e)
         return ;
     }
 
-    case WM_KEYDOWN:
+		case WM_KEYDOWN:
+		case WM_SYSKEYDOWN:
         if ((wParam >= 0) && (wParam <= 255))
         {
             zero_mem(e, sizeof(wog_Event));
@@ -98,6 +99,7 @@ void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e)
         break;
 
     case WM_KEYUP:
+		case WM_SYSKEYUP:
         if ((wParam >= 0) && (wParam <= 255))
         {
             zero_mem(e, sizeof(wog_Event));
diff --git a/src/extern/wog.h b/src/extern/wog.h
index 0b2540e..35bd51d 100644
--- a/src/extern/wog.h
+++ b/src/extern/wog.h
@@ -55,6 +55,78 @@ typedef struct wog_Event
     //};
 }wog_Event;
 
+//*		VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
+ //*	0x40 : unassigned
+ //*	VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
+
+//���������ַ�0~9
+#define   VK_0         0x30 
+#define   VK_1         0x31 
+#define   VK_2         0x32 
+#define   VK_3         0x33 
+#define   VK_4         0x34 
+#define   VK_5         0x35 
+#define   VK_6         0x36 
+#define   VK_7         0x37 
+#define   VK_8         0x38 
+#define   VK_9         0x39
+
+//���������ַ�A~Z
+#define   VK_A	0x41 
+#define   VK_B	0x42 
+#define   VK_C	0x43 
+#define   VK_D	0x44 
+#define   VK_E	0x45 
+#define   VK_F	0x46 
+#define   VK_G	0x47 
+#define   VK_H	0x48 
+#define   VK_I	0x49 
+#define   VK_J	0x4A 
+#define   VK_K	0x4B 
+#define   VK_L	0x4C 
+#define   VK_M	0x4D 
+#define   VK_N	0x4E 
+#define   VK_O	0x4F 
+#define   VK_P	0x50 
+#define   VK_Q	0x51 
+#define   VK_R	0x52 
+#define   VK_S	0x53 
+#define   VK_T	0x54 
+#define   VK_U	0x55 
+#define   VK_V	0x56 
+#define   VK_W	0x57 
+#define   VK_X	0x58 
+#define   VK_Y	0x59 
+#define   VK_Z	0x5A 
+
+//���������ַ�a~z
+#define   VK_a	0x61 
+#define   VK_b	0x62 
+#define   VK_c	0x63 
+#define   VK_d	0x64 
+#define   VK_e	0x65 
+#define   VK_f	0x66 
+#define   VK_g	0x67 
+#define   VK_h	0x68 
+#define   VK_i	0x69 
+#define   VK_j	0x6A 
+#define   VK_k	0x6B 
+#define   VK_l	0x6C 
+#define   VK_m	0x6D 
+#define   VK_n	0x6E 
+#define   VK_o	0x6F 
+#define   VK_p	0x70 
+#define   VK_q	0x71 
+#define   VK_r	0x72 
+#define   VK_s	0x73 
+#define   VK_t	0x74 
+#define   VK_u	0x75 
+#define   VK_v	0x76 
+#define   VK_w	0x77 
+#define   VK_x	0x78 
+#define   VK_y	0x79 
+#define   VK_z	0x7A 
+
 typedef struct {
 	int width, height, channels;
 	unsigned char* buffer;
diff --git a/src/gizmo/gizmo.c b/src/gizmo/gizmo.c
new file mode 100644
index 0000000..e3eaaf1
--- /dev/null
+++ b/src/gizmo/gizmo.c
@@ -0,0 +1,83 @@
+#include "gizmo.h"
+#include "../core/device.h"
+#include "../math/math.h"
+#include "../shaders/common.h"
+
+struct {
+	bool show_grid, g_pressing;
+} gizmo_state;
+
+void gizmo_init() {
+	gizmo_state.show_grid = FALSE;
+	gizmo_state.g_pressing = FALSE;
+}
+
+void gizmo_onevent(wog_Event* e, float dt) {
+	if (e == NULL) return;
+	if (e->type == WOG_EKEYDOWN) {
+		if (e->key == VK_G && !gizmo_state.g_pressing) {
+			gizmo_state.show_grid = !gizmo_state.show_grid;
+			gizmo_state.g_pressing = TRUE;
+		}
+	}
+	else if (e->type == WOG_EKEYUP) {
+		if(e->key == VK_G)
+			gizmo_state.g_pressing = FALSE;
+	}
+}
+
+void gizmo_onupdate(float dt) {
+}
+
+void gizmo_ondraw() {
+	if (gizmo_state.show_grid)
+		gizmo_grid();
+}
+
+// varying
+#define _color reg_v4_00
+static void vert(UniformCollection* uniforms, VertexShaderIn* in, Vec4* clipcoord) {
+	static Vec4 p; p.xyz = in->vertex->position; p.w = 1;
+	object2clip(&p, clipcoord);
+	color_tocolor32(in->vertex->color, _color);
+}
+static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color32* color) {
+	*color = *_color;
+	return 1;
+}
+static Program line_shader = {
+	vert, frag,
+	VARYING_V4_00
+};
+
+void gizmo_grid() {
+	Vert verts[] = {
+		{0, {-10000, 0, 0}, vec3zero, vec4zero, vec2zero, 0xffff0000},
+		{1, {10000, 0, 0}, vec3zero, vec4zero, vec2zero, 0xffff0000},
+		{2, {0, -10000, 0}, vec3zero, vec4zero, vec2zero, 0xff00ff00},
+		{3, {0, 10000, 0}, vec3zero, vec4zero, vec2zero, 0xff00ff00},
+		{4, {0, 0, -10000}, vec3zero, vec4zero, vec2zero, 0xff0000ff},
+		{5, {0, 0, 10000}, vec3zero, vec4zero, vec2zero, 0xff0000ff},
+	};
+	int grid[] = { 0, 1, 2, 3, 4, 5 };
+	ssr_bindvertices(&verts, 6, &grid, 3);
+	ssr_matrixmode(MATRIX_MODEL);
+	ssr_loadidentity();
+	ssr_useprogram(&line_shader);
+	ssr_draw(PRIMITIVE_LINE);
+	ssr_unuseprogram();
+}
+
+void gizmo_line(Vec3 start, Vec3 end, Color32 color) {
+	Vert verts[] = {
+		{0, start, vec3zero, vec4zero, vec2zero, color32_tocolor(&color)},
+		{1, end, vec3zero, vec4zero, vec2zero, color32_tocolor(&color)},
+	};
+	int line[] = { 0, 1};
+	ssr_bindvertices(&verts, 2, &line, 1);
+	ssr_matrixmode(MATRIX_MODEL);
+	ssr_loadidentity();
+	ssr_useprogram(&line_shader);
+	ssr_draw(PRIMITIVE_LINE);
+	ssr_unuseprogram();
+}
diff --git a/src/gizmo/gizmo.h b/src/gizmo/gizmo.h
index 9e416d0..e95880b 100644
--- a/src/gizmo/gizmo.h
+++ b/src/gizmo/gizmo.h
@@ -1,7 +1,9 @@
 #ifndef _SOFTSHADEROOM_GIZMO_H_
 #define _SOFTSHADEROOM_GIZMO_H_
 
+#include "../extern/wog.h"
 #include "../math/math.h"
+#include "../core/vert.h"
 
 /*gizmos for visualizing*/
 
@@ -10,8 +12,16 @@ typedef enum GizmoIcon2d {
 	ICON2D_CAMERA,
 }GizmoIcon2d;
 
-void gizmo_icon2d(float x, float y, float z, GizmoIcon2d icon);
+void gizmo_init();
+
+void gizmo_onevent(wog_Event* e, float dt);
+void gizmo_onupdate(float dt);
+void gizmo_ondraw();
 
+void gizmo_grid();
+
+void gizmo_icon2d(float x, float y, float z, GizmoIcon2d icon);
 
+void gizmo_line(Vec3 start, Vec3 end, Color32 color);
 
 #endif
\ No newline at end of file
diff --git a/src/main.c b/src/main.c
index b0ee5df..4645ad7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -7,10 +7,26 @@
 #include "extern/wog.h"
 #include "shaders/common.h"
 #include "extend/camera.h"
+#include "extend/scene.h"
+
+#define TITLE "Soft Shade Room"
 
 #define SCREEN_WIDTH 600.f
 #define SCREEN_HEIGHT 480.f
 
+static char* instruction = 
+"/*********************************************/\n"
+"/*  SoftShadeRoom                            */\n"
+"/*                                      chai */\n"
+"/*********************************************/\n"
+"Instructions:\n"
+"RightMouseButton+MouseMove:  look around\n"
+"MiddleMouseButton+MouseMove: move around\n"
+"MouseScroll:                 zoom in\\zoom out\n"
+"Shift+Above Operation:       speed up\n"
+"key-g:                       show\\hide grid\n"
+"----------------------------------------------\n";
+
 typedef void(*F)(void*);
 
 F onload;
@@ -18,20 +34,21 @@ F onupdate;
 F onevent;
 F ondraw;
 
-/*https://stackoverflow.com/questions/1489932/how-to-concatenate-twice-with-the-c-preprocessor-and-expand-a-macro-as-in-arg*/
-#define SETEXAMPLEF(f, e) \
+#define SET_EXAMPLE_FUNC(f, e) \
 	f = f##_##e;
 
-#define SETEXAMPLE(i) \
-	SETEXAMPLEF(onload, i)\
-	SETEXAMPLEF(ondraw, i)\
-	SETEXAMPLEF(onevent, i)\
-	SETEXAMPLEF(onupdate, i)
+#define SET_EXAMPLE(i) \
+	SET_EXAMPLE_FUNC(onload, i)\
+	SET_EXAMPLE_FUNC(ondraw, i)\
+	SET_EXAMPLE_FUNC(onevent, i)\
+	SET_EXAMPLE_FUNC(onupdate, i)
 
 int main(int argc, char* argv[]) {
-	wog_Window* wnd = wog_createWindow("Soft Shade Room", SCREEN_WIDTH, SCREEN_HEIGHT, 500, 500, 0);
+	printf(instruction);
+
+	SET_EXAMPLE(CURRENT_EXAMPLE);
+	wog_Window* wnd = wog_createWindow(TITLE, SCREEN_WIDTH, SCREEN_HEIGHT, 500, 500, 0);
 	wog_Surface* surface = wog_getsurface(wnd); // ARGB format
-	Camera* camera;
 	/* init ssr */
 	ssr_Config config = {
 		SCREEN_WIDTH, SCREEN_HEIGHT,
@@ -39,19 +56,24 @@ int main(int argc, char* argv[]) {
 		surface->buffer
 	};
 	ssr_init(&config);
-	SETEXAMPLE(EXAMPLECUR);
 	/*set up global camera*/
-	CameraConfig cam_config = { /*default camera setting*/
-		{0, 0, 800},
+	CameraConfig cam_config = {
+		{0, 10, 800},
 		{0, 0, 0},
-		60, SCREEN_WIDTH / SCREEN_HEIGHT, 0.1, 1500,
+		60, SCREEN_WIDTH / SCREEN_HEIGHT, 0.1, 100000,
 		{5, 5}, {150, 150},
 		4000,
 	};
 	onload(&cam_config);
-	camera = camera_create(wnd, &cam_config);
+	scene.main_camera = camera_create(wnd, &cam_config);
+	gizmo_init();
 	wog_show(wnd);
 
+	_screen_params.x = SCREEN_WIDTH;
+	_screen_params.y = SCREEN_HEIGHT;
+	_screen_params.z = 1 / SCREEN_WIDTH;
+	_screen_params.w = 1 / SCREEN_HEIGHT;
+
 	/* main loop */
 	uint prev = wog_tick();
 	uint dt = 0;
@@ -62,9 +84,15 @@ int main(int argc, char* argv[]) {
 	while (1) {
 		/*handle events*/
 		while (wog_pollEvent(wnd, &e)) {
-			camera_onevent(camera, &e, _dt);
+			camera_onevent(scene.main_camera, &e, _dt);
+			gizmo_onevent(&e, _dt);
 			if (e.type == WOG_ECLOSE) {
 				goto quit;
+			}
+			else if (e.type == WOG_EKEYDOWN) {
+				if (e.key == VK_ESCAPE) {
+					goto quit;
+				}
 			} else {
 				onevent(&e);
 			}
@@ -86,12 +114,14 @@ int main(int argc, char* argv[]) {
 	
 		/*update*/
 		_dt = dt / 1000.f;
-		camera_onupdate(camera, _dt);
+		camera_onupdate(scene.main_camera, _dt);
+		gizmo_onupdate(_dt);
 		onupdate(&_dt);
 		
 		/*draw*/
-		camera_ondraw(camera);
+		camera_ondraw(scene.main_camera);
 		ondraw(NULL);
+		gizmo_ondraw();
 
 		ssr_present();
 		wog_updateSurface(wnd);
@@ -99,7 +129,7 @@ int main(int argc, char* argv[]) {
 	}
 	
 	quit:
-	camera_destroy(camera);
+	camera_destroy(scene.main_camera);
 	wog_destroyWindow(wnd);
 
 	return 0;
diff --git a/src/shaders/common.c b/src/shaders/common.c
index 411c7e4..333b433 100644
--- a/src/shaders/common.c
+++ b/src/shaders/common.c
@@ -2,6 +2,7 @@
 
 Vec4 _proj_params;
 Vec2 _time;
+Vec4 _screen_params;
 
 Vec3 unpacknormal(Color32 c32) {
 	Vec3 normal = {
diff --git a/src/shaders/common.h b/src/shaders/common.h
index 36f80c0..61066e5 100644
--- a/src/shaders/common.h
+++ b/src/shaders/common.h
@@ -35,6 +35,12 @@ Vec4 _proj_params;
 // duration
 Vec2 _time;
 
+// width 
+// height
+// 1 / width 
+// 1 / height
+Vec4 _screen_params;
+
 /************************************************************************/
 /* functions                                                            */
 /************************************************************************/
diff --git a/src/shaders/pbr.c b/src/shaders/pbr.c
index 666f758..9bb051d 100644
--- a/src/shaders/pbr.c
+++ b/src/shaders/pbr.c
@@ -56,7 +56,7 @@ static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color32* col
 	//vec3_scale(&c, roughness, &c);
 	color32_saturate(&c);
 	*color = c;
-	vec3_scale(color, 1 - depth, color);
+	//vec3_scale(color, 1 - depth, color);
 	return 1;
 }
 
-- 
cgit v1.1-26-g67d0