summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-12-08 21:29:29 +0800
committerchai <chaifix@163.com>2019-12-08 21:29:29 +0800
commit69d8af71d6882e801496fcd7ed971081c0b720d8 (patch)
tree452f7d037cf977e4a934d433bd2f12c03ed1ea10
parent31be0df6255ef704bed28d2be56acbe1cea7caad (diff)
*misc
-rw-r--r--src/core/device.c29
-rw-r--r--src/core/device.h10
-rw-r--r--src/core/shader.c6
-rw-r--r--src/core/shader.h12
-rw-r--r--src/core/texture.c78
-rw-r--r--src/core/texture.h14
-rw-r--r--src/core/vert.c16
-rw-r--r--src/core/vert.h6
-rw-r--r--src/example/03_texture.c24
-rw-r--r--src/main.c40
-rw-r--r--src/math/math.h2
-rw-r--r--src/math/vec4.c7
-rw-r--r--src/shaders/unlit.c5
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) {
diff --git a/src/main.c b/src/main.c
index 1dd4663..176c2e6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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
};