Basic rendering working.
authorethereal <ethereal@ethv.net>
Wed, 24 Jun 2015 02:04:28 +0000 (02:04 +0000)
committerethereal <ethereal@ethv.net>
Wed, 24 Jun 2015 02:04:28 +0000 (02:04 +0000)
src/ecommon.h
src/ecore/render.c
src/ewrap/main.c

index 6b26346..f217cdc 100644 (file)
@@ -50,6 +50,11 @@ typedef struct __attribute__((packed)) {
     uint32_t msg[16];
 
     shm_cam_t cam;
+
+    float cam_basis_x[4];
+    float cam_basis_y[4];
+
+    float cam_origin[4];
 } shm_region_t;
 
 #endif
index 36899d7..3557e58 100644 (file)
@@ -1,6 +1,6 @@
 #include "ecore.h"
 #include "render.h"
-#include "math.h"
+#include "../vmath.h"
 
 uint32_t render_start, render_end;
 /*uint8_t __attribute__((section(".data_bank2"))) in_buffer[0x2000];*/
@@ -22,10 +22,11 @@ int sphere_intersect(shm_sph_t *sph, vector_t *ray, vector_t *dir,
     float *intersect) {
 
     vector_t pos;
-    set_vector(&pos, sph->x, sph->y, sph->z, 1.0);
+    set_vector(&pos, sph->x, sph->y, sph->z, 0.0);
+    sub_vectors(ray, &pos, &pos);
     
-    float b = 2*(dot_vectors(ray, dir));
-    float c = dot_vectors(ray, ray) - 1.0;
+    float b = 2*(dot_vectors(&pos, dir));
+    float c = dot_vectors(&pos, &pos) - sph->r*sph->r;
 
     float dis = b*b - 4*c;
     if(dis < 0) return 0;
@@ -40,9 +41,9 @@ int sphere_intersect(shm_sph_t *sph, vector_t *ray, vector_t *dir,
         i1 = i2; i2 = t;
     }
 
-    if(i1 < 1e-5) {
+    if(i1 < 1e-3) {
         // if it's only a glancing touch, ignore it
-        if(i2 <= 1e-5) return 0;
+        if(i2 <= 1e-3) return 0;
         *intersect = i2;
     }
     else *intersect = i1;
@@ -51,6 +52,7 @@ int sphere_intersect(shm_sph_t *sph, vector_t *ray, vector_t *dir,
 }
 
 int find_closest(vector_t *ray, vector_t *dir, float *min_i, int *min_ind) {
+    *min_ind = -1;
     for(int i = 0; i < buf_region->sph_count; i ++) {
         float intersect = 0;
         if(!sphere_intersect(spheres + i, ray, dir, &intersect)) continue;
@@ -69,6 +71,11 @@ vector_t trace(vector_t *ray, vector_t *dir, int depth) {
         ret.c[0] = ret.c[1] = ret.c[2] = ret.c[3] = 0.0;
         return ret;
     }
+    /*else {
+        vector_t ret;
+        ret.c[0] = ret.c[1] = ret.c[2] = ret.c[3] = 1.0;
+        return ret;
+    }*/
 
     /* We have an intersection. */
     vector_t intersection;
@@ -87,7 +94,7 @@ vector_t trace(vector_t *ray, vector_t *dir, int depth) {
 
     /* Do we need to do a recursive raycast? */
     vector_t ret;
-    ret.c[0] = ret.c[1] = ret.c[2] = ret.c[3] = 0.1;
+    ret.c[0] = ret.c[1] = ret.c[2] = ret.c[3] = 0.0;
     if(mat->ref > 0 && depth) {
         vector_t r;
         /* r = n*(2 * n.dot(-dir)) + dir */
@@ -110,7 +117,14 @@ vector_t trace(vector_t *ray, vector_t *dir, int depth) {
         ret.c[1] += lights[i].a * mat->a * mat->g * lights[i].g;
         ret.c[2] += lights[i].a * mat->a * mat->b * lights[i].b;
 
-        if(find_closest(&intersection, &ldir, &min_i, &min_ind)) continue;
+        vector_t itest;
+        mul_vector(&ldir, 1e-3, &itest);
+        add_vectors(&itest, &intersection, &itest);
+
+        min_i = 0; min_ind = -1;
+        if(find_closest(&itest, &ldir, &min_i, &min_ind) && min_i > 1e-3) {
+            continue;
+        }
 
         /* apply diffuse */
         float diffuse = dot_vectors(&ldir, &normal);
@@ -122,7 +136,6 @@ vector_t trace(vector_t *ray, vector_t *dir, int depth) {
         ret.c[2] += diffuse * mat->b * lights[i].b;
         
         /* apply specular */
-
         vector_t r;
         mul_vector(&normal, -2 * dot_vectors(&normal, &ldir), &r);
         add_vectors(&r, &ldir, &r);
@@ -138,9 +151,6 @@ vector_t trace(vector_t *ray, vector_t *dir, int depth) {
     if(ret.c[0] > 1) ret.c[0] = 1;
     if(ret.c[1] > 1) ret.c[1] = 1;
     if(ret.c[2] > 1) ret.c[2] = 1;
-    ret.c[0] = 1;
-    ret.c[1] = 1;
-    ret.c[2] = 1;
 
     return ret;
 }
@@ -153,9 +163,9 @@ void render_range() {
 
     vector_t cam_pos;
     set_vector(&cam_pos, buf_region->cam.x, buf_region->cam.y,
-        buf_region->cam.z, 1.0);
+        buf_region->cam.z, 0.0);
     vector_t cam_rot;
-    set_quaternion(&cam_rot, buf_region->cam.dx, buf_region->cam.dy,
+    set_vector(&cam_rot, buf_region->cam.dx, buf_region->cam.dy,
         buf_region->cam.dz, buf_region->cam.dw);
 
     /* Calculate camera plane origin. */
@@ -172,21 +182,37 @@ void render_range() {
     set_vector(&cam_basisy, 0.0, -1.0, 0.0, 0.0);
     rotate_vector(&cam_rot, &cam_basisy, &cam_basisy);
 
+    shm_region->cam_origin[0] = cam_plane.c[0];
+    shm_region->cam_origin[1] = cam_plane.c[1];
+    shm_region->cam_origin[2] = cam_plane.c[2];
+    shm_region->cam_origin[3] = cam_plane.c[3];
+    
+    shm_region->cam_basis_x[0] = cam_basisx.c[0];
+    shm_region->cam_basis_x[1] = cam_basisx.c[1];
+    shm_region->cam_basis_x[2] = cam_basisx.c[2];
+    shm_region->cam_basis_x[3] = cam_basisx.c[3];
+    shm_region->cam_basis_y[0] = cam_basisy.c[0];
+    shm_region->cam_basis_y[1] = cam_basisy.c[1];
+    shm_region->cam_basis_y[2] = cam_basisy.c[2];
+    shm_region->cam_basis_y[3] = cam_basisy.c[3];
+
+    unsigned ix = render_start % buf_region->width;
+    unsigned iy = render_start / buf_region->width;
+
     while(render_start != render_end) {
-        float x = (render_start % buf_region->width)
-            / (float)buf_region->width - 0.5;
-        float y = (render_start / buf_region->width)
-            / (float)buf_region->height - 0.5;
+        float x = (ix / (float)buf_region->width) - 0.5;
+        float y = (iy / (float)buf_region->height) - 0.5;
         
         /* Calculate ray direction. */
         vector_t ray_dir, temp;
         mul_vector(&cam_basisx, x, &ray_dir);
         mul_vector(&cam_basisy, y, &temp);
         add_vectors(&temp, &ray_dir, &ray_dir);
+        add_vectors(&ray_dir, &cam_plane, &ray_dir);
         norm_vector(&ray_dir);
 
         /* Begin trace */
-        vector_t col = trace(&cam_pos, &ray_dir, 1);
+        vector_t col = trace(&cam_pos, &ray_dir, 2);
 
         /* Write back result into framebuffer. */
         uint32_t result = 0;
@@ -197,5 +223,7 @@ void render_range() {
         write_render_result(result);
         /* Done, next pixel! */
         render_start ++;
+        ix ++;
+        if(ix >= buf_region->width) ix = 0, iy ++;
     }
 }
index e85bfd3..24cd3a4 100644 (file)
@@ -3,6 +3,10 @@
 #include <stdio.h>
 #include <math.h>
 
+#ifndef M_PI
+    #define M_PI 3.14159265358979323846
+#endif
+
 #include "e-hal.h"
 #include "e-loader.h"
 
@@ -56,13 +60,10 @@ int main() {
     // 
     while(shm_region->finished == 0) {}
     printf("Finished init! Filling data...\n");
-    shm_region->width = 0x40;
-    shm_region->height = 0x40;
+    shm_region->width = 0x100;
+    shm_region->height = 0x100;
     shm_region->fb_off = 0x200;
 
-    shm_region->light_count = 0;
-    shm_region->mat_count = 0;
-    shm_region->sph_count = 0;
 
     shm_region->data_end = 0x100;
 
@@ -72,20 +73,52 @@ int main() {
     shm_region->finished = 0;
     shm_region->generation = 1;
 
-    shm_mat_t *material = (void*)((uint8_t*)shm_region + sizeof(*shm_region));
-    material->r = material->g = material->b = 1.0;
+    shm_region->mat_count = 2;
+    shm_region->mat_off = sizeof(*shm_region);
+    shm_mat_t *material = (void*)((uint8_t*)shm_region + shm_region->mat_off);
+    material->r = 1.0;
+    material->g = material->b = 0.0;
+    material->shininess = 1.0;
+    material->sr = material->sg = material->sb = 1.0;
+    material->a = material->s = material->d = 1.0;
+    material ++;
+    material->r = material->b = 0.0;
+    material->g = 1.0;
     material->shininess = 1.0;
     material->sr = material->sg = material->sb = 1.0;
     material->a = material->s = material->d = 1.0;
 
-    shm_sph_t *sphere = (void *)((uint8_t*)shm_region + sizeof(*shm_region) + sizeof(*material));
-    sphere->x = 0.0;
+    shm_region->sph_count = 2;
+    shm_region->sph_off = shm_region->mat_off + sizeof(*material)*shm_region->mat_count;
+    shm_sph_t *sphere = (void *)((uint8_t*)shm_region + shm_region->sph_off);
+    sphere->x = 0.3;
     sphere->y = 0.0;
-    sphere->z = 0.0;
-    sphere->r = 10.0;
+    sphere->z = 1.1;
+    sphere->r = 0.3;
     sphere->mat = 0;
 
-    shm_region->data_end = (sizeof(*shm_region) + sizeof(*material) + sizeof(*sphere));
+    sphere ++;
+    sphere->x = -0.3;
+    sphere->y = 0.0;
+    sphere->z = 1.0;
+    sphere->r = 0.3;
+    sphere->mat = 1;
+
+    shm_region->light_count = 1;
+    shm_region->light_off = shm_region->sph_off + sizeof(*sphere)*shm_region->sph_count;
+    shm_light_t *light = (void *)((uint8_t*)shm_region + shm_region->light_off);
+    light->x = 0;
+    light->y = 0;
+    light->z = 0;
+    light->a = 0.3;
+    light->d = 1.0;
+    light->s = 0.0;
+    light->r = 1.0;
+    light->g = 1.0;
+    light->b = 1.0;
+
+    shm_region->data_end = shm_region->light_off + sizeof(*light)*shm_region->light_count;
+    printf("data_end: %lx\n", shm_region->data_end);
     /*
     const uint32_t in_buffer_address = 0x52e0;
     for(int i = 0; i < 100; i ++) {
@@ -101,12 +134,32 @@ int main() {
     printf("Waiting for rendering to finish...\n");
     while(shm_region->finished != 1) {}
     printf("Finished rendering!\n");
+    usleep(100000);
 
+    /*
     printf("fb: ");
     for(int i = 0; i < 0x1000; i ++) {
         printf("%lx ", *((uint32_t *)shm_region + 0x200/4 + i));
     }
     printf("\n");
+    */
+
+    printf("camera plane basis vectors: (%f,%f,%f,%f) and (%f,%f,%f,%f)\n",
+        shm_region->cam_basis_x[0], shm_region->cam_basis_x[1], shm_region->cam_basis_x[2], shm_region->cam_basis_x[3],
+        shm_region->cam_basis_y[0], shm_region->cam_basis_y[1], shm_region->cam_basis_y[2], shm_region->cam_basis_y[3]);
+    printf("camera plane origin: (%f,%f,%f,%f)\n",
+        shm_region->cam_origin[0], shm_region->cam_origin[1], shm_region->cam_origin[2], shm_region->cam_origin[3]);
+
+    FILE *fp = fopen("output.ppm", "w");
+    
+    fprintf(fp, "P3 %lu %lu 255\n", shm_region->width, shm_region->height);
+    for(int i = 0; i < shm_region->width * shm_region->height; i ++) {
+        uint32_t res = *((uint32_t *)shm_region + 0x200/4 + i);
+        fprintf(fp, "%lu %lu %lu  ", res & 0xfe, (res >> 8) & 0xff, (res >> 16) & 0xff);
+        if(((i+1) % shm_region->width) == 0) fprintf(fp, "\n");
+    }
+
+    fclose(fp);
 
     /*
     printf("in buffer content:");