diff options
author | chai <chaifix@163.com> | 2020-07-16 01:45:33 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-07-16 01:45:33 +0800 |
commit | efb40cfff1bbbd4f6ff0b0c05788dff6ad45ff02 (patch) | |
tree | 5ec8775ed0c6daa9ae57fe5079c422b220b1eba4 | |
parent | b0235d7a0bac4994da7102887ec0ba1cd613769f (diff) |
*mesh import
-rw-r--r-- | Release/SoftShadeRoom.exe | bin | 128512 -> 133632 bytes | |||
-rw-r--r-- | SoftShadeRoom/SoftShadeRoom.vcxproj | 4 | ||||
-rw-r--r-- | SoftShadeRoom/SoftShadeRoom.vcxproj.filters | 12 | ||||
-rw-r--r-- | src/example/03_texture/03_texture.c | 23 | ||||
-rw-r--r-- | src/extend/camera.c | 1 | ||||
-rw-r--r-- | src/extend/mesh.c | 193 | ||||
-rw-r--r-- | src/gizmo/gizmo.h | 1 | ||||
-rw-r--r-- | src/main.c | 16 | ||||
-rw-r--r-- | src/math/math.h | 2 | ||||
-rw-r--r-- | src/math/vec3.c | 13 |
10 files changed, 165 insertions, 100 deletions
diff --git a/Release/SoftShadeRoom.exe b/Release/SoftShadeRoom.exe Binary files differindex 75efd3d..34fe03d 100644 --- a/Release/SoftShadeRoom.exe +++ b/Release/SoftShadeRoom.exe diff --git a/SoftShadeRoom/SoftShadeRoom.vcxproj b/SoftShadeRoom/SoftShadeRoom.vcxproj index c0808e9..cc89fc2 100644 --- a/SoftShadeRoom/SoftShadeRoom.vcxproj +++ b/SoftShadeRoom/SoftShadeRoom.vcxproj @@ -170,6 +170,7 @@ <ClCompile Include="..\src\extern\wog.c" /> <ClCompile Include="..\src\gizmo\gizmo.c" /> <ClCompile Include="..\src\gizmo\icon2d.c" /> + <ClCompile Include="..\src\gizmo\visualize.c" /> <ClCompile Include="..\src\main.c" /> <ClCompile Include="..\src\math\mat.c" /> <ClCompile Include="..\src\math\math.c" /> @@ -186,6 +187,7 @@ <ClCompile Include="..\src\shaders\unlit.c" /> <ClCompile Include="..\src\test\test_mat4.c" /> <ClCompile Include="..\src\test\test_quat.c" /> + <ClCompile Include="..\src\util\darray.c" /> <ClCompile Include="..\src\util\time.c" /> </ItemGroup> <ItemGroup> @@ -213,6 +215,7 @@ <ClInclude Include="..\src\extern\stb_image.h" /> <ClInclude Include="..\src\extern\wog.h" /> <ClInclude Include="..\src\gizmo\gizmo.h" /> + <ClInclude Include="..\src\gizmo\visualize.h" /> <ClInclude Include="..\src\math\math.h" /> <ClInclude Include="..\src\math\structs.h" /> <ClInclude Include="..\src\settings.h" /> @@ -223,6 +226,7 @@ <ClInclude Include="..\src\ssr.h" /> <ClInclude Include="..\src\test\test.h" /> <ClInclude Include="..\src\util\assert.h" /> + <ClInclude Include="..\src\util\darray.h" /> <ClInclude Include="..\src\util\time.h" /> <ClInclude Include="..\src\util\type.h" /> </ItemGroup> diff --git a/SoftShadeRoom/SoftShadeRoom.vcxproj.filters b/SoftShadeRoom/SoftShadeRoom.vcxproj.filters index 2c33500..0971d5f 100644 --- a/SoftShadeRoom/SoftShadeRoom.vcxproj.filters +++ b/SoftShadeRoom/SoftShadeRoom.vcxproj.filters @@ -178,6 +178,12 @@ <ClCompile Include="..\src\shaders\common\shadow.c"> <Filter>shaders\common</Filter> </ClCompile> + <ClCompile Include="..\src\gizmo\visualize.c"> + <Filter>gizmo</Filter> + </ClCompile> + <ClCompile Include="..\src\util\darray.c"> + <Filter>util</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\src\math\math.h"> @@ -282,5 +288,11 @@ <ClInclude Include="..\src\shaders\common\shadow.h"> <Filter>shaders\common</Filter> </ClInclude> + <ClInclude Include="..\src\gizmo\visualize.h"> + <Filter>gizmo</Filter> + </ClInclude> + <ClInclude Include="..\src\util\darray.h"> + <Filter>util</Filter> + </ClInclude> </ItemGroup> </Project>
\ No newline at end of file diff --git a/src/example/03_texture/03_texture.c b/src/example/03_texture/03_texture.c index bb9a5ba..a7857fa 100644 --- a/src/example/03_texture/03_texture.c +++ b/src/example/03_texture/03_texture.c @@ -40,6 +40,9 @@ static Mesh* yingham_mesh; static Texture* cyborg_albedo; static Mesh* cyborg_mesh; +static Texture* ball_albedo; +static Mesh* ball_mesh; + EXAMPLE void onload_texture(void* data) { CameraConfig* conf = (CameraConfig*)data; @@ -91,26 +94,28 @@ EXAMPLE void ondraw_texture(void*data) { */ /*render mech*/ - ssr_setuniformtex(0, mech_albedo); - ssr_setuniformtex(1, mech_normal); - ssr_setuniformtex(2, mech_roughness); - ssr_setuniformtex(3, mech_metalness); - ssr_bindvertices(mech_mesh->vertices, mech_mesh->vert_count, mech_mesh->triangles, mech_mesh->tris_count); - ssr_draw(PRIMITIVE_TRIANGLE); + //ssr_setuniformtex(0, mech_albedo); + //ssr_setuniformtex(1, mech_normal); + //ssr_setuniformtex(2, mech_roughness); + //ssr_setuniformtex(3, mech_metalness); + //ssr_bindvertices(mech_mesh->vertices, mech_mesh->vert_count, mech_mesh->triangles, mech_mesh->tris_count); + //ssr_draw(PRIMITIVE_TRIANGLE); /* ssr_setstencilfunc(STENCILFUNC_EQUAL, 1, 0xff); ssr_setstencilop(STENCILOP_KEEP, STENCILOP_KEEP, STENCILOP_KEEP); */ /*render yingham*/ - ssr_setuniformtex(0, yingham_albedo); - ssr_bindvertices(yingham_mesh->vertices, yingham_mesh->vert_count, yingham_mesh->triangles, yingham_mesh->tris_count); - ssr_draw(PRIMITIVE_TRIANGLE); +// ssr_setuniformtex(0, yingham_albedo); +// ssr_bindvertices(yingham_mesh->vertices, yingham_mesh->vert_count, yingham_mesh->triangles, yingham_mesh->tris_count); +// ssr_draw(PRIMITIVE_TRIANGLE); /*render ground*/ ssr_setuniformtex(0, ground_albedo); ssr_bindvertices(ground_mesh->vertices, ground_mesh->vert_count, ground_mesh->triangles, ground_mesh->tris_count); ssr_draw(PRIMITIVE_TRIANGLE); + draw_tbn(ground_mesh, VISUAL_ALL, 10); + //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/extend/camera.c b/src/extend/camera.c index 108668a..d148cd8 100644 --- a/src/extend/camera.c +++ b/src/extend/camera.c @@ -129,6 +129,7 @@ static void _onlookaround(Camera* cam,float 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.pitch = clamp(cam->euler.pitch, -90, 90); cam->euler.yaw += angle.y; //printf("%f %f\n", cam->euler.pitch, cam->euler.yaw); internal_quat_fromeuler(&cam->euler, &cam->transform.localrotation); diff --git a/src/extend/mesh.c b/src/extend/mesh.c index 1f393db..e7685e6 100644 --- a/src/extend/mesh.c +++ b/src/extend/mesh.c @@ -1,61 +1,15 @@ #include "mesh.h" +#include "../util/darray.h" +#include "../shaders/common/mathlib.h" #define GENERATE_TANGNET //#define GENERATE_NORMAL //#define OPTIMIZE_MESH - #define LINE_SIZE 1024 -#define darray_push(darray, value) \ - do { \ - (darray) = darray_hold((darray), 1, sizeof(*(darray))); \ - (darray)[darray_size(darray) - 1] = (value); \ - } while (0) - -#define DARRAY_RAW_DATA(darray) ((int*)(darray) - 2) -#define DARRAY_CAPACITY(darray) (DARRAY_RAW_DATA(darray)[0]) -#define DARRAY_OCCUPIED(darray) (DARRAY_RAW_DATA(darray)[1]) - -int darray_size(void *darray) { - return darray != NULL ? DARRAY_OCCUPIED(darray) : 0; -} - -void darray_free(void *darray) { - if (darray != NULL) { - free(DARRAY_RAW_DATA(darray)); - } -} - #define UNUSED_VAR(x) ((void)(x)) - -void *darray_hold(void *darray, int count, int itemsize) { - assert(count > 0 && itemsize > 0); - if (darray == NULL) { - int raw_size = sizeof(int) * 2 + itemsize * count; - int *base = (int*)malloc(raw_size); - base[0] = count; /* capacity */ - base[1] = count; /* occupied */ - return base + 2; - } - else if (DARRAY_OCCUPIED(darray) + count <= DARRAY_CAPACITY(darray)) { - DARRAY_OCCUPIED(darray) += count; - return darray; - } - else { - int needed_size = DARRAY_OCCUPIED(darray) + count; - int double_curr = DARRAY_CAPACITY(darray) * 2; - int capacity = needed_size > double_curr ? needed_size : double_curr; - int occupied = needed_size; - int raw_size = sizeof(int) * 2 + itemsize * capacity; - int *base = (int*)realloc(DARRAY_RAW_DATA(darray), raw_size); - base[0] = capacity; - base[1] = occupied; - return base + 2; - } -} - Vec3 internal_vec3_min(Vec3 a, Vec3 b) { float x = min(a.x, b.x); float y = min(a.y, b.y); @@ -72,6 +26,13 @@ Vec3 internal_vec3_max(Vec3 a, Vec3 b) { return r; } +/************************************************************************/ +/* obj loader */ +/************************************************************************/ + +#define SIMPLE_OBJ_LOADER 0 + +#if SIMPLE_OBJ_LOADER static Mesh *build_mesh( Vec3 *positions, Vec2 *texcoords, Vec3 *normals, Vec4 *tangents, Vec4 *joints, Vec4 *weights, @@ -126,13 +87,6 @@ static Mesh *build_mesh( return mesh; } -/************************************************************************/ -/* obj loader */ -/************************************************************************/ - -#define SIMPLE_OBJ_LOADER 0 - -#if SIMPLE_OBJ_LOADER Mesh* mesh_loadfromobj(const char *filename) { Vec3 *positions = NULL; Vec2 *texcoords = NULL; @@ -215,8 +169,7 @@ Mesh* mesh_loadfromobj(const char *filename) { return mesh; } -#else - +#else // SIMPLE_OBJ_LOADER typedef struct { int normal_index; int uv_index; @@ -235,6 +188,24 @@ typedef struct { FaceVertex vertices[3]; } FaceInfo; +typedef struct { + int vertices[3]; + Vec3 tangent; // tangent of face +} Triangle; + +typedef struct { + Vert props; // position, normal, texcoord etc + int* related_triangles; +} MeshVertexInfo; + +typedef struct { + MeshVertexInfo* vertices; // vertices list + Triangle* triangles; // triangles list +} MeshInfo; + +void calc_face_tanget(MeshInfo* mesh); +void calc_vertex_tangnet(MeshInfo* mesh); + Mesh* mesh_loadfromobj(const char* path) { Vec3* position_list = NULL; Vec3* normal_list = NULL; @@ -297,11 +268,13 @@ Mesh* mesh_loadfromobj(const char* path) { int vert_count = 0; - Mesh temp_mesh = {0}; + //Mesh temp_mesh = {0}; + MeshInfo mesh_info = {0}; for (int i = 0; i < darray_size(face_list); ++i) { FaceInfo* face = &face_list[i]; + Triangle triangle = {0}; for (int j = 0; j < 3; ++j) { FaceVertex face_vert = face->vertices[j]; @@ -311,52 +284,108 @@ Mesh* mesh_loadfromobj(const char* path) { VertexListElement* vertex = &vertex_list[pos_index]; if (vertex->vertices) { - for (int j = 0; j < darray_size(vertex->vertices); ++j) + for (int k = 0; k < darray_size(vertex->vertices); ++k) { - VertexInfo* vert = &vertex->vertices[j]; + VertexInfo* vert = &vertex->vertices[k]; if (vert->normal_index == normal_index && vert->uv_index == uv_index) { - darray_push(temp_mesh.triangles, vert->index); + triangle.vertices[j] = vert->index; + MeshVertexInfo* mesh_vertex_info = &mesh_info.vertices[vert->index]; + darray_push(mesh_vertex_info->related_triangles, i); goto next; } } } - // create seam - VertexInfo new_vert; new_vert.normal_index = normal_index; new_vert.uv_index = uv_index; new_vert.index = vert_count; - darray_push(vertex->vertices, new_vert); - Vert vert; - vert.position = position_list[pos_index]; - vert.normal = normal_list[normal_index]; - vert.texcoord = uv_list[uv_index]; - vert.index = vert_count; - darray_push(temp_mesh.vertices, vert); - - darray_push(temp_mesh.triangles, vert_count); - - ++temp_mesh.vert_count; + MeshVertexInfo vert = {0}; + vert.props.position = position_list[pos_index]; + vert.props.normal = normal_list[normal_index]; + vert.props.texcoord = uv_list[uv_index]; + vert.props.index = vert_count; + darray_push(vert.related_triangles, i); + darray_push(mesh_info.vertices, vert); + triangle.vertices[j] = vert_count; + ++vert_count; - next: continue; + next: + continue; } - - ++temp_mesh.tris_count; + + darray_push(mesh_info.triangles, triangle); } + calc_face_tanget(&mesh_info); + calc_vertex_tangnet(&mesh_info); + Mesh* mesh = malloc(sizeof(Mesh)); - mesh->triangles = temp_mesh.triangles; - mesh->vertices = temp_mesh.vertices; - mesh->tris_count = temp_mesh.tris_count; - mesh->vert_count = temp_mesh.vert_count; + int num_of_face = darray_size(mesh_info.triangles) ; + mesh->triangles = malloc(num_of_face * 3 * sizeof(uint)); + for (int i = 0; i < darray_size(mesh_info.triangles); ++i) { + mesh->triangles[3 * i] = mesh_info.triangles[i].vertices[0]; + mesh->triangles[3 * i + 1] = mesh_info.triangles[i].vertices[1]; + mesh->triangles[3 * i + 2] = mesh_info.triangles[i].vertices[2]; + } + mesh->tris_count = num_of_face; + mesh->vertices = malloc(sizeof(Vert) * darray_size(mesh_info.vertices)); + for (int i = 0; i < darray_size(mesh_info.vertices); ++i) { + mesh->vertices[i] = mesh_info.vertices[i].props; + } + mesh->vert_count = darray_size(mesh_info.vertices); return mesh; } -#endif
\ No newline at end of file +void calc_face_tanget(MeshInfo* mesh) { + MeshVertexInfo* vertices = mesh->vertices; + Triangle* faces = mesh->triangles; + for (int i = 0; i < darray_size(faces); ++i) { + Triangle* face = &faces[i]; + int v0 = face->vertices[0]; + int v1 = face->vertices[1]; + int v2 = face->vertices[2]; + // delta uv + Vec2 duv1 = vec2_minus(vertices[v1].props.texcoord, vertices[v0].props.texcoord); + Vec2 duv2 = vec2_minus(vertices[v2].props.texcoord, vertices[v0].props.texcoord); + // edge + Vec3 dp1 = vec3_minus(vertices[v1].props.position, vertices[v0].props.position); + Vec3 dp2 = vec3_minus(vertices[v2].props.position, vertices[v0].props.position); + float f = 1.0f / (duv1.x * duv2.y - duv2.x * duv1.y); + face->tangent.x = f * (duv2.y * dp1.x - duv1.y * dp2.x); + face->tangent.y = f * (duv2.y * dp1.y - duv1.y * dp2.y); + face->tangent.z = f * (duv2.y * dp1.z - duv1.y * dp2.z); + face->tangent = vec3_normalize(face->tangent); + } + // 平均化三角形切线 +} + +void calc_vertex_tangnet(MeshInfo* mesh) { + MeshVertexInfo* vertices = mesh->vertices; + Triangle* faces = mesh->triangles; + for (int i = 0; i < darray_size(vertices); ++i) { + MeshVertexInfo* vert = &vertices[i]; + Vec3 tangent = vec3(0,0,0); + Vec3 bitangent = vec3(0,0,0); + int face_count = darray_size(vert->related_triangles); + for (int j = 0; j < face_count; ++j) { + int face_index = vert->related_triangles[j]; + Triangle* face = &faces[face_index]; + tangent = vec3_plus(tangent, face->tangent); + } + tangent = vec3_normalize(tangent); + vert->props.tangent = vec4(tangent.x, tangent.y, tangent.z, 1); + // orthogonalize + bitangent = vec3_normalize(vec3_cross(vert->props.normal, tangent)); + internal_vec3_orthogonalize( + &tangent, &bitangent, &vert->props.normal, &tangent, &bitangent, &vert->props.normal); + } +} + +#endif // SIMPLE_OBJ_LOADER
\ No newline at end of file diff --git a/src/gizmo/gizmo.h b/src/gizmo/gizmo.h index 066099d..aba40b5 100644 --- a/src/gizmo/gizmo.h +++ b/src/gizmo/gizmo.h @@ -4,6 +4,7 @@ #include "../extern/wog.h" #include "../math/math.h" #include "../core/vert.h" +#include "visualize.h" /*gizmos for visualizing*/ @@ -35,16 +35,14 @@ static char* instruction = "Options: \n" " -b <image> set baking target image\n" "Examples: \n" -" \n" -"-------------------------------------------------\n"; +" \n"; -typedef void(*F)(void*); +typedef void(*Callback)(void*); -// Example entry -F onload; -F onupdate; -F onevent; -F ondraw; +Callback onload; +Callback onupdate; +Callback onevent; +Callback ondraw; bool setup(const char* name) { HMODULE module = GetModuleHandle(NULL); @@ -52,7 +50,7 @@ bool setup(const char* name) { #define _setup(p)\ memset(func, 0, sizeof(func)); \ sprintf(func, "%s_%s", #p, name); \ - p = (F)GetProcAddress(module, func); + p = (Callback)GetProcAddress(module, func); _setup(onload); _setup(onupdate); _setup(onevent); diff --git a/src/math/math.h b/src/math/math.h index 8fa748b..b520f9e 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -81,6 +81,8 @@ float internal_vec3_magnitude2(Vec3* v1); void internal_vec3_lerp(Vec3* v1, Vec3* v2, float t, Vec3* out); void internal_vec3_slerp(Vec3* v1, Vec3* v2, float t, Vec3* out); +void internal_vec3_orthogonalize(Vec3* x, Vec3* y, Vec3* z, Vec3* out_x, Vec3* out_y, Vec3* out_z); // 以z为基准进行正交化 + void internal_vec4_dividew(Vec4* v, Vec3* out); void internal_vec4_dividewnoz(Vec4* v, Vec4* out); diff --git a/src/math/vec3.c b/src/math/vec3.c index e9c12a4..43154dc 100644 --- a/src/math/vec3.c +++ b/src/math/vec3.c @@ -4,6 +4,8 @@ #include "../util/assert.h" #include "../core/mem.h" +#include "../shaders/common/mathlib.h" + Vec3 vec3forward = {0,0,1}; Vec3 vec3up = {0, 1, 0}; Vec3 vec3left = {1, 0, 0}; @@ -134,4 +136,15 @@ void internal_vec3_minus(Vec3* v1, Vec3* v2, Vec3* out) { out->x = v1->x - v2->x; out->y = v1->y - v2->y; out->z = v1->z - v2->z; +} + +// x tangent +// y bitangent +// z normal +void internal_vec3_orthogonalize(Vec3* x, Vec3* y, Vec3* z, Vec3* out_x, Vec3* out_y, Vec3* out_z) { + *out_z = *z; + *out_x = vec3_minus(*x, vec3_scale(*z, vec3_dot(*z, *x))); + Vec3 v1 = vec3_scale(*z, vec3_dot(*z, *y)); + Vec3 v2 = vec3_scale(*out_x, vec3_dot(*out_x, *y)); + *out_y = vec3_minus(*y, vec3_plus(v1, v2)); }
\ No newline at end of file |