Browse Source

added 2 ways to tile textures

IverMartinson 5 months ago
parent
commit
852b39bd09

BIN
build/librasteriver.so


BIN
build/main.bin


+ 2 - 1
readme.md

@@ -55,4 +55,5 @@ To run the binary, it needs to be in the same folder as librasteriver.so (if you
 - [ ] normal map shading
 - [ ] bump maps
 - [ ] normal maps
-- [x] memory tracker
+- [x] memory tracker
+- [x] tileable textures

+ 4 - 0
src/headers/custom_types.h

@@ -60,6 +60,8 @@ typedef enum {
     RI_MATERIAL_DONT_DEPTH_TEST = ((uint64_t)1 << 8), // should check Z buffer (if 1, render on top of everything)
     RI_MATERIAL_DONT_DEPTH_WRITE = ((uint64_t)1 << 9), // should write to the Z buffer (if 1, render behind everything)
     RI_MATERIAL_DOUBLE_SIDED = ((uint64_t)1 << 10), // ignore backface culling
+    RI_MATERIAL_USE_UV_LOOP_MULTIPLIER = ((uint64_t)1 << 11), // use multiplier that tells how many times to loop the texture
+    RI_MATERIAL_USE_UV_RENDER_RESOLUTION = ((uint64_t)1 << 12), // use custom resolution that textures always appear as (scaling just tiles the texture)
 } RI_material_flags;
 
 typedef struct {
@@ -69,6 +71,8 @@ typedef struct {
     unsigned int albedo;
     double wireframe_width;
     uint64_t flags;
+    RI_vector_2f uv_loop_multiplier;
+    RI_vector_2f texture_render_size;
 } RI_material;
 
 typedef struct { // An entity that has an mesh, transform, materials, etc

+ 18 - 9
src/launch_program/main.c

@@ -4,7 +4,7 @@ int main(){
     // get RasterIver context
     RasterIver *ri = RI_get_ri();
 
-    ri->debug_memory = 1;
+    ri->debug_memory = 0;
 
     RI_init(1000, 1000, "This is RasterIver 2.0!!");
 
@@ -12,11 +12,11 @@ int main(){
 
     // data for loading files
     char *filenames[] = {"objects/unit_cube.obj", "objects/cow-nonormals.obj", "objects/test_guy.obj", "objects/unit_plane.obj"};
-    RI_texture_creation_data texture_creation_info[3] = {{"textures/bill_mcdinner.png", {0, 0}}, {"textures/this is the floor.png", {0, 0}}, {"textures/test_guy_texture.png", {0, 0}}};
+    RI_texture_creation_data texture_creation_info[4] = {{"textures/bill_mcdinner.png", {0, 0}}, {"textures/this is the floor.png", {0, 0}}, {"textures/test_guy_texture.png", {0, 0}}, {"textures/THIS IS THE WALL.png", {0, 0}}};
     
     // requesting assets
     RI_mesh* meshes = RI_request_meshes(4, filenames, 0);
-    RI_texture* textures = RI_request_textures(3, texture_creation_info);
+    RI_texture* textures = RI_request_textures(4, texture_creation_info);
     RI_material* materials = RI_request_materials(4);
     RI_actor* actors = RI_request_actors(4);
     RI_scene* scenes = RI_request_scenes(1);
@@ -30,16 +30,20 @@ int main(){
     // textures
     RI_texture* test_object_texture = &textures[0];
     RI_texture* floor_texture = &textures[1];
+    RI_texture* wall_texture = &textures[3];
 
     // materials
     RI_material* floor_material = &materials[0];
-    floor_material->flags = RI_MATERIAL_HAS_TEXTURE | RI_MATERIAL_DOUBLE_SIDED;
+    floor_material->flags = RI_MATERIAL_HAS_TEXTURE | RI_MATERIAL_DOUBLE_SIDED | RI_MATERIAL_USE_UV_LOOP_MULTIPLIER;
     floor_material->texture_reference = floor_texture;
     floor_material->albedo = 0xFFFFFFFF;
-    
+    floor_material->uv_loop_multiplier = (RI_vector_2f){25, 25};
+
     RI_material* wall_material = &materials[1];
-    wall_material->flags = RI_MATERIAL_DOUBLE_SIDED;
+    wall_material->flags = RI_MATERIAL_DOUBLE_SIDED | RI_MATERIAL_HAS_TEXTURE | RI_MATERIAL_USE_UV_RENDER_RESOLUTION;
     wall_material->albedo = 0xFF7777FF;
+    wall_material->texture_reference = wall_texture;
+    wall_material->texture_render_size = (RI_vector_2f){200, 400};
 
     RI_material* test_object_material = &materials[2];
     test_object_material->flags = RI_MATERIAL_HAS_TEXTURE;
@@ -86,6 +90,8 @@ int main(){
     scene->FOV = 1.5; // 90 degrees in radians
     scene->minimum_clip_distance = 0.1;
 
+    RI_euler_rotation_to_quaternion(&scene->camera_rotation, (RI_vector_3f){0, 0, 0});
+
     double y_rotation = 0;
 
     while (running){
@@ -93,11 +99,14 @@ int main(){
 
         RI_euler_rotation_to_quaternion(&screen->transform.rotation, (RI_vector_3f){-3.14159 / 2, 0, ri->frame * 0.03});
 
-        scene->camera_position = (RI_vector_3f){cos(ri->frame * 0.07) * 10 * sin(ri->frame * 0.2), sin(ri->frame * 0.07) * 10 * sin(ri->frame * 0.2), -300};
+        // scene->camera_position = (RI_vector_3f){cos(ri->frame * 0.07) * 10 * sin(ri->frame * 0.2), sin(ri->frame * 0.07) * 10 * sin(ri->frame * 0.2), -300};
         scene->camera_position = (RI_vector_3f){0, 0, -300};
-        scene->camera_rotation = (RI_vector_4f){0, 1, 0, 0};
+        
+        wall->transform.scale.x = fabs(sin(y_rotation)) * 100 + 70;
+
+        // RI_euler_rotation_to_quaternion(&scene->camera_rotation, (RI_vector_3f){0, y_rotation * .01 + 1.5, 0});
 
-        RI_euler_rotation_to_quaternion(&floor->transform.rotation, (RI_vector_3f){0, y_rotation, 0});
+        // RI_euler_rotation_to_quaternion(&floor->transform.rotation, (RI_vector_3f){0, y_rotation, 0});
         
         RI_euler_rotation_to_quaternion(&test_object->transform.rotation, (RI_vector_3f){y_rotation, y_rotation, y_rotation});
         // RI_euler_rotation_to_quaternion(&test_object->transform.rotation, (RI_vector_3f){0, y_rotation, 0});

+ 37 - 14
src/library/rasteriver.c

@@ -461,6 +461,15 @@ void RI_euler_rotation_to_quaternion(RI_vector_4f *quaternion, RI_vector_3f eule
     quaternion->z = cx * cy * sz - sx * sy * cz;
 }
 
+double mod(double a, double b){
+    if(b < 0.0)
+        return -mod(-a, -b);   
+    double ret = fmod(a, b);
+    if(ret < 0.0)
+        ret+=b;
+    return ret;
+}
+
 int RI_render(RI_scene *scene, RI_texture *target_texture){
     // do rendering stuff
     if (ri.running){
@@ -526,29 +535,30 @@ int RI_render(RI_scene *scene, RI_texture *target_texture){
                 vector_3f_hadamard(&cur_r_face->position_1, current_actor->transform.scale);
                 vector_3f_hadamard(&cur_r_face->position_2, current_actor->transform.scale);
 
-                // combine camera and object rotation
-                RI_vector_4f combined_rotation = current_actor->transform.rotation;
-                RI_vector_4f camera_rotation = scene->camera_rotation;
-
-                quaternion_conjugate(&camera_rotation);
-                
-                quaternion_multiply(&combined_rotation, camera_rotation);
-
-                // rotate
-                quaternion_rotate(&cur_r_face->position_0, combined_rotation);
-                quaternion_rotate(&cur_r_face->position_1, combined_rotation);
-                quaternion_rotate(&cur_r_face->position_2, combined_rotation);
+                // actor rotation
+                quaternion_rotate(&cur_r_face->position_0, current_actor->transform.rotation);
+                quaternion_rotate(&cur_r_face->position_1, current_actor->transform.rotation);
+                quaternion_rotate(&cur_r_face->position_2, current_actor->transform.rotation);
                 
                 // object position
                 vector_3f_element_wise_add(&cur_r_face->position_0, current_actor->transform.position);
                 vector_3f_element_wise_add(&cur_r_face->position_1, current_actor->transform.position);
                 vector_3f_element_wise_add(&cur_r_face->position_2, current_actor->transform.position);
-
-                // camera position
+                
+                // camera rotation
                 vector_3f_element_wise_subtract(&cur_r_face->position_0, scene->camera_position);
                 vector_3f_element_wise_subtract(&cur_r_face->position_1, scene->camera_position);
                 vector_3f_element_wise_subtract(&cur_r_face->position_2, scene->camera_position);
 
+                quaternion_rotate(&cur_r_face->position_0, scene->camera_rotation);
+                quaternion_rotate(&cur_r_face->position_1, scene->camera_rotation);
+                quaternion_rotate(&cur_r_face->position_2, scene->camera_rotation);
+                
+                // camera position
+                // vector_3f_element_wise_subtract(&cur_r_face->position_0, scene->camera_position);
+                // vector_3f_element_wise_subtract(&cur_r_face->position_1, scene->camera_position);
+                // vector_3f_element_wise_subtract(&cur_r_face->position_2, scene->camera_position);
+
                 RI_vector_3f *pos_0 = &cur_r_face->position_0;
                 RI_vector_3f *pos_1 = &cur_r_face->position_1;
                 RI_vector_3f *pos_2 = &cur_r_face->position_2;
@@ -868,6 +878,19 @@ int RI_render(RI_scene *scene, RI_texture *target_texture){
                         double ux = (w0 * (uv_0->x / pos_0->z) + w1 * (uv_1->x / pos_1->z) + w2 * (uv_2->x / pos_2->z)) / w_over_z;
                         double uy = (w0 * (uv_0->y / pos_0->z) + w1 * (uv_1->y / pos_1->z) + w2 * (uv_2->y / pos_2->z)) / w_over_z;                
                     
+                        if (mat->flags & RI_MATERIAL_USE_UV_LOOP_MULTIPLIER){
+                            ux *= mat->uv_loop_multiplier.x;
+                            uy *= mat->uv_loop_multiplier.y;
+                        }
+
+                        if (mat->flags & RI_MATERIAL_USE_UV_RENDER_RESOLUTION){
+                            ux *= mat->texture_reference->resolution.x / mat->texture_render_size.x;
+                            uy *= mat->texture_reference->resolution.y / mat->texture_render_size.y;
+                        }
+
+                        ux = mod(ux, 1.0);
+                        uy = mod(-uy, 1.0);
+
                         RI_vector_2 texel_position = {mat->texture_reference->resolution.x * ux, mat->texture_reference->resolution.y * uy};
                         
                         if (texel_position.y * mat->texture_reference->resolution.x + texel_position.x < 0 || texel_position.y * mat->texture_reference->resolution.x + texel_position.x >= mat->texture_reference->resolution.x * mat->texture_reference->resolution.y) 

BIN
textures/bill_mcdinner.png