diff options
-rw-r--r-- | src/core/device.c | 29 | ||||
-rw-r--r-- | src/core/device.h | 10 | ||||
-rw-r--r-- | src/core/shader.c | 6 | ||||
-rw-r--r-- | src/core/shader.h | 12 | ||||
-rw-r--r-- | src/core/texture.c | 78 | ||||
-rw-r--r-- | src/core/texture.h | 14 | ||||
-rw-r--r-- | src/core/vert.c | 16 | ||||
-rw-r--r-- | src/core/vert.h | 6 | ||||
-rw-r--r-- | src/example/03_texture.c | 24 | ||||
-rw-r--r-- | src/main.c | 40 | ||||
-rw-r--r-- | src/math/math.h | 2 | ||||
-rw-r--r-- | src/math/vec4.c | 7 | ||||
-rw-r--r-- | src/shaders/unlit.c | 5 |
13 files changed, 188 insertions, 61 deletions
diff --git a/src/core/device.c b/src/core/device.c index 9e4a6eb..cf9fee2 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -43,6 +43,10 @@ struct { Program* program; UniformCollection uniforms; + /*texture relavent*/ + FilterMode filtermode; + WrapMode wrapmode; + uint enable; } state; @@ -73,6 +77,9 @@ void ssr_init(ssr_Config* conf) { state.buffersize = sizeof(Color) * config.width * config.height; state.zbuffer = ssrM_newvector(uint, config.width * config.height); memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height); + + state.filtermode = FILTERMODE_POINT; + state.wrapmode = WRAPMODE_CLAMP; } float ssr_getaspect() { @@ -87,6 +94,22 @@ int ssr_getframebufferh() { return config.height; } +void ssr_setfiltermode(FilterMode filter_mode) { + state.filtermode = filter_mode; +} + +void ssr_setwrapmode(WrapMode wrap_mode) { + state.wrapmode = wrap_mode; +} + +FilterMode ssr_getfiltermode() { + return state.filtermode; +} + +WrapMode ssr_getwrapmode() { + return state.wrapmode; +} + void ssr_matrixmode(ssr_MatrixMode mode) { state.matrixmode = mode; } @@ -410,3 +433,9 @@ void ssr_setuniformvec2(uint idx, Vec2* src) { if (idx < 0 || idx > 7) return; state.uniforms.var_vec2[idx] = *src; } + +void ssr_setuniformtex(uint idx, Texture* tex) { + ssr_assert(tex); + if (idx < 0 || idx > 11) return; + state.uniforms.var_tex[idx] = tex; +} diff --git a/src/core/device.h b/src/core/device.h index 5cf9c4a..b265471 100644 --- a/src/core/device.h +++ b/src/core/device.h @@ -39,6 +39,9 @@ float ssr_getaspect(); int ssr_getframebufferw(); int ssr_getframebufferh(); +void ssr_setfiltermode(FilterMode filter_mode); +void ssr_setwrapmode(WrapMode wrap_mode); + void ssr_matrixmode(ssr_MatrixMode mode); void ssr_loadidentity(); void ssr_pushmatrix(); @@ -76,6 +79,7 @@ void ssr_setuniformmat4(uint idx, Mat4* src); void ssr_setuniformvec4(uint idx, Vec4* src); void ssr_setuniformvec3(uint idx, Vec3* src); void ssr_setuniformvec2(uint idx, Vec2* src); +void ssr_setuniformtex(uint idx, Texture* tex); void ssr_draw(ssr_PrimitiveType primitive); void ssr_clearcolor(Color color); @@ -92,9 +96,9 @@ Color ssr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char bool ssr_testdepth(uint x, uint y, uint depth); /*尝试写入深度,如果可绘制返回true,否则discard*/ bool ssr_testdepthf(uint x, uint y, float depth01); -/* -** Utils -*/ void ssrU_viewport(Vec2* p, Vec2* out); +FilterMode ssr_getfiltermode(); +WrapMode ssr_getwrapmode(); + #endif
\ No newline at end of file diff --git a/src/core/shader.c b/src/core/shader.c index 89daa36..a508820 100644 --- a/src/core/shader.c +++ b/src/core/shader.c @@ -215,6 +215,12 @@ void ssrS_setregtofragin(uint extra_varying_flag, FragmentShaderIn* frag_in){ } } +Color32 texture2d(Texture* tex, Vec2* uv) { + FilterMode filter_mode = ssr_getfiltermode(); + WrapMode wrap_mode = ssr_getwrapmode(); + return texture_sampling(tex, filter_mode, wrap_mode, uv->x, uv->y); +} + float* ssrS_bcpnum(Vec3* bc, float A, float B, float C, float* out) { ssr_assert(bc && out); *out = bc->A * A + bc->B * B + bc->C * C; diff --git a/src/core/shader.h b/src/core/shader.h index f663a47..bc4e04c 100644 --- a/src/core/shader.h +++ b/src/core/shader.h @@ -23,7 +23,7 @@ typedef struct UniformCollection { void* userdata; } UniformCollection; -#define TEX(i) (&uniforms->var_tex[i]) +#define TEX(i) (uniforms->var_tex[i]) #define UM4(i) (&uniforms->var_mat4[i]) #define UV2(i) (&uniforms->var_vec2[i]) #define UV3(i) (&uniforms->var_vec3[i]) @@ -157,8 +157,6 @@ Register reg_v2[6]; Register reg_v3[8]; Register reg_v4[6]; -void reg_all_wipe(); /*标记清空所有寄存器*/ - /*寄存器指针,使用错误可能会出现野指针*/ float* reg_num_00; @@ -189,16 +187,12 @@ Vec4* reg_v4_03; Vec4* reg_v4_04; Vec4* reg_v4_05; -/*设置寄存器指针,指向寄存器(注意在fragment阶段,指针会指向fragmentIn结构)*/ +/*设置寄存器指针,指向寄存器(在fragment阶段,指针会指向fragmentIn结构)*/ void ssrS_setupregisterpoints(uint extra_varying_flag, int idx); /*设置寄存器指针,指向fragIn结构*/ void ssrS_setregtofragin(uint extra_varying_flag, FragmentShaderIn* frag_in); - -/* -** texture -*/ -Color32 texture2d(float x, float y); +Color32 texture2d(Texture* tex, Vec2* uv); #endif
\ No newline at end of file diff --git a/src/core/texture.c b/src/core/texture.c index 7104bfb..1b70e4b 100644 --- a/src/core/texture.c +++ b/src/core/texture.c @@ -1,3 +1,81 @@ #include "texture.h" +#define STB_IMAGE_IMPLEMENTATION +#include "../lib/stb_image.h" +#include <stdio.h> +static void texture_abgr2argb(Texture* tex) { + ssr_assert(tex); + int width = tex->width, height = tex->height; + Color* pixels = tex->pixels; + for (int i = 0; i < width * height; ++i) { + uint r = (pixels[i] & 0xff) << 16; + uint g = ((pixels[i] >> 8) & 0xff) << 8; + uint b = ((pixels[i] >> 16) & 0xff); + uint a = ((pixels[i] >> 24) & 0xff) << 24; + pixels[i] = r | g | b | a; + } +} +Texture* texture_loadfromfile(const char* path) { + ssr_assert(path); + FILE* file = fopen(path, "rb"); + ssr_assert(file); + fseek(file, 0, SEEK_END); + int size = ftell(file); + fseek(file, 0, SEEK_SET); + char* buffer = ssrM_newvector(char, size); + ssr_assert(buffer); + int l = fread(buffer, 1, size, file); + if ( l!= size) { + free(buffer); + fclose(file); + return NULL; + } + fclose(file); + int width, height; + Color* pixels = (Color*)stbi_load_from_memory((unsigned char*)buffer, size, &width, &height, NULL, STBI_rgb_alpha); + ssrM_free(buffer); + if (!pixels) return NULL; + Texture* texture = ssrM_new(Texture); + texture->width = width; texture->height = height; + texture->pixels = pixels; + texture_abgr2argb(texture); + return texture; +} + +static Color32 sampling(Texture* tex, WrapMode wrap_mode, int x, int y) { + Color32 color; + if (wrap_mode == WRAPMODE_CLAMP) { /*clamp*/ + x = clamp(x, 0, tex->width - 1); + y = clamp(y, 0, tex->height - 1); + } else { /*repeat*/ + x = x % tex->width; + y = y % tex->height; + } + color_tocolor32(tex->pixels[x + y * tex->width], &color); + return color; +} + +Color32 texture_sampling(Texture* tex, FilterMode filter_mode, WrapMode wrap_mode, float x01, float y01) { + ssr_assert(tex); + int x = x01 * tex->width, y = (1 - y01) * tex->height; /*map to texture coordinate*/ + if (filter_mode == FILTERMODE_POINT) { + return sampling(tex, wrap_mode, x, y); + } + else if (filter_mode == FILTERMODE_BILINEAR) { + int x_min = floor(x), y_min = floor(y); + int x_max = ceil(x), y_max = ceil(y); + static Color32 tl, tr, bl, br, t, b, out; + tl = sampling(tex, wrap_mode, x_min, y_min); + tr = sampling(tex, wrap_mode, x_max, y_min); + bl = sampling(tex, wrap_mode, x_min, y_max); + br = sampling(tex, wrap_mode, x_max, y_max); + vec4_lerp(&tl, &tr, x - x_min, &t); + vec4_lerp(&bl, &br, x - x_min, &b); + vec4_lerp(&t, &b, y - y_min, &out); + return out; + } + else if (filter_mode == FILTERMODE_TRILINEAR) { + /*TODO*/ + } +} diff --git a/src/core/texture.h b/src/core/texture.h index 20a0228..49fed4b 100644 --- a/src/core/texture.h +++ b/src/core/texture.h @@ -3,13 +3,6 @@ #include "vert.h" -typedef struct Texture{ - uint width, height; - Color* pixels; -}Texture; - -void texture_loadfromfile(const char* path, Texture* out); - typedef enum FilterMode { FILTERMODE_POINT, FILTERMODE_BILINEAR, @@ -21,6 +14,13 @@ typedef enum WrapMode{ WRAPMODE_CLAMP, } WrapMode; +typedef struct Texture{ + uint width, height; + Color* pixels; +}Texture; + +Texture* texture_loadfromfile(const char* path); + Color32 texture_sampling(Texture* tex, FilterMode filter_mode, WrapMode wrap_mode, float x, float y); #endif
\ No newline at end of file diff --git a/src/core/vert.c b/src/core/vert.c deleted file mode 100644 index 95469d3..0000000 --- a/src/core/vert.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "vert.h" - -Vert* vert_new() { - Vert* vert = ssrM_new(Vert); - return vert; -} - -void vert_init(Vert* v) { - ssr_assert(v); - v->index = 0; -} - -void vert_free(Vert* v) { - ssr_assert(v); - ssrM_free(v); -}
\ No newline at end of file diff --git a/src/core/vert.h b/src/core/vert.h index 0542ded..a85e38c 100644 --- a/src/core/vert.h +++ b/src/core/vert.h @@ -22,7 +22,7 @@ void color32_saturate(Color32* c); /*readonly*/ typedef struct Vert { - int index; + uint index; Vec3 position; Vec3 normal; Vec3 tangent; @@ -32,8 +32,4 @@ typedef struct Vert { Vec4 weight; } Vert; -Vert* vert_new(uint comp); -void vert_init(Vert* v, uint comp); -void vert_free(Vert* v); - #endif
\ No newline at end of file diff --git a/src/example/03_texture.c b/src/example/03_texture.c index acb85c4..d4e08a4 100644 --- a/src/example/03_texture.c +++ b/src/example/03_texture.c @@ -10,20 +10,22 @@ static int cube[] = { }; static Vert verts[] = { - {0, {1, 1, 1}, {1, 1, 1}, zerovec3, zerovec2, 0xffff0000}, - {1, {-1, 1, 1}, {-1, 1, 1}, zerovec3, zerovec2,0xff00ff00}, - {2, {-1, -1, 1}, {-1, -1, 1}, zerovec3, zerovec2, 0xff0000ff}, - {3, {1, -1, 1}, {1, -1, 1}, zerovec3, zerovec2, 0xffff00ff}, - {4, {1, 1, -1}, {1, 1, -1}, zerovec3, zerovec2, 0xffaa28aa}, - {5, {-1, 1, -1}, {-1, 1, -1}, zerovec3, zerovec2,0xffFFC58E}, - {6, {-1, -1, -1}, {-1, -1, -1}, zerovec3, zerovec2, 0xffA100FF}, - {7, {1, -1, -1}, {1, -1, -1}, zerovec3, zerovec2, 0xffFAFF00}, + {0, {1, 1, 1}, {1, 1, 1}, zerovec3, {1, 1}, 0xffff0000}, + {1, {-1, 1, 1}, {-1, 1, 1}, zerovec3, {0, 1},0xff00ff00}, + {2, {-1, -1, 1}, {-1, -1, 1}, zerovec3, {0, 0}, 0xff0000ff}, + {3, {1, -1, 1}, {1, -1, 1}, zerovec3, {1, 0}, 0xffff00ff}, + {4, {1, 1, -1}, {1, 1, -1}, zerovec3, {1, 0} , 0xffaa28aa}, + {5, {-1, 1, -1}, {-1, 1, -1}, zerovec3, {0, 0},0xffFFC58E}, + {6, {-1, -1, -1}, {-1, -1, -1}, zerovec3, {0, 1}, 0xffA100FF}, + {7, {1, -1, -1}, {1, -1, -1}, zerovec3, {1, 1} , 0xffFAFF00}, }; extern Program ssr_built_in_shader_unlit; static Vec3 light = {-1, -1, -1}; +static Texture* texture; + void onloadtexture(void* data) { ssr_matrixmode(MATRIX_PROJECTION); ssr_loadidentity(); @@ -38,6 +40,12 @@ void onloadtexture(void* data) { ssr_useprogram(&ssr_built_in_shader_unlit); ssr_enable(ENABLEMASK_BACKFACECULL); ssr_enable(ENABLEMASK_DEPTHTEST); + + texture = texture_loadfromfile("res/helmet/screenshot2.png"); + ssr_setuniformtex(0, texture); + + ssr_setwrapmode(WRAPMODE_CLAMP); + ssr_setfiltermode(FILTERMODE_POINT); } void oneventtexture(void* data) { @@ -8,8 +8,8 @@ SDL_Surface* suf; -#define SCREEN_WIDTH 600 /*800*/ -#define SCREEN_HEIGHT 500 /*600*/ +#define SCREEN_WIDTH 600/*800*/ +#define SCREEN_HEIGHT 480/*600*/ typedef void(*F)(void*); F onload; @@ -30,7 +30,7 @@ SETEXAMPLEF(onupdate, i) int main(int argc, char* argv[]) { - if (SDL_Init(SDL_INIT_EVERYTHING) < 0) + if (SDL_Init(SDL_INIT_EVENTS | SDL_INIT_TIMER | SDL_INIT_VIDEO) < 0) return 1; SDL_Window* wnd = SDL_CreateWindow("Soft Shade Room", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); SDL_Event e; @@ -40,18 +40,24 @@ int main(int argc, char* argv[]) ssr_assert(suf->format->Rshift == 16); ssr_assert(suf->format->Gshift == 8); ssr_assert(suf->format->Bshift == 0); + /* init ssr */ ssr_Config config = { - SCREEN_WIDTH, SCREEN_HEIGHT,/* screen size */ - 0, /* double buffer */ - suf->pixels /* screen buffer */ + SCREEN_WIDTH, SCREEN_HEIGHT, + 0, + suf->pixels }; ssr_init(&config); + SETEXAMPLE(EXAMPLECUR); + onload(0); + /* main loop */ - uint previous = SDL_GetTicks(); + uint prev = SDL_GetTicks(); uint dt = 0; + uint frame_count = 0; + uint time_stamp = 0; while (1) { while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { @@ -60,15 +66,27 @@ int main(int argc, char* argv[]) onevent(&e); } } - dt = SDL_GetTicks() - previous; - previous = dt + previous; + + dt = SDL_GetTicks() - prev; + prev += dt; + time_stamp += dt; + ++frame_count; + if (time_stamp >= 1000) { + printf("%3d fps\n", frame_count); + time_stamp -= 1000; + frame_count = 0; + } + onupdate(&dt); ondraw(0); ssr_present(); SDL_UpdateWindowSurface(wnd); - Sleep(10); /*100fps limit*/ + + Sleep(1); /*reduce cpu usage*/ } - quit: + +quit: SDL_Quit(); + return 0; } diff --git a/src/math/math.h b/src/math/math.h index 35219a3..1db7df7 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -182,6 +182,8 @@ void vec4_dividew(Vec4* v, Vec3* out); void vec4_tostring(Vec4* v, char buf[]); void vec4_print(Vec4* v); +void vec4_lerp(Vec4* a, Vec4* b, float t, Vec4* out); + /************************************************************************/ /* Matrix */ /************************************************************************/ diff --git a/src/math/vec4.c b/src/math/vec4.c index ca64820..b79adca 100644 --- a/src/math/vec4.c +++ b/src/math/vec4.c @@ -21,4 +21,11 @@ void vec4_tostring(Vec4* v, char buf[]) { void vec4_print(Vec4* v) { vec4_tostring(v, printbuffer); printf("\n%s\n", printbuffer); +} + +void vec4_lerp(Vec4* a, Vec4* b, float t, 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); }
\ No newline at end of file diff --git a/src/shaders/unlit.c b/src/shaders/unlit.c index 7ff4497..fe692f0 100644 --- a/src/shaders/unlit.c +++ b/src/shaders/unlit.c @@ -17,11 +17,12 @@ static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color* color float strongness = vec3_dot(light, &in->normal); vec3_scale(vert_color, 1 - clamp(strongness, 0, 1), vert_color); *color = color32_tocolor(vert_color); - + //Color32 c = texture2d(maintex, &in->texcoord); + //*color = color32_tocolor(&c); return 1; } Program ssr_built_in_shader_unlit = { vert, frag, - VARYING_V4_00 + VARYING_V4_00 | VARYING_TEXCOORD }; |