void keyboard (unsigned char key, int x, int y) { vector *vec = camera_direction(-state.camera.pitch, state.camera.yaw, state.camera.roll); vector *move = malloc_vector(); copy_vector(move, vec); scale(vec, 10); rotate(move, 0, 90, 0); printf("pitch: %f, yaw: %f\n", state.camera.pitch, state.camera.yaw); switch(key) { case 'q': exit(0); break; case 'w': state.camera.x += vec->data[0]; state.camera.y += vec->data[1]; state.camera.z += vec->data[2]; break; case 'a': state.camera.x += 10*move->data[0]; state.camera.z += 10*move->data[2]; break; case 's': state.camera.x -= vec->data[0]; state.camera.y -= vec->data[1]; state.camera.z -= vec->data[2]; break; case 'd': state.camera.x -= 10*move->data[0]; state.camera.z -= 10*move->data[2]; break; case 'r': case 'R': if(state.filling) { glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); } else { glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); } state.filling = !state.filling; break; default: break; } free_vector(vec); printf("x: %f, y: %f, z: %f\n", state.camera.x, state.camera.y, state.camera.z); }
int main(int argc, char **argv) { #ifdef _WIN32 FILE* ctt = fopen("CON", "w" ); FILE* fout = freopen( "CON", "w", stdout ); FILE* ferr = freopen( "CON", "w", stderr ); #endif corange_init("../../assets_core"); graphics_viewport_set_title("Teapot"); graphics_viewport_set_size(1280, 720); camera* cam = entity_new("camera", camera); cam->position = vec3_new(5, 5, 5); cam->target = vec3_new(0, 0, 0); teapot_shader = asset_hndl_new_load(P("./assets/teapot.mat")); teapot_object = asset_hndl_new_load(P("./assets/teapot.obj")); int running = 1; SDL_Event e = {0}; while(running) { frame_begin(); camera* cam = entity_get("camera"); while(SDL_PollEvent(&e)) { switch(e.type){ case SDL_KEYDOWN: case SDL_KEYUP: if (e.key.keysym.sym == SDLK_ESCAPE) { running = 0; } if (e.key.keysym.sym == SDLK_PRINTSCREEN) { graphics_viewport_screenshot(); } if (e.key.keysym.sym == SDLK_r && e.key.keysym.mod == KMOD_LCTRL) { asset_reload_all(); } break; case SDL_QUIT: running = 0; break; } camera_control_orbit(cam, e); ui_event(e); } ui_update(); glClearColor(0.25, 0.25, 0.25, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); shader_program* shader = material_first_program(asset_hndl_ptr(&teapot_shader)); shader_program_enable(shader); shader_program_set_mat4(shader, "world", mat4_id()); shader_program_set_mat4(shader, "view", camera_view_matrix(cam)); shader_program_set_mat4(shader, "proj", camera_proj_matrix(cam)); shader_program_set_texture(shader, "cube_beach", 0, asset_hndl_new_load(P("$CORANGE/water/cube_sea.dds"))); shader_program_set_vec3(shader, "camera_direction", camera_direction(cam)); renderable* r = asset_hndl_ptr(&teapot_object); for(int i=0; i < r->num_surfaces; i++) { renderable_surface* s = r->surfaces[i]; int mentry_id = min(i, ((material*)asset_hndl_ptr(&r->material))->num_entries-1); material_entry* me = material_get_entry(asset_hndl_ptr(&r->material), mentry_id); glBindBuffer(GL_ARRAY_BUFFER, s->vertex_vbo); shader_program_enable_attribute(shader, "vPosition", 3, 18, (void*)0); shader_program_enable_attribute(shader, "vNormal", 3, 18, (void*)(sizeof(float) * 3)); //shader_program_enable_attribute(shader, "vTangent", 3, 18, (void*)(sizeof(float) * 6)); //shader_program_enable_attribute(shader, "vBinormal", 3, 18, (void*)(sizeof(float) * 9)); //shader_program_enable_attribute(shader, "vTexcoord", 2, 18, (void*)(sizeof(float) * 12)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->triangle_vbo); glDrawElements(GL_TRIANGLES, s->num_triangles * 3, GL_UNSIGNED_INT, (void*)0); shader_program_disable_attribute(shader, "vPosition"); shader_program_disable_attribute(shader, "vNormal"); //shader_program_disable_attribute(shader, "vTangent"); //shader_program_disable_attribute(shader, "vBinormal"); //shader_program_disable_attribute(shader, "vTexcoord"); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); } shader_program_disable(shader); glDisable(GL_DEPTH_TEST); ui_render(); graphics_swap(); frame_end(); } corange_finish(); return 0; }
Pix3D render(SIObj & objectIn, int volumeWidth, float focalDistance) { unsigned int S = 640 * 480; //image sizes for Pix3D are 640x480 float volW = (float)volumeWidth; //floating point version of volume width float hvw = volW * 0.5f; //half the volume width R3 lightPosition = R3(-1000.0f, 1000.0f, -1000.0f); float ambientLight = 100.0f; //init buffers for the Pix3D data bool * vd = new bool[S]; R3 * points = new R3[S]; Vec3b * colors = new Vec3b[S]; //camera focal ranges in angles //angle-y = 60.0f, angle-x = 45.0f float angleY = 60.0f, angleX = 40.0f; //half versions float hay = angleY * 0.5f; float hax = angleX * 0.5f; R3 cameraLocation(hvw, hvw, -focalDistance); //the location of the camera //define the projection plane dimensions float planeWidth = tan(hay * ll_R3_C::ll_R3_deg2rad) * focalDistance * 2.0f; float planeHeight = tan(hax * ll_R3_C::ll_R3_deg2rad) * focalDistance * 2.0f; float hpw = planeWidth * 0.5f; float hph = planeHeight * 0.5f; //define the top left corner of the projection plane R3 planeTopLeft = R3(hvw - hpw, hvw + hph, 0.0f); float rayXInc = planeWidth / 640.0f; float rayYInc = -planeHeight / 480.0f; //pre-compute some data used for ray-tracing //tris : the triangles //normals : the normal vectors for the triangles //c2ps : the vector from the camera to the center of the triangles //radiuses : the radius' of the bounding spheres for each triangle vector<SI_FullTriangle> tris; vector<R3> normals, C2Ps; vector<float> radiuses; R3 camera_direction(0.0f, 0.0f, -1.0f); for (int i = 0; i < objectIn._triangles.size(); i++) //for each triangle { SI_FullTriangle triangle = objectIn.getTriangle(i); R3 normal = triangle.normal(); float angle = acos(normal * camera_direction) * ll_R3_C::ll_R3_rad2deg; if (abs(angle) <= 90.0f) //perform back-face culling { R3 center = (triangle.a + triangle.b + triangle.c) * (1.0f / 3.0f); float radius = R3(center.dist(triangle.a), center.dist(triangle.b), center.dist(triangle.c)).max(); tris.push_back(triangle); normals.push_back(normal); C2Ps.push_back(center - cameraLocation); radiuses.push_back(radius); } } bool found = false, hit = false; R3 ray, ip; float d = 0.0f, bestDistance; R3 intersectionPoint, normal; int __index = 0; R3 q = planeTopLeft; for (int y = 0; y < 480; y++, q.y += rayYInc) { q.x = planeTopLeft.x; for (int x = 0; x < 640; x++, __index++, q.x += rayXInc) { ray = (q - cameraLocation).unit(); found = false; bestDistance = FLT_MAX; for (int j = 0; j < tris.size(); j++) { hit = false; //check if ray intersects bounding sphere //C2P is the vector from the camera to the center R3 C2P = C2Ps[j]; R3 projectedPoint = C2P.project(ray); if (projectedPoint.dist(C2P) > radiuses[j]) continue; SI_FullTriangle T = tris[j]; d = T.RayIntersectsTriangle(cameraLocation, ray, normals[j], ip, hit); if (hit) { if (d < bestDistance) { bestDistance = d; intersectionPoint = ip; normal = normals[j]; } found = true; } } if (found) { points[__index] = intersectionPoint; R3 lightNormal = (lightPosition - intersectionPoint).unit(); float angle = abs(acos(normal * lightNormal) * ll_R3_C::ll_R3_rad2deg); float _color = ambientLight; if (angle <= 90.0f) { float diffuse = 180.0f - angle; _color += diffuse / 180.0f * 150.0f; } _color = _color > 255.0f ? 255.0f : _color; colors[__index] = Vec3b((unsigned char)_color, (unsigned char)_color, (unsigned char)_color); } vd[__index] = found; } } Pix3D ret(S, points, colors, vd); delete [] points; delete [] colors; delete [] vd; return ret; }