diff --git a/assets/shaders/blinn_phong.frag.orig b/assets/shaders/blinn_phong.frag.orig deleted file mode 100755 index f4bf122..0000000 --- a/assets/shaders/blinn_phong.frag.orig +++ /dev/null @@ -1,130 +0,0 @@ -//include fog.glsl common.glsl commonFrag.glsl version.glsl - -struct Light -{ - vec3 position; - vec3 direction; - float outer_angle; - float inner_angle; - float falloff; - float intensity; - vec3 color; - uint pcf_enabled; - int type; - int radius; - float depth_bias; -}; - -const int LT_SPOT = 0; -const int LT_DIR = 1; -const int LT_POINT = 2; - -const int MAX_LIGHTS = 128; - -uniform sampler2D diffuse_texture; -uniform Light lights[MAX_LIGHTS]; -uniform int total_active_lights; - -uniform float specular; -uniform float diffuse; -uniform float specular_strength; -out vec4 frag_color; - -vec3 calc_point_light(in Light light) -{ - vec3 diffuse_comp = vec3(0.0); - vec3 specular_comp = vec3(0.0); - vec3 light_direction = vertex - light.position; - float dist = abs(length(light_direction)); - if(dist <= light.radius) - { - light_direction = normalize(light_direction); - vec3 normalized_normal = normalize(normal); - float cos_ang_incidence = dot(normalized_normal, -light_direction); - cos_ang_incidence = clamp(cos_ang_incidence, 0, 1); - - if(cos_ang_incidence > 0) - { - diffuse_comp = light.color * diffuse * cos_ang_incidence; - vec3 vertex_to_eye = normalize(camera_pos - vertex); - vec3 halfway = normalize(light.direction + vertex_to_eye); - float specular_factor = max(0.0, dot(normalized_normal, halfway)); - specular_factor = pow(specular_factor, specular_strength); - specular_comp = light.color * specular * specular_factor; - } - float attenuation = pow(max(0.0, (1.0 - (dist / light.radius))), light.falloff + 1.0f); - return (((diffuse_comp + specular_comp) * attenuation) * light.intensity); - } - else - { - return vec3(0.0); - } -} - -vec3 calc_dir_light(in Light light) -{ - vec3 diffuse_comp = vec3(0.0); - vec3 specular_comp = vec3(0.0); - vec3 normalized_normal = normalize(normal); - float cos_ang_incidence = dot(normalized_normal, -light.direction); - cos_ang_incidence = clamp(cos_ang_incidence, 0, 1); - float shadow_factor = 1.0; - - if(cos_ang_incidence > 0) - { - diffuse_comp = light.color * diffuse * cos_ang_incidence; - - vec3 vertex_to_eye = normalize(camera_pos - vertex); - vec3 light_reflect = normalize(reflect(light.direction, normalized_normal)); - vec3 halfway = normalize(light.direction + vertex_to_eye); - float specular_factor = max(0.0, dot(normalized_normal, halfway)); - specular_factor = pow(specular_factor, specular_strength); - specular_comp = light.color * specular * specular_factor; - // if(light.castShadow == 1) - // { - // shadow_factor = calcShadowFactor(vertLightSpace.xyz); - // } - } - //return (light.intensity * (diffuse_comp + specular_comp)) * shadow_factor; - return (light.intensity * (diffuse_comp + specular_comp)); -} - -vec3 calc_spot_light(in Light light) -{ - vec3 color = vec3(0.0); - vec3 light_to_surface = vertex - light.position; - float angle = dot(light.direction, normalize(light_to_surface)); - if(acos(angle) < light.outer_angle) - { - color = calc_point_light(light); - color *= smoothstep(cos(light.outer_angle), cos(light.inner_angle), angle); - // if(light.cast_shadow != 0) - // { - // float shadow_factor = calc_shadow_factor(vert_light_space.xyz / vert_light_space.w); - // color *= shadow_factor; - // } - } - return color;// * shadowFactor; -} - - -void main() -{ - vec4 albedo_color = diffuse_color * texture(diffuse_texture, uv); - vec3 light_contribution = vec3(0.0, 0.0, 0.0); - - for(int i = 0; i < total_active_lights; i++) - { - if(i == total_active_lights) break; - - if(lights[i].type == LT_POINT) - light_contribution += calc_point_light(lights[i]); - else if(lights[i].type == LT_DIR) - light_contribution += calc_dir_light(lights[i]); - else - light_contribution += calc_spot_light(lights[i]); - } - - //frag_color = apply_fog((albedo_color * vec4(light_contribution + ambient_light, 1.0))); - frag_color = diffuse_color; -} diff --git a/src/common/linmath.c b/src/common/linmath.c index 6ae68e7..7253589 100755 --- a/src/common/linmath.c +++ b/src/common/linmath.c @@ -4,686 +4,689 @@ #include -const vec3 UNIT_X = {.x = 1, .y = 0, .z = 0}; -const vec3 UNIT_Y = {.x = 0, .y = 1, .z = 0}; -const vec3 UNIT_Z = {.x = 0, .y = 0, .z = 1}; - -const vec3 UNIT_X_NEG = {.x = -1, .y = 0, .z = 0}; -const vec3 UNIT_Y_NEG = {.x = 0, .y = -1, .z = 0}; -const vec3 UNIT_Z_NEG = {.x = 0, .y = 0, .z = -1}; +const vec3 UNIT_X = { 1, 0, 0 }; +const vec3 UNIT_Y = { 0, 1, 0 }; +const vec3 UNIT_Z = { 0, 0, 1 }; + +const vec3 UNIT_X_NEG = { -1, 0, 0 }; +const vec3 UNIT_Y_NEG = { 0, -1, 0 }; +const vec3 UNIT_Z_NEG = { 0, 0, -1 }; void vec2_fill(vec2* res, float x, float y) { - res->x = x; - res->y = y; + res->x = x; + res->y = y; } void vec2_add(vec2* res, vec2* v1, vec2* v2) { - res->x = v1->x + v2->x; - res->y = v1->y + v2->y; + res->x = v1->x + v2->x; + res->y = v1->y + v2->y; } void vec2_sub(vec2* res, vec2* v1, vec2* v2) { - res->x = v1->x - v2->x; - res->y = v1->y - v2->y; + res->x = v1->x - v2->x; + res->y = v1->y - v2->y; } void vec2_assign(vec2* res, const vec2* val) { - res->x = val->x; - res->y = val->y; + res->x = val->x; + res->y = val->y; } float vec2_len(vec2* val) { - return sqrtf((val->x * val->x) + (val->y * val->y)); + return sqrtf((val->x * val->x) + (val->y * val->y)); } void vec2_norm(vec2* res, vec2* val) { - if (!val->x && !val->y) - { - vec2_assign(res, val); - return; - } + if(!val->x && !val->y) + { + vec2_assign(res, val); + return; + } + + float l = 1.0f / vec2_len(val); + vec2 v; + v.x = val->x * l; + v.y = val->y * l; - float l = 1.0f / vec2_len(val); - vec2 v; - v.x = val->x * l; - v.y = val->y * l; - - res->x = v.x; - res->y = v.y; + res->x = v.x; + res->y = v.y; } void vec2_mul(vec2* res, vec2* v1, vec2* v2) { - res->x = v1->x * v2->x; - res->y = v1->y * v2->y; + res->x = v1->x * v2->x; + res->y = v1->y * v2->y; } void vec3_fill(vec3* res, float x, float y, float z) { - res->x = x; - res->y = y; - res->z = z; + res->x = x; + res->y = y; + res->z = z; } void vec3_add(vec3* res, const vec3* v1, const vec3* v3) { - res->x = v1->x + v3->x; - res->y = v1->y + v3->y; - res->z = v1->z + v3->z; + res->x = v1->x + v3->x; + res->y = v1->y + v3->y; + res->z = v1->z + v3->z; } void vec3_sub(vec3* res, const vec3* v1, const vec3* v3) { - res->x = v1->x - v3->x; - res->y = v1->y - v3->y; - res->z = v1->z - v3->z; + res->x = v1->x - v3->x; + res->y = v1->y - v3->y; + res->z = v1->z - v3->z; } void vec3_assign(vec3* res, const vec3* val) { - res->x = val->x; - res->y = val->y; - res->z = val->z; + res->x = val->x; + res->y = val->y; + res->z = val->z; } void vec3_cross(vec3* res, const vec3* v1, const vec3* v2) { - vec3 v; - v.x = (v1->y * v2->z) - (v1->z * v2->y); - v.y = (v1->z * v2->x) - (v1->x * v2->z); - v.z = (v1->x * v2->y) - (v1->y * v2->x); + vec3 v; + v.x = (v1->y * v2->z) - (v1->z * v2->y); + v.y = (v1->z * v2->x) - (v1->x * v2->z); + v.z = (v1->x * v2->y) - (v1->y * v2->x); - res->x = v.x; - res->y = v.y; - res->z = v.z; + res->x = v.x; + res->y = v.y; + res->z = v.z; } float vec3_len(vec3* val) { - return sqrtf((val->x * val->x) + (val->y * val->y) + (val->z * val->z)); + return sqrtf((val->x * val->x) + (val->y * val->y) + (val->z * val->z)); } void vec3_norm(vec3* res, vec3* val) { - if (!val->x && !val->y && !val->z) - { - vec3_assign(res, val); - return; - } + if(!val->x && !val->y && !val->z) + { + vec3_assign(res, val); + return; + } + + float l = 1.0f / vec3_len(val); + vec3 v; + v.x = val->x * l; + v.y = val->y * l; + v.z = val->z * l; - float l = 1.0f / vec3_len(val); - vec3 v; - v.x = val->x * l; - v.y = val->y * l; - v.z = val->z * l; - - res->x = v.x; - res->y = v.y; - res->z = v.z; + res->x = v.x; + res->y = v.y; + res->z = v.z; } void vec3_mul(vec3* res, vec3* v1, vec3* v3) { - res->x = v1->x * v3->x; - res->y = v1->y * v3->y; - res->z = v1->z * v3->z; + res->x = v1->x * v3->x; + res->y = v1->y * v3->y; + res->z = v1->z * v3->z; } void vec3_mul_mat4(vec3* res, vec3* val, mat4* mat) { - vec3 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + mat->mat[12]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + mat->mat[13]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + mat->mat[14]; - res->x = v.x; - res->y = v.y; - res->z = v.z; + vec3 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + mat->mat[12]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + mat->mat[13]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + mat->mat[14]; + res->x = v.x; + res->y = v.y; + res->z = v.z; } void vec3_scale(vec3* res, const vec3* val, float s) { - res->x = val->x * s; - res->y = val->y * s; - res->z = val->z * s; + res->x = val->x * s; + res->y = val->y * s; + res->z = val->z * s; } int vec3_equals(vec3* v1, vec3* v2) { - if ((v1->x < (v2->x + EPSILON) && v1->x > (v2->x - EPSILON)) && - (v1->y < (v2->y + EPSILON) && v1->y > (v2->y - EPSILON)) && - (v1->z < (v2->z + EPSILON) && v1->z > (v2->z - EPSILON))) - return 1; + if((v1->x < (v2->x + EPSILON) && v1->x >(v2->x - EPSILON)) && + (v1->y < (v2->y + EPSILON) && v1->y >(v2->y - EPSILON)) && + (v1->z < (v2->z + EPSILON) && v1->z >(v2->z - EPSILON))) + return 1; - return 0; + return 0; } void vec3_transform_norm(vec3* res, const vec3* val, const mat4* mat) { - /* - a = (Vx, Vy, Vz, 0) - b = (a×M)T - Out = (bx, by, bz) + /* + a = (Vx, Vy, Vz, 0) + b = (a×M)T + Out = (bx, by, bz) - Omits the translation, only scaling + rotating*/ - vec3 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; - res->x = v.x; - res->y = v.y; - res->z = v.z; + Omits the translation, only scaling + rotating*/ + vec3 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; + res->x = v.x; + res->y = v.y; + res->z = v.z; } float vec3_dot(vec3* v1, vec3* v2) { - return (v1->x * v2->x + - v1->y * v2->y + - v1->z * v2->z); + return (v1->x * v2->x + + v1->y * v2->y + + v1->z * v2->z); } void vec4_fill(vec4* res, float x, float y, float z, float w) { - res->x = x; - res->y = y; - res->z = z; - res->w = w; + res->x = x; + res->y = y; + res->z = z; + res->w = w; } void vec4_fill_vec3(vec4* res, const vec3* v, float w) { - res->x = v->x; - res->y = v->y; - res->z = v->z; - res->w = w; + res->x = v->x; + res->y = v->y; + res->z = v->z; + res->w = w; } void vec4_add(vec4* res, vec4* v1, vec4* v4) { - res->x = v1->x + v4->x; - res->y = v1->y + v4->y; - res->z = v1->z + v4->z; - res->w = v1->w + v4->w; + res->x = v1->x + v4->x; + res->y = v1->y + v4->y; + res->z = v1->z + v4->z; + res->w = v1->w + v4->w; } void vec4_sub(vec4* res, vec4* v1, vec4* v4) { - res->x = v1->x - v4->x; - res->y = v1->y - v4->y; - res->z = v1->z - v4->z; - res->w = v1->w - v4->w; + res->x = v1->x - v4->x; + res->y = v1->y - v4->y; + res->z = v1->z - v4->z; + res->w = v1->w - v4->w; } void vec4_assign(vec4* res, const vec4* val) { - res->x = val->x; - res->y = val->y; - res->z = val->z; - res->w = val->w; + res->x = val->x; + res->y = val->y; + res->z = val->z; + res->w = val->w; } float vec4_len(vec4* val) { - return sqrtf((val->x * val->x) + - (val->y * val->y) + - (val->z * val->z) + - (val->w * val->w)); + return sqrtf((val->x * val->x) + + (val->y * val->y) + + (val->z * val->z) + + (val->w * val->w)); } void vec4_norm(vec4* res, vec4* val) { - if (!val->x && !val->y && !val->z && !val->w) - { - vec4_assign(res, val); - return; - } - - float l = 1.0f / vec4_len(val); - vec4 v; - v.x = val->x * l; - v.y = val->y * l; - v.z = val->z * l; - v.w = val->w * l; - - res->x = v.x; - res->y = v.y; - res->z = v.z; - res->w = v.w; + if(!val->x && !val->y && !val->z && !val->w) + { + vec4_assign(res, val); + return; + } + + float l = 1.0f / vec4_len(val); + vec4 v; + v.x = val->x * l; + v.y = val->y * l; + v.z = val->z * l; + v.w = val->w * l; + + res->x = v.x; + res->y = v.y; + res->z = v.z; + res->w = v.w; } void vec4_mul(vec4* res, vec4* v1, vec4* v4) { - res->x = v1->x * v4->x; - res->y = v1->y * v4->y; - res->z = v1->z * v4->z; - res->w = v1->w * v4->w; + res->x = v1->x * v4->x; + res->y = v1->y * v4->y; + res->z = v1->z * v4->z; + res->w = v1->w * v4->w; } void vec4_mul_mat4(vec4* res, vec4* val, mat4* mat) { - vec4 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + val->w * mat->mat[12]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + val->w * mat->mat[13]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + val->w * mat->mat[14]; - v.w = val->x * mat->mat[3] + val->y * mat->mat[7] + val->z * mat->mat[11] + val->w * mat->mat[15]; - res->x = v.x; - res->y = v.y; - res->z = v.z; - res->w = v.w; + vec4 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + val->w * mat->mat[12]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + val->w * mat->mat[13]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + val->w * mat->mat[14]; + v.w = val->x * mat->mat[3] + val->y * mat->mat[7] + val->z * mat->mat[11] + val->w * mat->mat[15]; + res->x = v.x; + res->y = v.y; + res->z = v.z; + res->w = v.w; } void vec4_scale(vec4* res, const vec4* val, float s) { - res->x = val->x * s; - res->y = val->y * s; - res->z = val->z * s; - res->w = val->w * s; + res->x = val->x * s; + res->y = val->y * s; + res->z = val->z * s; + res->w = val->w * s; } int vec4_equals(vec4* v1, vec4* v2) { - if ((v1->x < (v2->x + EPSILON) && v1->x > (v2->x - EPSILON)) && - (v1->y < (v2->y + EPSILON) && v1->y > (v2->y - EPSILON)) && - (v1->z < (v2->z + EPSILON) && v1->z > (v2->z - EPSILON)) && - (v1->w < (v2->w + EPSILON) && v1->w > (v2->w - EPSILON))) - return 1; + if((v1->x < (v2->x + EPSILON) && v1->x >(v2->x - EPSILON)) && + (v1->y < (v2->y + EPSILON) && v1->y >(v2->y - EPSILON)) && + (v1->z < (v2->z + EPSILON) && v1->z >(v2->z - EPSILON)) && + (v1->w < (v2->w + EPSILON) && v1->w >(v2->w - EPSILON))) + return 1; - return 0; + return 0; } void vec4_transform_norm(vec4* res, const vec4* val, const mat4* mat) { - /* - a = (Vx, Vy, Vz, 0) - b = (a×M)T - Out = (bx, by, bz) + /* + a = (Vx, Vy, Vz, 0) + b = (a×M)T + Out = (bx, by, bz) - Omits the translation, only scaling + rotating*/ - vec4 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; - res->x = v.x; - res->y = v.y; - res->z = v.z; + Omits the translation, only scaling + rotating*/ + vec4 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; + res->x = v.x; + res->y = v.y; + res->z = v.z; } void mat4_identity(mat4* res) { - memset(res->mat, 0, sizeof(float) * 16); - res->mat[0] = res->mat[5] = res->mat[10] = res->mat[15] = 1.0f; + memset(res->mat, 0, sizeof(float) * 16); + res->mat[0] = res->mat[5] = res->mat[10] = res->mat[15] = 1.0f; } void mat4_mul(mat4* res, const mat4* mat1, const mat4* mat2) { - float mat[16]; - const float *m1 = mat1->mat, *m2 = mat2->mat; + float mat[16]; + const float *m1 = mat1->mat, *m2 = mat2->mat; + + mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; + mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; + mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; + mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; - mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; - mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; - mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; - mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; + mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; + mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; + mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; + mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; - mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; - mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; - mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; - mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; + mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; + mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; + mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; + mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; - mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; - mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; - mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; - mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; + mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; + mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; + mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; + mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; - mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; - mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; - mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; - mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; - - memcpy(res->mat, mat, sizeof(float)*16); + memcpy(res->mat, mat, sizeof(float) * 16); } void mat4_translate(mat4* res, float x, float y, float z) { - memset(res->mat, 0, sizeof(float) * 16); - res->mat[0] = 1.0f; - res->mat[5] = 1.0f; - res->mat[10] = 1.0f; + memset(res->mat, 0, sizeof(float) * 16); + res->mat[0] = 1.0f; + res->mat[5] = 1.0f; + res->mat[10] = 1.0f; - res->mat[12] = x; - res->mat[13] = y; - res->mat[14] = z; - res->mat[15] = 1.0f; + res->mat[12] = x; + res->mat[13] = y; + res->mat[14] = z; + res->mat[15] = 1.0f; } void mat4_lookat(mat4* res, const vec3* eye, const vec3* center, const vec3* up_vec) { - vec3 f, up, s, u; - mat4 translate; + vec3 f, up, s, u; + mat4 translate; - vec3_sub(&f, center, eye); - vec3_norm(&f, &f); + vec3_sub(&f, center, eye); + vec3_norm(&f, &f); - vec3_assign(&up, up_vec); - vec3_norm(&up, &up); + vec3_assign(&up, up_vec); + vec3_norm(&up, &up); - vec3_cross(&s, &f, &up); - vec3_norm(&s, &s); + vec3_cross(&s, &f, &up); + vec3_norm(&s, &s); - vec3_cross(&u, &s, &f); - vec3_norm(&s, &s); + vec3_cross(&u, &s, &f); + vec3_norm(&s, &s); - mat4_identity(res); + mat4_identity(res); - res->mat[0] = s.x; - res->mat[4] = s.y; - res->mat[8] = s.z; + res->mat[0] = s.x; + res->mat[4] = s.y; + res->mat[8] = s.z; - res->mat[1] = u.x; - res->mat[5] = u.y; - res->mat[9] = u.z; + res->mat[1] = u.x; + res->mat[5] = u.y; + res->mat[9] = u.z; - res->mat[2] = -f.x; - res->mat[6] = -f.y; - res->mat[10] = -f.z; + res->mat[2] = -f.x; + res->mat[6] = -f.y; + res->mat[10] = -f.z; - mat4_translate(&translate, -eye->x, -eye->y, -eye->z); - mat4_mul(res, res, &translate); + mat4_translate(&translate, -eye->x, -eye->y, -eye->z); + mat4_mul(res, res, &translate); } -void mat4_perspective(mat4* res, float fov, float aspect, float nearz, float farz ) +void mat4_perspective(mat4* res, float fov, float aspect, float nearz, float farz) { - float r = TO_RADIANS(fov / 2); - float deltaz = farz - nearz; - float s = (float)sin(r); - float cotangent = 0; + float r = TO_RADIANS(fov / 2); + float deltaz = farz - nearz; + float s = (float)sin(r); + float cotangent = 0; - if (deltaz == 0 || s == 0 || aspect == 0) - return; + if(deltaz == 0 || s == 0 || aspect == 0) + return; - cotangent = (float)cos(r) / s; - mat4_identity(res); - res->mat[0] = cotangent / aspect; - res->mat[5] = cotangent; - res->mat[10] = -(farz + nearz) / deltaz; - res->mat[11] = -1; - res->mat[14] = -2 * nearz * farz / deltaz; - res->mat[15] = 0; + cotangent = (float)cos(r) / s; + mat4_identity(res); + res->mat[0] = cotangent / aspect; + res->mat[5] = cotangent; + res->mat[10] = -(farz + nearz) / deltaz; + res->mat[11] = -1; + res->mat[14] = -2 * nearz * farz / deltaz; + res->mat[15] = 0; } void mat4_ortho(mat4* res, - float left, float right, - float bottom, float top, - float nearz, float farz) -{ - float tx = -((right + left) / (right - left)); - float ty = -((top + bottom) / (top - bottom)); - float tz = -((farz + nearz) / (farz - nearz)); - mat4_identity(res); - res->mat[0] = 2 / (right - left); - res->mat[5] = 2 / (top - bottom); - res->mat[10] = -2 / (farz - nearz); - res->mat[12] = tx; - res->mat[13] = ty; - res->mat[14] = tz; + float left, float right, + float bottom, float top, + float nearz, float farz) +{ + float tx = -((right + left) / (right - left)); + float ty = -((top + bottom) / (top - bottom)); + float tz = -((farz + nearz) / (farz - nearz)); + mat4_identity(res); + res->mat[0] = 2 / (right - left); + res->mat[5] = 2 / (top - bottom); + res->mat[10] = -2 / (farz - nearz); + res->mat[12] = tx; + res->mat[13] = ty; + res->mat[14] = tz; } void mat4_scale(mat4* res, float x, float y, float z) { - memset(res->mat, 0, sizeof(float) * 16); - res->mat[0] = x; - res->mat[5] = y; - res->mat[10] = z; - res->mat[15] = 1.0f; + memset(res->mat, 0, sizeof(float) * 16); + res->mat[0] = x; + res->mat[5] = y; + res->mat[10] = z; + res->mat[15] = 1.0f; } void mat4_from_quat(mat4* res, const quat* q) { - float xx = q->x * q->x; - float xy = q->x * q->y; - float xz = q->x * q->z; - float xw = q->x * q->w; + float xx = q->x * q->x; + float xy = q->x * q->y; + float xz = q->x * q->z; + float xw = q->x * q->w; - float yy = q->y * q->y; - float yz = q->y * q->z; - float yw = q->y * q->w; + float yy = q->y * q->y; + float yz = q->y * q->z; + float yw = q->y * q->w; - float zz = q->z * q->z; - float zw = q->z * q->w; + float zz = q->z * q->z; + float zw = q->z * q->w; - res->mat[0] = 1 - 2 * (yy + zz); - res->mat[1] = 2 * (xy + zw); - res->mat[2] = 2 * (xz - yw); - res->mat[3] = 0; + res->mat[0] = 1 - 2 * (yy + zz); + res->mat[1] = 2 * (xy + zw); + res->mat[2] = 2 * (xz - yw); + res->mat[3] = 0; - res->mat[4] = 2 * (xy - zw); - res->mat[5] = 1 - 2 * (xx + zz); - res->mat[6] = 2 * (yz + xw); - res->mat[7] = 0.0; + res->mat[4] = 2 * (xy - zw); + res->mat[5] = 1 - 2 * (xx + zz); + res->mat[6] = 2 * (yz + xw); + res->mat[7] = 0.0; - res->mat[8] = 2 * (xz + yw); - res->mat[9] = 2 * (yz - xw); - res->mat[10] = 1 - 2 * (xx + yy); - res->mat[11] = 0.0; + res->mat[8] = 2 * (xz + yw); + res->mat[9] = 2 * (yz - xw); + res->mat[10] = 1 - 2 * (xx + yy); + res->mat[11] = 0.0; - res->mat[12] = 0.0; - res->mat[13] = 0.0; - res->mat[14] = 0.0; - res->mat[15] = 1.0; + res->mat[12] = 0.0; + res->mat[13] = 0.0; + res->mat[14] = 0.0; + res->mat[15] = 1.0; } void mat4_rot_x(mat4* res, const float angle) { - res->mat[0] = 1.0f; - res->mat[1] = 0.0f; - res->mat[2] = 0.0f; - res->mat[3] = 0.0f; + float angle_radians = TO_RADIANS(angle); + res->mat[0] = 1.0f; + res->mat[1] = 0.0f; + res->mat[2] = 0.0f; + res->mat[3] = 0.0f; - res->mat[4] = 0.0f; - res->mat[5] = cosf(angle); - res->mat[6] = sinf(angle); - res->mat[7] = 0.0f; + res->mat[4] = 0.0f; + res->mat[5] = cosf(angle_radians); + res->mat[6] = sinf(angle_radians); + res->mat[7] = 0.0f; - res->mat[8] = 0.0f; - res->mat[9] = -sinf(angle); - res->mat[10] = cosf(angle); - res->mat[11] = 0.0f; + res->mat[8] = 0.0f; + res->mat[9] = -sinf(angle_radians); + res->mat[10] = cosf(angle_radians); + res->mat[11] = 0.0f; - res->mat[12] = 0.0f; - res->mat[13] = 0.0f; - res->mat[14] = 0.0f; - res->mat[15] = 1.0f; + res->mat[12] = 0.0f; + res->mat[13] = 0.0f; + res->mat[14] = 0.0f; + res->mat[15] = 1.0f; } void mat4_rot_y(mat4* res, float angle) { - res->mat[0] = cosf(angle); - res->mat[1] = 0.0f; - res->mat[2] = -sinf(angle); - res->mat[3] = 0.0f; + float angle_radians = TO_RADIANS(angle); + res->mat[0] = cosf(angle_radians); + res->mat[1] = 0.0f; + res->mat[2] = -sinf(angle_radians); + res->mat[3] = 0.0f; - res->mat[4] = 0.0f; - res->mat[5] = 1.0f; - res->mat[6] = 0.0f; - res->mat[7] = 0.0f; + res->mat[4] = 0.0f; + res->mat[5] = 1.0f; + res->mat[6] = 0.0f; + res->mat[7] = 0.0f; - res->mat[8] = sinf(angle); - res->mat[9] = 0.0f; - res->mat[10] = cosf(angle); - res->mat[11] = 0.0f; + res->mat[8] = sinf(angle_radians); + res->mat[9] = 0.0f; + res->mat[10] = cosf(angle_radians); + res->mat[11] = 0.0f; - res->mat[12] = 0.0f; - res->mat[13] = 0.0f; - res->mat[14] = 0.0f; - res->mat[15] = 1.0f; + res->mat[12] = 0.0f; + res->mat[13] = 0.0f; + res->mat[14] = 0.0f; + res->mat[15] = 1.0f; } void mat4_rot_z(mat4* res, float angle) { - res->mat[0] = cosf(angle); - res->mat[1] = sinf(angle); - res->mat[2] = 0.0f; - res->mat[3] = 0.0f; + float angle_radians = TO_RADIANS(angle); + res->mat[0] = cosf(angle_radians); + res->mat[1] = sinf(angle_radians); + res->mat[2] = 0.0f; + res->mat[3] = 0.0f; - res->mat[4] = -sinf(angle); - res->mat[5] = cosf(angle); - res->mat[6] = 0.0f; - res->mat[7] = 0.0f; + res->mat[4] = -sinf(angle_radians); + res->mat[5] = cosf(angle_radians); + res->mat[6] = 0.0f; + res->mat[7] = 0.0f; - res->mat[8] = 0.0f; - res->mat[9] = 0.0f; - res->mat[10] = 1.0f; - res->mat[11] = 0.0f; + res->mat[8] = 0.0f; + res->mat[9] = 0.0f; + res->mat[10] = 1.0f; + res->mat[11] = 0.0f; - res->mat[12] = 0.0f; - res->mat[13] = 0.0f; - res->mat[14] = 0.0f; - res->mat[15] = 1.0f; + res->mat[12] = 0.0f; + res->mat[13] = 0.0f; + res->mat[14] = 0.0f; + res->mat[15] = 1.0f; } void mat4_assign(mat4* res, const mat4* m) { - if(res == m) - return; - memcpy(res->mat, m->mat, sizeof(float) * 16); + if(res == m) + return; + memcpy(res->mat, m->mat, sizeof(float) * 16); } void mat4_inverse(mat4* res, mat4* mat) { - mat4 tmp; - float det; - int i; - - tmp.mat[0] = mat->mat[5] * mat->mat[10] * mat->mat[15] - - mat->mat[5] * mat->mat[11] * mat->mat[14] - - mat->mat[9] * mat->mat[6] * mat->mat[15] + - mat->mat[9] * mat->mat[7] * mat->mat[14] + - mat->mat[13] * mat->mat[6] * mat->mat[11] - - mat->mat[13] * mat->mat[7] * mat->mat[10]; - - tmp.mat[4] = -mat->mat[4] * mat->mat[10] * mat->mat[15] + - mat->mat[4] * mat->mat[11] * mat->mat[14] + - mat->mat[8] * mat->mat[6] * mat->mat[15] - - mat->mat[8] * mat->mat[7] * mat->mat[14] - - mat->mat[12] * mat->mat[6] * mat->mat[11] + - mat->mat[12] * mat->mat[7] * mat->mat[10]; - - tmp.mat[8] = mat->mat[4] * mat->mat[9] * mat->mat[15] - - mat->mat[4] * mat->mat[11] * mat->mat[13] - - mat->mat[8] * mat->mat[5] * mat->mat[15] + - mat->mat[8] * mat->mat[7] * mat->mat[13] + - mat->mat[12] * mat->mat[5] * mat->mat[11] - - mat->mat[12] * mat->mat[7] * mat->mat[9]; - - tmp.mat[12] = -mat->mat[4] * mat->mat[9] * mat->mat[14] + - mat->mat[4] * mat->mat[10] * mat->mat[13] + - mat->mat[8] * mat->mat[5] * mat->mat[14] - - mat->mat[8] * mat->mat[6] * mat->mat[13] - - mat->mat[12] * mat->mat[5] * mat->mat[10] + - mat->mat[12] * mat->mat[6] * mat->mat[9]; - - tmp.mat[1] = -mat->mat[1] * mat->mat[10] * mat->mat[15] + - mat->mat[1] * mat->mat[11] * mat->mat[14] + - mat->mat[9] * mat->mat[2] * mat->mat[15] - - mat->mat[9] * mat->mat[3] * mat->mat[14] - - mat->mat[13] * mat->mat[2] * mat->mat[11] + - mat->mat[13] * mat->mat[3] * mat->mat[10]; - - tmp.mat[5] = mat->mat[0] * mat->mat[10] * mat->mat[15] - - mat->mat[0] * mat->mat[11] * mat->mat[14] - - mat->mat[8] * mat->mat[2] * mat->mat[15] + - mat->mat[8] * mat->mat[3] * mat->mat[14] + - mat->mat[12] * mat->mat[2] * mat->mat[11] - - mat->mat[12] * mat->mat[3] * mat->mat[10]; - - tmp.mat[9] = -mat->mat[0] * mat->mat[9] * mat->mat[15] + - mat->mat[0] * mat->mat[11] * mat->mat[13] + - mat->mat[8] * mat->mat[1] * mat->mat[15] - - mat->mat[8] * mat->mat[3] * mat->mat[13] - - mat->mat[12] * mat->mat[1] * mat->mat[11] + - mat->mat[12] * mat->mat[3] * mat->mat[9]; - - tmp.mat[13] = mat->mat[0] * mat->mat[9] * mat->mat[14] - - mat->mat[0] * mat->mat[10] * mat->mat[13] - - mat->mat[8] * mat->mat[1] * mat->mat[14] + - mat->mat[8] * mat->mat[2] * mat->mat[13] + - mat->mat[12] * mat->mat[1] * mat->mat[10] - - mat->mat[12] * mat->mat[2] * mat->mat[9]; - - tmp.mat[2] = mat->mat[1] * mat->mat[6] * mat->mat[15] - - mat->mat[1] * mat->mat[7] * mat->mat[14] - - mat->mat[5] * mat->mat[2] * mat->mat[15] + - mat->mat[5] * mat->mat[3] * mat->mat[14] + - mat->mat[13] * mat->mat[2] * mat->mat[7] - - mat->mat[13] * mat->mat[3] * mat->mat[6]; - - tmp.mat[6] = -mat->mat[0] * mat->mat[6] * mat->mat[15] + - mat->mat[0] * mat->mat[7] * mat->mat[14] + - mat->mat[4] * mat->mat[2] * mat->mat[15] - - mat->mat[4] * mat->mat[3] * mat->mat[14] - - mat->mat[12] * mat->mat[2] * mat->mat[7] + - mat->mat[12] * mat->mat[3] * mat->mat[6]; - - tmp.mat[10] = mat->mat[0] * mat->mat[5] * mat->mat[15] - - mat->mat[0] * mat->mat[7] * mat->mat[13] - - mat->mat[4] * mat->mat[1] * mat->mat[15] + - mat->mat[4] * mat->mat[3] * mat->mat[13] + - mat->mat[12] * mat->mat[1] * mat->mat[7] - - mat->mat[12] * mat->mat[3] * mat->mat[5]; - - tmp.mat[14] = -mat->mat[0] * mat->mat[5] * mat->mat[14] + - mat->mat[0] * mat->mat[6] * mat->mat[13] + - mat->mat[4] * mat->mat[1] * mat->mat[14] - - mat->mat[4] * mat->mat[2] * mat->mat[13] - - mat->mat[12] * mat->mat[1] * mat->mat[6] + - mat->mat[12] * mat->mat[2] * mat->mat[5]; - - tmp.mat[3] = -mat->mat[1] * mat->mat[6] * mat->mat[11] + - mat->mat[1] * mat->mat[7] * mat->mat[10] + - mat->mat[5] * mat->mat[2] * mat->mat[11] - - mat->mat[5] * mat->mat[3] * mat->mat[10] - - mat->mat[9] * mat->mat[2] * mat->mat[7] + - mat->mat[9] * mat->mat[3] * mat->mat[6]; - - tmp.mat[7] = mat->mat[0] * mat->mat[6] * mat->mat[11] - - mat->mat[0] * mat->mat[7] * mat->mat[10] - - mat->mat[4] * mat->mat[2] * mat->mat[11] + - mat->mat[4] * mat->mat[3] * mat->mat[10] + - mat->mat[8] * mat->mat[2] * mat->mat[7] - - mat->mat[8] * mat->mat[3] * mat->mat[6]; - - tmp.mat[11] = -mat->mat[0] * mat->mat[5] * mat->mat[11] + - mat->mat[0] * mat->mat[7] * mat->mat[9] + - mat->mat[4] * mat->mat[1] * mat->mat[11] - - mat->mat[4] * mat->mat[3] * mat->mat[9] - - mat->mat[8] * mat->mat[1] * mat->mat[7] + - mat->mat[8] * mat->mat[3] * mat->mat[5]; - - tmp.mat[15] = mat->mat[0] * mat->mat[5] * mat->mat[10] - - mat->mat[0] * mat->mat[6] * mat->mat[9] - - mat->mat[4] * mat->mat[1] * mat->mat[10] + - mat->mat[4] * mat->mat[2] * mat->mat[9] + - mat->mat[8] * mat->mat[1] * mat->mat[6] - - mat->mat[8] * mat->mat[2] * mat->mat[5]; - - det = mat->mat[0] * tmp.mat[0] + mat->mat[1] * tmp.mat[4] + mat->mat[2] * tmp.mat[8] + mat->mat[3] * tmp.mat[12]; - - if (det == 0) { - return; - } - - det = 1.f / det; - - for (i = 0; i < 16; i++) { - res->mat[i] = tmp.mat[i] * det; - } + mat4 tmp; + float det; + int i; + + tmp.mat[0] = mat->mat[5] * mat->mat[10] * mat->mat[15] - + mat->mat[5] * mat->mat[11] * mat->mat[14] - + mat->mat[9] * mat->mat[6] * mat->mat[15] + + mat->mat[9] * mat->mat[7] * mat->mat[14] + + mat->mat[13] * mat->mat[6] * mat->mat[11] - + mat->mat[13] * mat->mat[7] * mat->mat[10]; + + tmp.mat[4] = -mat->mat[4] * mat->mat[10] * mat->mat[15] + + mat->mat[4] * mat->mat[11] * mat->mat[14] + + mat->mat[8] * mat->mat[6] * mat->mat[15] - + mat->mat[8] * mat->mat[7] * mat->mat[14] - + mat->mat[12] * mat->mat[6] * mat->mat[11] + + mat->mat[12] * mat->mat[7] * mat->mat[10]; + + tmp.mat[8] = mat->mat[4] * mat->mat[9] * mat->mat[15] - + mat->mat[4] * mat->mat[11] * mat->mat[13] - + mat->mat[8] * mat->mat[5] * mat->mat[15] + + mat->mat[8] * mat->mat[7] * mat->mat[13] + + mat->mat[12] * mat->mat[5] * mat->mat[11] - + mat->mat[12] * mat->mat[7] * mat->mat[9]; + + tmp.mat[12] = -mat->mat[4] * mat->mat[9] * mat->mat[14] + + mat->mat[4] * mat->mat[10] * mat->mat[13] + + mat->mat[8] * mat->mat[5] * mat->mat[14] - + mat->mat[8] * mat->mat[6] * mat->mat[13] - + mat->mat[12] * mat->mat[5] * mat->mat[10] + + mat->mat[12] * mat->mat[6] * mat->mat[9]; + + tmp.mat[1] = -mat->mat[1] * mat->mat[10] * mat->mat[15] + + mat->mat[1] * mat->mat[11] * mat->mat[14] + + mat->mat[9] * mat->mat[2] * mat->mat[15] - + mat->mat[9] * mat->mat[3] * mat->mat[14] - + mat->mat[13] * mat->mat[2] * mat->mat[11] + + mat->mat[13] * mat->mat[3] * mat->mat[10]; + + tmp.mat[5] = mat->mat[0] * mat->mat[10] * mat->mat[15] - + mat->mat[0] * mat->mat[11] * mat->mat[14] - + mat->mat[8] * mat->mat[2] * mat->mat[15] + + mat->mat[8] * mat->mat[3] * mat->mat[14] + + mat->mat[12] * mat->mat[2] * mat->mat[11] - + mat->mat[12] * mat->mat[3] * mat->mat[10]; + + tmp.mat[9] = -mat->mat[0] * mat->mat[9] * mat->mat[15] + + mat->mat[0] * mat->mat[11] * mat->mat[13] + + mat->mat[8] * mat->mat[1] * mat->mat[15] - + mat->mat[8] * mat->mat[3] * mat->mat[13] - + mat->mat[12] * mat->mat[1] * mat->mat[11] + + mat->mat[12] * mat->mat[3] * mat->mat[9]; + + tmp.mat[13] = mat->mat[0] * mat->mat[9] * mat->mat[14] - + mat->mat[0] * mat->mat[10] * mat->mat[13] - + mat->mat[8] * mat->mat[1] * mat->mat[14] + + mat->mat[8] * mat->mat[2] * mat->mat[13] + + mat->mat[12] * mat->mat[1] * mat->mat[10] - + mat->mat[12] * mat->mat[2] * mat->mat[9]; + + tmp.mat[2] = mat->mat[1] * mat->mat[6] * mat->mat[15] - + mat->mat[1] * mat->mat[7] * mat->mat[14] - + mat->mat[5] * mat->mat[2] * mat->mat[15] + + mat->mat[5] * mat->mat[3] * mat->mat[14] + + mat->mat[13] * mat->mat[2] * mat->mat[7] - + mat->mat[13] * mat->mat[3] * mat->mat[6]; + + tmp.mat[6] = -mat->mat[0] * mat->mat[6] * mat->mat[15] + + mat->mat[0] * mat->mat[7] * mat->mat[14] + + mat->mat[4] * mat->mat[2] * mat->mat[15] - + mat->mat[4] * mat->mat[3] * mat->mat[14] - + mat->mat[12] * mat->mat[2] * mat->mat[7] + + mat->mat[12] * mat->mat[3] * mat->mat[6]; + + tmp.mat[10] = mat->mat[0] * mat->mat[5] * mat->mat[15] - + mat->mat[0] * mat->mat[7] * mat->mat[13] - + mat->mat[4] * mat->mat[1] * mat->mat[15] + + mat->mat[4] * mat->mat[3] * mat->mat[13] + + mat->mat[12] * mat->mat[1] * mat->mat[7] - + mat->mat[12] * mat->mat[3] * mat->mat[5]; + + tmp.mat[14] = -mat->mat[0] * mat->mat[5] * mat->mat[14] + + mat->mat[0] * mat->mat[6] * mat->mat[13] + + mat->mat[4] * mat->mat[1] * mat->mat[14] - + mat->mat[4] * mat->mat[2] * mat->mat[13] - + mat->mat[12] * mat->mat[1] * mat->mat[6] + + mat->mat[12] * mat->mat[2] * mat->mat[5]; + + tmp.mat[3] = -mat->mat[1] * mat->mat[6] * mat->mat[11] + + mat->mat[1] * mat->mat[7] * mat->mat[10] + + mat->mat[5] * mat->mat[2] * mat->mat[11] - + mat->mat[5] * mat->mat[3] * mat->mat[10] - + mat->mat[9] * mat->mat[2] * mat->mat[7] + + mat->mat[9] * mat->mat[3] * mat->mat[6]; + + tmp.mat[7] = mat->mat[0] * mat->mat[6] * mat->mat[11] - + mat->mat[0] * mat->mat[7] * mat->mat[10] - + mat->mat[4] * mat->mat[2] * mat->mat[11] + + mat->mat[4] * mat->mat[3] * mat->mat[10] + + mat->mat[8] * mat->mat[2] * mat->mat[7] - + mat->mat[8] * mat->mat[3] * mat->mat[6]; + + tmp.mat[11] = -mat->mat[0] * mat->mat[5] * mat->mat[11] + + mat->mat[0] * mat->mat[7] * mat->mat[9] + + mat->mat[4] * mat->mat[1] * mat->mat[11] - + mat->mat[4] * mat->mat[3] * mat->mat[9] - + mat->mat[8] * mat->mat[1] * mat->mat[7] + + mat->mat[8] * mat->mat[3] * mat->mat[5]; + + tmp.mat[15] = mat->mat[0] * mat->mat[5] * mat->mat[10] - + mat->mat[0] * mat->mat[6] * mat->mat[9] - + mat->mat[4] * mat->mat[1] * mat->mat[10] + + mat->mat[4] * mat->mat[2] * mat->mat[9] + + mat->mat[8] * mat->mat[1] * mat->mat[6] - + mat->mat[8] * mat->mat[2] * mat->mat[5]; + + det = mat->mat[0] * tmp.mat[0] + mat->mat[1] * tmp.mat[4] + mat->mat[2] * tmp.mat[8] + mat->mat[3] * tmp.mat[12]; + + if(det == 0) { + return; + } + + det = 1.f / det; + + for(i = 0; i < 16; i++) { + res->mat[i] = tmp.mat[i] * det; + } } @@ -691,138 +694,138 @@ void mat4_inverse(mat4* res, mat4* mat) void quat_fill(quat* res, float x, float y, float z, float w) { - res->x = x; - res->y = y; - res->z = z; - res->w = w; + res->x = x; + res->y = y; + res->z = z; + res->w = w; } void quat_identity(quat* res) { - res->x = 0.0; - res->y = 0.0; - res->z = 0.0; - res->w = 1.0; + res->x = 0.0; + res->y = 0.0; + res->z = 0.0; + res->w = 1.0; } void quat_mul_vec3(vec3* res, const quat* q, const vec3* v) { - vec3 uv, uuv, qvec; - qvec.x = q->x; - qvec.y = q->y; - qvec.z = q->z; + vec3 uv, uuv, qvec; + qvec.x = q->x; + qvec.y = q->y; + qvec.z = q->z; - vec3_cross(&uv, &qvec, v); - vec3_cross(&uuv, &qvec, &uv); + vec3_cross(&uv, &qvec, v); + vec3_cross(&uuv, &qvec, &uv); - vec3_scale(&uv, &uv, (2.0f * q->w)); - vec3_scale(&uuv, &uuv, 2.0f); + vec3_scale(&uv, &uv, (2.0f * q->w)); + vec3_scale(&uuv, &uuv, 2.0f); - vec3_add(res, v, &uv); - vec3_add(res, res, &uuv); + vec3_add(res, v, &uv); + vec3_add(res, res, &uuv); } void quat_assign(quat* res, const quat* val) { - res->x = val->x; - res->y = val->y; - res->z = val->z; - res->w = val->w; + res->x = val->x; + res->y = val->y; + res->z = val->z; + res->w = val->w; } void quat_mul(quat* res, const quat* q1, const quat* q2) { - quat tmp1, tmp2; - quat_assign(&tmp1, q1); - quat_assign(&tmp2, q2); + quat tmp1, tmp2; + quat_assign(&tmp1, q1); + quat_assign(&tmp2, q2); - res->x = tmp1.w * tmp2.x + tmp1.x * tmp2.w + tmp1.y * tmp2.z - tmp1.z * tmp2.y; - res->y = tmp1.w * tmp2.y + tmp1.y * tmp2.w + tmp1.z * tmp2.x - tmp1.x * tmp2.z; - res->z = tmp1.w * tmp2.z + tmp1.z * tmp2.w + tmp1.x * tmp2.y - tmp1.y * tmp2.x; - res->w = tmp1.w * tmp2.w - tmp1.x * tmp2.x - tmp1.y * tmp2.y - tmp1.z * tmp2.z; + res->x = tmp1.w * tmp2.x + tmp1.x * tmp2.w + tmp1.y * tmp2.z - tmp1.z * tmp2.y; + res->y = tmp1.w * tmp2.y + tmp1.y * tmp2.w + tmp1.z * tmp2.x - tmp1.x * tmp2.z; + res->z = tmp1.w * tmp2.z + tmp1.z * tmp2.w + tmp1.x * tmp2.y - tmp1.y * tmp2.x; + res->w = tmp1.w * tmp2.w - tmp1.x * tmp2.x - tmp1.y * tmp2.y - tmp1.z * tmp2.z; } float quat_len_sq(const quat* q) { - return (q->x * q->x) + (q->y * q->y) + (q->z * q->z) + (q->w * q->w); + return (q->x * q->x) + (q->y * q->y) + (q->z * q->z) + (q->w * q->w); } float quat_len(const quat* q) { - return (float)sqrt(quat_len_sq(q)); + return (float)sqrt(quat_len_sq(q)); } void quat_norm(quat* res, const quat* val) { - float length = quat_len(val); - if(fabs(length) < EPSILON) - { - quat_fill(res, 0.0f, 0.0f, 0.0f, 0.0f); - return; - } + float length = quat_len(val); + if(fabs(length) < EPSILON) + { + quat_fill(res, 0.0f, 0.0f, 0.0f, 0.0f); + return; + } - quat_fill(res, res->x / length, res->y / length, res->z / length, res->w / length); + quat_fill(res, res->x / length, res->y / length, res->z / length, res->w / length); } void quat_axis_angle(quat* res, const vec3* v, float angle) { - float half_angle = angle * 0.5f; - float scale = sinf(half_angle); + float half_angle = TO_RADIANS(angle) * 0.5f; + float scale = sinf(half_angle); - res->x = v->x * scale; - res->y = v->y * scale; - res->z = v->z * scale; - res->w = cosf(half_angle); - quat_norm(res, res); + res->x = v->x * scale; + res->y = v->y * scale; + res->z = v->z * scale; + res->w = cosf(half_angle); + quat_norm(res, res); } void quat_get_forward_rh(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_Z_NEG); + quat_mul_vec3(res, q, &UNIT_Z_NEG); } void quat_get_forward_lh(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_Z); + quat_mul_vec3(res, q, &UNIT_Z); } void quat_get_up(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_Y); + quat_mul_vec3(res, q, &UNIT_Y); } void quat_get_right(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_X); + quat_mul_vec3(res, q, &UNIT_X); } float quat_get_pitch(const quat* q) { - float result = (float)atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z); - return result; + float result = (float)atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z); + return result; } float quat_get_yaw(const quat* q) { - float result = (float)asin(-2 * (q->x * q->z - q->w * q->y)); - return result; + float result = (float)asin(-2 * (q->x * q->z - q->w * q->y)); + return result; } float quat_get_roll(const quat* q) { - float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z); - return result; + float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z); + return result; } void quat_mul_mat4(quat* res, quat* val, mat4* mat) { - vec4 v; - vec4_fill(&v, val->x, val->y, val->z, val->w); - vec4_mul_mat4(&v, &v, mat); - res->x = v.x; - res->y = v.y; - res->z = v.z; - res->w = v.w; + vec4 v; + vec4_fill(&v, val->x, val->y, val->z, val->w); + vec4_mul_mat4(&v, &v, mat); + res->x = v.x; + res->y = v.y; + res->z = v.z; + res->w = v.w; } void plane_init(Plane* plane, vec3* normal, vec3* point) diff --git a/src/game/editor.c b/src/game/editor.c index 6718988..c2b551f 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -117,16 +117,18 @@ void editor_init(struct Editor* editor) editor->grid_relative = 1; editor->grid_num_lines = 100; editor->grid_scale = 1.f; - editor->tool_mesh_draw_enabled = 0; + editor->tool_mesh_draw_enabled = 1; editor->tool_snap_enabled = 1; + editor->tool_rotate_arc_radius = 10.f; + editor->tool_rotate_arc_segments = 20.f; editor->axis_line_length = 500.f; vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f); vec4_fill(&editor->tool_mesh_color, 0.f, 1.f, 1.f, 1.f); - vec4_fill(&editor->selected_entity_colour, 1.f, 1.f, 0.f, 1.f); + vec4_fill(&editor->selected_entity_colour, 0.96, 0.61, 0.17, 1.f); vec4_fill(&editor->grid_color, 0.3f, 0.3f, 0.3f, 0.1f); - vec4_fill(&editor->axis_color_x, 1.f, 0.f, 0.f, 1.f); - vec4_fill(&editor->axis_color_y, 0.f, 1.f, 0.f, 1.f); - vec4_fill(&editor->axis_color_z, 0.f, 0.f, 1.f, 1.f); + vec4_fill(&editor->axis_color_x, 0.87, 0.32, 0.40, 1.f); + vec4_fill(&editor->axis_color_y, 0.53, 0.67, 0.28, 1.f); + vec4_fill(&editor->axis_color_z, 0.47, 0.67, 0.89, 1.f); debug_vars_list = array_new(struct Debug_Variable); empty_indices = array_new(int); @@ -183,9 +185,9 @@ void editor_render(struct Editor* editor, struct Camera * active_camera) float half_axis_line_length = editor->axis_line_length / 2.f; - im_line((vec3) { -half_axis_line_length, 0.f, 0.f }, (vec3) { half_axis_line_length, 0.f, 0.f }, position, rotation, scale, editor->axis_color_x, GDM_LINES, 1); // X Axis - im_line((vec3) { 0.f, -half_axis_line_length, 0.f }, (vec3) { 0.f, half_axis_line_length, 0.f }, position, rotation, scale, editor->axis_color_y, GDM_LINES, 1); // Y Axis - im_line((vec3) { 0.f, 0.f, -half_axis_line_length }, (vec3) { 0.f, 0.f, half_axis_line_length }, position, rotation, scale, editor->axis_color_z, GDM_LINES, 1); // Z Axis + im_line((vec3) { -half_axis_line_length, 0.f, 0.f }, (vec3) { half_axis_line_length, 0.f, 0.f }, position, rotation, scale, editor->axis_color_x, 1); // X Axis + im_line((vec3) { 0.f, -half_axis_line_length, 0.f }, (vec3) { 0.f, half_axis_line_length, 0.f }, position, rotation, scale, editor->axis_color_y, 1); // Y Axis + im_line((vec3) { 0.f, 0.f, -half_axis_line_length }, (vec3) { 0.f, 0.f, half_axis_line_length }, position, rotation, scale, editor->axis_color_z, 1); // Z Axis //Draw Grid if(editor->grid_enabled) @@ -428,7 +430,9 @@ void editor_update(struct Editor* editor, float dt) if(editor->tool_mesh_draw_enabled) { - if(editor->current_mode == EDITOR_MODE_TRANSLATE) + switch(editor->current_mode) + { + case EDITOR_MODE_TRANSLATE: { quat rotation = { 0.f, 0.f, 0.f, 1.f }; vec3 scale = { 1.f, 1.f, 1.f }; @@ -438,20 +442,32 @@ void editor_update(struct Editor* editor, float dt) switch(editor->current_axis) { case EDITOR_AXIS_XZ: - im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, GDM_LINES, 3); - im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, GDM_LINES, 3); + im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, 3); + im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, 3); break; case EDITOR_AXIS_Y: - im_line((vec3) { 0.f, -editor->axis_line_length, 0.f }, (vec3) { 0.f, editor->axis_line_length, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_y, GDM_LINES, 3); + im_line((vec3) { 0.f, -editor->axis_line_length, 0.f }, (vec3) { 0.f, editor->axis_line_length, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_y, 3); break; case EDITOR_AXIS_X: - im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, GDM_LINES, 3); + im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, 3); break; case EDITOR_AXIS_Z: - im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, GDM_LINES, 3); + im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, 3); break; } } + break; + case EDITOR_MODE_ROTATE: + { + quat rotation = { 0.f, 0.f, 0.f, 1.f }; + quat_axis_angle(&rotation, &UNIT_X, -90.f); + vec3 scale = { 1.f, 1.f, 1.f }; + //im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, editor->tool_mesh_position, rotation, editor->axis_color_x, 3); + im_arc(editor->tool_rotate_arc_radius, 0.f, 90.f, editor->tool_rotate_arc_segments, editor->tool_mesh_position, rotation, editor->axis_color_y, 3); + } + break; + + } } } @@ -626,11 +642,12 @@ void editor_mode_set(struct Editor* editor, int mode) if(editor->current_mode != mode) { editor->current_mode = mode; - if(editor->current_mode == EDITOR_MODE_TRANSLATE) - editor->tool_mesh_draw_enabled = 1; - else - editor->tool_mesh_draw_enabled = 0; } + + if(editor->selected_entity) + transform_get_absolute_position(editor->selected_entity, &editor->tool_mesh_position); + else + vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f); } void editor_entity_select(struct Editor* editor, struct Entity* entity) diff --git a/src/game/editor.h b/src/game/editor.h index 854978a..c603758 100755 --- a/src/game/editor.h +++ b/src/game/editor.h @@ -34,6 +34,8 @@ struct Editor vec3 tool_mesh_position; vec4 tool_mesh_color; int tool_mesh_draw_enabled; + float tool_rotate_arc_radius; + int tool_rotate_arc_segments; float axis_line_length; vec4 axis_color_x; vec4 axis_color_y; diff --git a/src/game/geometry.c b/src/game/geometry.c index b66941c..c478eac 100755 --- a/src/game/geometry.c +++ b/src/game/geometry.c @@ -26,9 +26,11 @@ void geom_init(void) geometry_list = array_new(struct Geometry); empty_indices = array_new(int); draw_modes = array_new_cap(GLenum, GDM_NUM_DRAWMODES); - draw_modes[GDM_TRIANGLES] = GL_TRIANGLES; - draw_modes[GDM_LINES] = GL_LINES; - draw_modes[GDM_POINTS] = GL_POINTS; + draw_modes[GDM_TRIANGLES] = GL_TRIANGLES; + draw_modes[GDM_LINES] = GL_LINES; + draw_modes[GDM_POINTS] = GL_POINTS; + draw_modes[GDM_LINE_STRIP] = GL_LINE_STRIP; + draw_modes[GDM_LINE_LOOP] = GL_LINE_LOOP; } int geom_find(const char* filename) diff --git a/src/game/geometry.h b/src/game/geometry.h index 6004212..bd87086 100755 --- a/src/game/geometry.h +++ b/src/game/geometry.h @@ -15,6 +15,8 @@ enum Geometry_Draw_Mode GDM_TRIANGLES = 0, GDM_LINES, GDM_POINTS, + GDM_LINE_STRIP, + GDM_LINE_LOOP, GDM_NUM_DRAWMODES }; diff --git a/src/game/im_render.c b/src/game/im_render.c index d57d3f7..8009ef2 100755 --- a/src/game/im_render.c +++ b/src/game/im_render.c @@ -10,13 +10,14 @@ #include #include +#include #define MAX_IM_VERTICES 2048 #define MAX_IM_GEOMETRIES (MAX_IM_VERTICES / 2) static struct { - struct IM_Vertex vertices[MAX_IM_VERTICES]; + struct IM_Vertex current_vertices[MAX_IM_VERTICES]; struct IM_Geom geometries[MAX_IM_GEOMETRIES]; uint vao; uint vbo; @@ -27,7 +28,7 @@ static struct IM_State; static struct IM_Geom* active_geom = NULL; -static int active_vertex_index = 0; +static int current_vertex_index = 0; static void im_geom_reset(struct IM_Geom* geom); static int im_sort_func(const void* p1, const void* p2); @@ -54,7 +55,7 @@ void im_init(void) glBindVertexArray(0); memset(&IM_State.geometries[0], 0, sizeof(struct IM_Geom) * MAX_IM_GEOMETRIES); - memset(&IM_State.vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); + memset(&IM_State.current_vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); IM_State.curr_geom = -1; IM_State.curr_vertex = 0; @@ -68,7 +69,7 @@ void im_cleanup(void) glDeleteVertexArrays(1, &IM_State.vao); memset(&IM_State.geometries[0], 0, sizeof(struct IM_Geom) * MAX_IM_GEOMETRIES); - memset(&IM_State.vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); + memset(&IM_State.current_vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); IM_State.vao = 0; IM_State.vbo = 0; IM_State.curr_geom = -1; @@ -103,9 +104,9 @@ void im_pos(float x, float y, float z) log_error("im_pos", "Buffer full!"); return; } - vec3_fill(&IM_State.vertices[active_vertex_index].position, x, y, z); + current_vertex_index++; + vec3_fill(&IM_State.current_vertices[current_vertex_index].position, x, y, z); IM_State.curr_vertex++; - active_vertex_index++; } void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order) @@ -152,27 +153,47 @@ void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_ active_geom = NULL; } -void im_line(vec3 p1, vec3 p2, vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode, int draw_order) +void im_line(vec3 p1, vec3 p2, vec3 position, quat rotation, vec3 scale, vec4 color, int draw_order) { - im_begin(position, rotation, scale, color, draw_mode, draw_order); + im_begin(position, rotation, scale, color, GDM_LINES, draw_order); im_pos(p1.x, p1.y, p1.z); im_pos(p2.x, p2.y, p2.z); im_end(); } +void im_circle(float radius, int num_divisions, vec3 position, quat rotation, vec4 color, int draw_order) +{ + im_arc(radius, 0.f, 360.f, num_divisions, position, rotation, color, draw_order); +} + +void im_arc(float radius, float angle_start, float angle_end, int num_divisions, vec3 position, quat rotation, vec4 color, int draw_order) +{ + im_begin(position, rotation, (vec3) { 1.f, 1.f, 1.f }, color, GDM_LINE_LOOP, draw_order); + float arc_degrees = angle_end - angle_start; + float increment = arc_degrees / num_divisions; + + if(arc_degrees != 360) + im_pos(0.f, 0.f, 0.f); + + for(float i = angle_start; i <= angle_end; i+= increment) + im_pos(sinf(i * M_PI / 180.f) * radius, cosf(i * M_PI / 180.f) * radius, 0.f); + + im_end(); +} + void im_end(void) { - active_geom->num_vertices = active_vertex_index + 1; + active_geom->num_vertices = current_vertex_index + 1; GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, IM_State.vbo)); GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER, sizeof(struct IM_Vertex) * active_geom->start_index, sizeof(struct IM_Vertex) * active_geom->num_vertices, - &IM_State.vertices[0])); + &IM_State.current_vertices[0])); glBindBuffer(GL_ARRAY_BUFFER, 0); active_geom = NULL; - active_vertex_index = 0; - memset(&IM_State.vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); + current_vertex_index = -1; + memset(&IM_State.current_vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); } void im_render(struct Camera* active_viewer) diff --git a/src/game/im_render.h b/src/game/im_render.h index 9770863..0991171 100755 --- a/src/game/im_render.h +++ b/src/game/im_render.h @@ -43,7 +43,9 @@ void im_begin(vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mod void im_pos(float x, float y, float z); void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order); void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order); -void im_line(vec3 p1, vec3 p2, vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode, int draw_order); +void im_line(vec3 p1, vec3 p2, vec3 position, quat rotation, vec3 scale, vec4 color, int draw_order); +void im_circle(float radius, int num_divisions, vec3 position, quat rotation, vec4 color, int draw_order); +void im_arc(float radius, float angle_start, float angle_end, int num_divisions, vec3 position, quat rotation, vec4 color, int draw_order); void im_end(void); void im_render(struct Camera* active_viewer); diff --git a/src/game/transform.c b/src/game/transform.c index dfb740c..03a68c1 100755 --- a/src/game/transform.c +++ b/src/game/transform.c @@ -96,7 +96,7 @@ void transform_rotate(struct Entity* entity, struct Transform* transform = &entity->transform; quat new_rot; quat_identity(&new_rot); - quat_axis_angle(&new_rot, axis, TO_RADIANS(angle)); + quat_axis_angle(&new_rot, axis, angle); if(space == TS_LOCAL) quat_mul(&transform->rotation, &transform->rotation, &new_rot); diff --git a/todo.txt b/todo.txt index 71cebfd..427af26 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,4 @@ Todo: - - Implement circle drawing with immediate mode renderer - - Implement arc drawing with renderer - Rotate mode tool widget - Complete rotate mode - Better, more accurate picking @@ -20,6 +18,8 @@ Todo: ? Improve bounding sphere calculation - Change the way lights are set as uniforms to remove snprintf calls per frame for every light attribute - Filter Scene heirarchy by search using entity name + - Command interface that allows applying commands to selected entity like r x 30 would rotate the selected entity or entities on x axis by 30 degrees + - Quick scene filter and entity selection by popping up a menu which has list of entities and fuzzy matches them based on the typed name - Screen mouse coordinates to world-coordinates for aiming - Player projectiles and sounds - Console commands @@ -247,4 +247,6 @@ Done: * Draw coloured axes lines at world origin or grid origin * Make axis lines always follow the same colour scheme for consistency across all tools, red for X axis, green for Y axis and blue for Z axis * Toggle between relative and static grid i.e, grid that moves along with the selected object or grid that remains stationary at the origin + * Implement circle drawing with immediate mode renderer + * Implement arc drawing with renderer