erebus
changeset 19:6204e4d3f445
scene loading
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 27 May 2014 07:43:55 +0300 |
parents | 09028848f276 |
children | ea95b62dbc87 |
files | README.md liberebus/src/erebus.cc liberebus/src/scene.cc liberebus/src/scene.h src/main.cc test/scene |
diffstat | 6 files changed, 265 insertions(+), 34 deletions(-) [+] |
line diff
1.1 --- a/README.md Mon May 26 23:34:12 2014 +0300 1.2 +++ b/README.md Tue May 27 07:43:55 2014 +0300 1.3 @@ -4,7 +4,7 @@ 1.4 Copyright (C) 2014 John Tsiombikas <nuclear@member.fsf.org> 1.5 1.6 This program is released as free software, under the terms of the GNU General 1.7 -Public License v3, or at your option any later version, published by the Free 1.8 +Public License v3, or at your option, any later version published by the Free 1.9 Software Foundation. 1.10 1.11 **This program is in a very early stage of development. Don't bother trying it.**
2.1 --- a/liberebus/src/erebus.cc Mon May 26 23:34:12 2014 +0300 2.2 +++ b/liberebus/src/erebus.cc Tue May 27 07:43:55 2014 +0300 2.3 @@ -203,33 +203,9 @@ 2.4 delete ctx->scn; 2.5 ctx->scn = new Scene; 2.6 2.7 - // XXX for now just create a test scene here 2.8 - Sphere *sph = new Sphere; 2.9 - sph->mtl.set_attrib("diffuse", Color(1.0, 0.3, 0.2)); 2.10 - SceneNode *sph_node = new SceneNode(sph); 2.11 - ctx->scn->add_object(sph); 2.12 - ctx->scn->add_node(sph_node); 2.13 - 2.14 - Box *box = new Box; 2.15 - box->mtl.set_attrib("diffuse", Color(0.9, 0.8, 0.75)); 2.16 - SceneNode *box_node = new SceneNode(box); 2.17 - box_node->set_position(Vector3(0, -1.25, 0)); 2.18 - box_node->set_scaling(Vector3(5, 0.5, 5)); 2.19 - ctx->scn->add_object(box); 2.20 - ctx->scn->add_node(box_node); 2.21 - 2.22 - Sphere *lt = new Sphere; 2.23 - lt->mtl.set_attrib("emissive", Color(10, 10, 10)); 2.24 - SceneNode *lt_node = new SceneNode(lt); 2.25 - lt_node->set_position(Vector3(-15, 15, -10)); 2.26 - lt_node->set_scaling(Vector3(8, 8, 8)); 2.27 - ctx->scn->add_object(lt); 2.28 - ctx->scn->add_node(lt_node); 2.29 - 2.30 - TargetCamera *cam = new TargetCamera(Vector3(0, 4, -8), Vector3(0, 0, 0)); 2.31 - //ctx->scn->add_object(cam); 2.32 - ctx->scn->use_camera(cam); 2.33 - 2.34 + if(!ctx->scn->load(fname)) { 2.35 + return -1; 2.36 + } 2.37 return 0; 2.38 } 2.39 2.40 @@ -317,8 +293,8 @@ 2.41 Vector3 cpos = cam->get_position(); 2.42 float mag = cpos.length(); 2.43 2.44 - float theta = atan2(cpos.z / mag, cpos.x / mag) + DEG_TO_RAD(dx * 0.5); 2.45 - float phi = acos(cpos.y / mag) + DEG_TO_RAD(dy * 0.5); 2.46 + float theta = atan2(cpos.z / mag, cpos.x / mag) - DEG_TO_RAD(dx * 0.5); 2.47 + float phi = acos(cpos.y / mag) - DEG_TO_RAD(dy * 0.5); 2.48 2.49 if(phi < 0) phi = 0; 2.50 if(phi > M_PI) phi = M_PI;
3.1 --- a/liberebus/src/scene.cc Mon May 26 23:34:12 2014 +0300 3.2 +++ b/liberebus/src/scene.cc Tue May 27 07:43:55 2014 +0300 3.3 @@ -1,8 +1,14 @@ 3.4 +#include <stdio.h> 3.5 +#include <stdlib.h> 3.6 +#include <string.h> 3.7 #include "scene.h" 3.8 +#include "snode.h" 3.9 +#include "object.h" 3.10 +#include "geomobj.h" 3.11 3.12 // default enviromental parameters 3.13 Environment::Environment() 3.14 - : bgcolor(0.05, 0.05, 0.05), ambient(0.05, 0.05, 0.05) 3.15 + : bgcolor(0.01, 0.01, 0.01), ambient(0.01, 0.01, 0.01) 3.16 { 3.17 } 3.18 3.19 @@ -105,5 +111,232 @@ 3.20 3.21 bool Scene::load(const char *fname) 3.22 { 3.23 - return false; // TODO 3.24 + FILE *fp = fopen(fname, "r"); 3.25 + if(!fp) { 3.26 + fprintf(stderr, "failed to open scene file: %s\n", fname); 3.27 + return false; 3.28 + } 3.29 + 3.30 + bool res = load(fp); 3.31 + fclose(fp); 3.32 + return res; 3.33 } 3.34 + 3.35 +static char *strip_wspace(char *str) 3.36 +{ 3.37 + while(*str && isspace(*str)) str++; 3.38 + return str; 3.39 +} 3.40 + 3.41 +bool Scene::load(FILE *fp) 3.42 +{ 3.43 + char buf[256]; 3.44 + 3.45 + while(fgets(buf, sizeof buf, fp)) { 3.46 + char *line = strip_wspace(buf); 3.47 + if(!line || !*line || *line == '#') { 3.48 + continue; 3.49 + } 3.50 + 3.51 + std::vector<char*> cmd; 3.52 + 3.53 + char *tok = 0; 3.54 + while((tok = strtok(tok ? 0 : line, " \t\v\n\r"))) { 3.55 + printf("token: %s\n", tok); 3.56 + cmd.push_back(tok); 3.57 + } 3.58 + cmd.push_back(0); 3.59 + 3.60 + 3.61 + if(!proc_cmd((int)cmd.size() - 1, &cmd[0])) { 3.62 + return false; 3.63 + } 3.64 + } 3.65 + 3.66 + return true; 3.67 +} 3.68 + 3.69 +static int parse_vec(char **argv, float *vec) 3.70 +{ 3.71 + int nelem = 0; 3.72 + char *endp; 3.73 + 3.74 + for(int i=0; i<4; i++) { 3.75 + if(!argv[i]) break; 3.76 + 3.77 + vec[nelem] = strtod(argv[i], &endp); 3.78 + if(endp == argv[i]) { 3.79 + break; 3.80 + } 3.81 + nelem++; 3.82 + } 3.83 + return nelem; 3.84 +} 3.85 + 3.86 +static SceneNode *proc_object(Object *obj, int argc, char **argv) 3.87 +{ 3.88 + float vec[4]; 3.89 + SceneNode *node = new SceneNode(obj); 3.90 + GeomObject *gobj = (GeomObject*)obj; 3.91 + 3.92 + for(int i=1; i<argc; i++) { 3.93 + if(strcmp(argv[i], "-position") == 0) { 3.94 + int nelem = parse_vec(argv + i + 1, vec); 3.95 + if(nelem < 3) { 3.96 + fprintf(stderr, "-position must be followed by 3 numbers\n"); 3.97 + goto err; 3.98 + } 3.99 + node->set_position(Vector3(vec[0], vec[1], vec[2])); 3.100 + i += 3; 3.101 + 3.102 + } else if(strcmp(argv[i], "-rotation") == 0) { 3.103 + int nelem = parse_vec(argv + i + 1, vec); 3.104 + if(nelem < 4) { 3.105 + fprintf(stderr, "-rotation must be followed by axis vector and angle\n"); 3.106 + goto err; 3.107 + } 3.108 + node->set_rotation(Quaternion(Vector3(vec[0], vec[1], vec[2]), vec[3])); 3.109 + i += 4; 3.110 + 3.111 + } else if(strcmp(argv[i], "-scaling") == 0) { 3.112 + int nelem = parse_vec(argv + i + 1, vec); 3.113 + Vector3 s; 3.114 + if(nelem == 1) { 3.115 + s.x = s.y = s.z = vec[0]; 3.116 + } else if(nelem == 3) { 3.117 + s = Vector3(vec[0], vec[1], vec[2]); 3.118 + } else { 3.119 + fprintf(stderr, "-scaling must be followed by 1 or 3 numbers\n"); 3.120 + goto err; 3.121 + } 3.122 + node->set_scaling(s); 3.123 + i += nelem; 3.124 + 3.125 + } else if(strcmp(argv[i], "-diffuse") == 0) { 3.126 + int nelem = parse_vec(argv + i + 1, vec); 3.127 + if(nelem < 3) { 3.128 + fprintf(stderr, "-diffuse must be followed by a color (r g b)\n"); 3.129 + goto err; 3.130 + } 3.131 + gobj->mtl.set_attrib("diffuse", Color(vec[0], vec[1], vec[2])); 3.132 + i += 3; 3.133 + 3.134 + } else if(strcmp(argv[i], "-specular") == 0) { 3.135 + int nelem = parse_vec(argv + i + 1, vec); 3.136 + if(nelem < 3) { 3.137 + fprintf(stderr, "-specular must be followed by a color\n"); 3.138 + goto err; 3.139 + } 3.140 + gobj->mtl.set_attrib("specular", Color(vec[0], vec[1], vec[2])); 3.141 + i += 3; 3.142 + 3.143 + } else if(strcmp(argv[i], "-emissive") == 0) { 3.144 + int nelem = parse_vec(argv + i + 1, vec); 3.145 + Color emissive; 3.146 + if(nelem == 1) { 3.147 + emissive = Vector3(1, 1, 1); 3.148 + } else if(nelem == 3) { 3.149 + emissive = Vector3(vec[0], vec[1], vec[2]); 3.150 + } else { 3.151 + fprintf(stderr, "-emissive must be followed by an intensity or a color\n"); 3.152 + goto err; 3.153 + } 3.154 + i += nelem; 3.155 + gobj->mtl.set_attrib("emissive", emissive); 3.156 + 3.157 + } else { 3.158 + fprintf(stderr, "unrecognized %s option: %s\n", argv[0], argv[i]); 3.159 + goto err; 3.160 + } 3.161 + } 3.162 + 3.163 + return node; 3.164 +err: 3.165 + delete node; 3.166 + return 0; 3.167 +} 3.168 + 3.169 +static Camera *proc_camera(int argc, char **argv) 3.170 +{ 3.171 + float vec[4]; 3.172 + TargetCamera *cam = new TargetCamera; 3.173 + 3.174 + for(int i=1; i<argc; i++) { 3.175 + if(strcmp(argv[i], "-position") == 0) { 3.176 + int nelem = parse_vec(argv + i + 1, vec); 3.177 + if(nelem < 3) { 3.178 + fprintf(stderr, "-position must be followed by 3 numbers\n"); 3.179 + goto err; 3.180 + } 3.181 + cam->set_position(Vector3(vec[0], vec[1], vec[2])); 3.182 + i += 3; 3.183 + 3.184 + } else if(strcmp(argv[i], "-target") == 0) { 3.185 + int nelem = parse_vec(argv + i + 1, vec); 3.186 + if(nelem < 3) { 3.187 + fprintf(stderr, "-target must be followed by 3 numbers\n"); 3.188 + goto err; 3.189 + } 3.190 + cam->set_target(Vector3(vec[0], vec[1], vec[2])); 3.191 + i += 3; 3.192 + 3.193 + } else if(strcmp(argv[i], "-fov") == 0) { 3.194 + int nelem = parse_vec(argv + i + 1, vec); 3.195 + if(nelem < 1) { 3.196 + fprintf(stderr, "-fov must be followed by the field of view in degrees\n"); 3.197 + goto err; 3.198 + } 3.199 + cam->set_fov(vec[0]); 3.200 + i += 1; 3.201 + 3.202 + } else { 3.203 + fprintf(stderr, "unrecognized camera option: %s\n", argv[i]); 3.204 + goto err; 3.205 + } 3.206 + } 3.207 + return cam; 3.208 + 3.209 +err: 3.210 + delete cam; 3.211 + return 0; 3.212 +} 3.213 + 3.214 +bool Scene::proc_cmd(int argc, char **argv) 3.215 +{ 3.216 + Object *obj = 0; 3.217 + SceneNode *node = 0; 3.218 + 3.219 + if(strcmp(argv[0], "sphere") == 0) { 3.220 + obj = new Sphere; 3.221 + node = proc_object(obj, argc, argv); 3.222 + 3.223 + } else if(strcmp(argv[0], "box") == 0) { 3.224 + obj = new Box; 3.225 + node = proc_object(obj, argc, argv); 3.226 + 3.227 + } else if(strcmp(argv[0], "mesh") == 0) { 3.228 + fprintf(stderr, "meshes not implemented yet\n"); 3.229 + return false; 3.230 + 3.231 + } else if(strcmp(argv[0], "camera") == 0) { 3.232 + Camera *cam = proc_camera(argc, argv); 3.233 + if(!cam) { 3.234 + return false; 3.235 + } 3.236 + use_camera(cam); 3.237 + 3.238 + } else { 3.239 + fprintf(stderr, "unknown command: %s\n", argv[0]); 3.240 + return false; 3.241 + } 3.242 + 3.243 + if(obj) { 3.244 + if(!node) { 3.245 + return false; 3.246 + } 3.247 + add_object(obj); 3.248 + add_node(node); 3.249 + } 3.250 + 3.251 + return true; 3.252 +}
4.1 --- a/liberebus/src/scene.h Mon May 26 23:34:12 2014 +0300 4.2 +++ b/liberebus/src/scene.h Tue May 27 07:43:55 2014 +0300 4.3 @@ -1,6 +1,7 @@ 4.4 #ifndef SCENE_H_ 4.5 #define SCENE_H_ 4.6 4.7 +#include <stdio.h> 4.8 #include <vector> 4.9 #include "snode.h" 4.10 #include "camera.h" 4.11 @@ -52,6 +53,9 @@ 4.12 bool intersect(const Ray &ray, RayHit *hit) const; 4.13 4.14 bool load(const char *fname); 4.15 + bool load(FILE *fp); 4.16 + 4.17 + bool proc_cmd(int argc, char **argv); 4.18 }; 4.19 4.20 #endif // SCENE_H_
5.1 --- a/src/main.cc Mon May 26 23:34:12 2014 +0300 5.2 +++ b/src/main.cc Tue May 27 07:43:55 2014 +0300 5.3 @@ -1,6 +1,7 @@ 5.4 #include <stdio.h> 5.5 #include <stdlib.h> 5.6 #include <assert.h> 5.7 +#include <vector> 5.8 #include "opengl.h" 5.9 #include "erebus.h" 5.10 5.11 @@ -25,11 +26,17 @@ 5.12 static erebus *erb; 5.13 static bool render_pending; 5.14 5.15 +static std::vector<char*> sfiles; 5.16 5.17 int main(int argc, char **argv) 5.18 { 5.19 glutInitWindowSize(1024, 600); 5.20 glutInit(&argc, argv); 5.21 + 5.22 + for(int i=1; i<argc; i++) { 5.23 + sfiles.push_back(argv[i]); 5.24 + } 5.25 + 5.26 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 5.27 glutCreateWindow("erebus OpenGL frontend"); 5.28 5.29 @@ -61,8 +68,11 @@ 5.30 erb_setopti(erb, ERB_OPT_WIDTH, width); 5.31 erb_setopti(erb, ERB_OPT_HEIGHT, height); 5.32 5.33 - if(erb_load_scene(erb, "scene") == -1) { 5.34 - return false; 5.35 + for(size_t i=0; i<sfiles.size(); i++) { 5.36 + printf("loading scene file: %s\n", sfiles[i]); 5.37 + if(erb_load_scene(erb, sfiles[i]) == -1) { 5.38 + return false; 5.39 + } 5.40 } 5.41 5.42 printf("begin rendering\n");
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/scene Tue May 27 07:43:55 2014 +0300 6.3 @@ -0,0 +1,8 @@ 6.4 +# test scene 6.5 + 6.6 +sphere -position 0 0 0 -scaling 1 1 1 -diffuse 1 0.5 0.4 6.7 +box -position 0 -1.25 0 -scaling 4 0.5 4 -diffuse 0.3 0.4 1.0 6.8 + 6.9 +box -position 0 5 0 -scaling 3 0.1 3 -emissive 4 4 4 6.10 + 6.11 +camera -position 0 3 -6 -target 0 0 0