static void rib_camera(FILE *o, Lib3dsFile *f, Lib3dsMatrix M) { Lib3dsNode *c; Lib3dsNode *t; const char *name=camera; ASSERT(f); if (!name) { if (f->cameras) { name=f->cameras->name; } } if (!name) { fprintf(stderr, "***ERROR*** No camera found!\n"); return; } c=lib3ds_file_node_by_name(f, name, LIB3DS_CAMERA_NODE); t=lib3ds_file_node_by_name(f, name, LIB3DS_TARGET_NODE); if (!c || !t) { fprintf(stderr, "***ERROR*** Invalid camera/target!\n"); return; } lib3ds_matrix_camera(M, c->data.camera.pos, t->data.target.pos, c->data.camera.roll); rib_concat_transform(o, M); fprintf(o, "Camera \"perspective\" \"float fov\" [%f]\n", c->data.camera.fov); }
/*! * */ static void display(void) { Lib3dsNode *c,*t; Lib3dsMatrix M; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (!file) { return; } c=lib3ds_file_node_by_name(file, camera, LIB3DS_CAMERA_NODE); t=lib3ds_file_node_by_name(file, camera, LIB3DS_TARGET_NODE); if (!c || !t) { return; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective( c->data.camera.fov, 1.0*gl_width/gl_height, 100.0, 20000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(-90, 1.0,0,0); { GLfloat lightPos[] = {0.0f, -1.0f, 0.0f, 0.0f}; glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glPushMatrix(); glTranslatef(0,-10,0); glutSolidTeapot(10.0); glPopMatrix(); } lib3ds_matrix_camera(M, c->data.camera.pos, t->data.target.pos, c->data.camera.roll); glMultMatrixf(&M[0][0]); { Lib3dsNode *p; for (p=file->nodes; p!=0; p=p->next) { render_node(p); } } if (!halt) { current_frame+=1.0; if (current_frame>file->frames) { current_frame=0; } lib3ds_file_eval(file, current_frame); glutSwapBuffers(); glutPostRedisplay(); } }
/*! * Main display function; called whenever the scene needs to be redrawn. */ static void display(void) { Lib3dsNode *c,*t; Lib3dsFloat fov, roll; float near, far, dist; float *campos; float *tgt; Lib3dsMatrix M; Lib3dsCamera *cam; Lib3dsVector v; Lib3dsNode *p; if( file != NULL && file->background.solid.use ) glClearColor(file->background.solid.col[0], file->background.solid.col[1], file->background.solid.col[2], 1.); /* TODO: fog */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if( anti_alias ) glEnable(GL_POLYGON_SMOOTH); else glDisable(GL_POLYGON_SMOOTH); if (!file) { return; } glLightModelfv(GL_LIGHT_MODEL_AMBIENT, file->ambient); c=lib3ds_file_node_by_name(file, camera, LIB3DS_CAMERA_NODE); t=lib3ds_file_node_by_name(file, camera, LIB3DS_TARGET_NODE); if( t != NULL ) tgt = t->data.target.pos; if( c != NULL ) { fov = c->data.camera.fov; roll = c->data.camera.roll; campos = c->data.camera.pos; } if ((cam = lib3ds_file_camera_by_name(file, camera)) == NULL) return; near = cam->near_range; far = cam->far_range; if (c == NULL || t == NULL) { if( c == NULL ) { fov = cam->fov; roll = cam->roll; campos = cam->position; } if( t == NULL ) tgt = cam->target; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* KLUDGE alert: OpenGL can't handle a near clip plane of zero, * so if the camera's near plane is zero, we give it a small number. * In addition, many .3ds files I've seen have a far plane that's * much too close and the model gets clipped away. I haven't found * a way to tell OpenGL not to clip the far plane, so we move it * further away. A factor of 10 seems to make all the models I've * seen visible. */ if( near <= 0. ) near = far * .001; gluPerspective( fov, 1.0*gl_width/gl_height, near, far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(-90, 1.0,0,0); /* User rotates the view about the target point */ lib3ds_vector_sub(v, tgt, campos); dist = lib3ds_vector_length(v); glTranslatef(0.,dist, 0.); glRotatef(view_rotx, 1., 0., 0.); glRotatef(view_roty, 0., 1., 0.); glRotatef(view_rotz, 0., 0., 1.); glTranslatef(0.,-dist, 0.); lib3ds_matrix_camera(M, campos, tgt, roll); glMultMatrixf(&M[0][0]); /* Lights. Set them from light nodes if possible. If not, use the * light objects directly. */ { static const GLfloat a[] = {0.0f, 0.0f, 0.0f, 1.0f}; static GLfloat c[] = {1.0f, 1.0f, 1.0f, 1.0f}; static GLfloat p[] = {0.0f, 0.0f, 0.0f, 1.0f}; Lib3dsLight *l; int li=GL_LIGHT0; for (l=file->lights; l; l=l->next) { glEnable(li); light_update(l); c[0] = l->color[0]; c[1] = l->color[1]; c[2] = l->color[2]; glLightfv(li, GL_AMBIENT, a); glLightfv(li, GL_DIFFUSE, c); glLightfv(li, GL_SPECULAR, c); p[0] = l->position[0]; p[1] = l->position[1]; p[2] = l->position[2]; glLightfv(li, GL_POSITION, p); if (l->spot_light) { p[0] = l->spot[0] - l->position[0]; p[1] = l->spot[1] - l->position[1]; p[2] = l->spot[2] - l->position[2]; glLightfv(li, GL_SPOT_DIRECTION, p); } ++li; } } if( show_object ) { for (p=file->nodes; p!=0; p=p->next) { render_node(p); } } if( show_bounds ) draw_bounds(tgt); if( show_cameras ) { for( cam = file->cameras; cam != NULL; cam = cam->next ) { lib3ds_matrix_camera(M, cam->position, cam->target, cam->roll); lib3ds_matrix_inv(M); glPushMatrix(); glMultMatrixf(&M[0][0]); glScalef(size/20, size/20, size/20); glCallList(cameraList); glPopMatrix(); } } if( show_lights ) { Lib3dsLight *light; for( light = file->lights; light != NULL; light = light->next ) draw_light(light->position, light->color); glMaterialfv(GL_FRONT, GL_EMISSION, black); } glutSwapBuffers(); }
void x3ds_instance::display() { assert(m_def != NULL); if (m_def->m_file == NULL) { return; } //update_material(); // save GL state glPushAttrib (GL_ALL_ATTRIB_BITS); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMatrixMode(GL_PROJECTION); glPushMatrix(); // apply gameSWF matrix rect bound; m_def->get_bound(&bound); matrix m = get_parent()->get_world_matrix(); m.transform(&bound); // get viewport size GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp); // int vp_width = vp[2]; int vp_height = vp[3]; bound.twips_to_pixels(); int w = (int) (bound.m_x_max - bound.m_x_min); int h = (int) (bound.m_y_max - bound.m_y_min); int x = (int) bound.m_x_min; int y = (int) bound.m_y_min; glViewport(x, vp_height - y - h, w, h); // set 3D params glClear(GL_DEPTH_BUFFER_BIT); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glCullFace(GL_BACK); glEnable(GL_POLYGON_SMOOTH); // glEnable(GL_BLEND); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); // set GL matrix to identity glMatrixMode(GL_PROJECTION); glLoadIdentity(); assert(m_camera); Lib3dsNode* cnode = lib3ds_file_node_by_name(m_def->m_file, m_camera->name, LIB3DS_CAMERA_NODE); Lib3dsNode* tnode = lib3ds_file_node_by_name(m_def->m_file, m_camera->name, LIB3DS_TARGET_NODE); float* target = tnode ? tnode->data.target.pos : m_camera->target; float view_angle; float roll; float* camera_pos; if (cnode) { view_angle = cnode->data.camera.fov; roll = cnode->data.camera.roll; camera_pos = cnode->data.camera.pos; } else { view_angle = m_camera->fov; roll = m_camera->roll; camera_pos = m_camera->position; } float ffar = m_camera->far_range; float nnear = m_camera->near_range <= 0 ? ffar * .001f : m_camera->near_range; float top = tan(view_angle * 0.5f) * nnear; float bottom = -top; float aspect = 1.3333f; // 4/3 == width /height float left = aspect* bottom; float right = aspect * top; // gluPerspective(fov, aspect, nnear, ffar) ==> glFrustum(left, right, bottom, top, nnear, ffar); // fov * 0.5 = arctan ((top-bottom)*0.5 / near) // Since bottom == -top for the symmetrical projection that gluPerspective() produces, then: // top = tan(fov * 0.5) * near // bottom = -top // Note: fov must be in radians for the above formulae to work with the C math library. // If you have comnputer your fov in degrees (as in the call to gluPerspective()), // then calculate top as follows: // top = tan(fov*3.14159/360.0) * near // The left and right parameters are simply functions of the top, bottom, and aspect: // left = aspect * bottom // right = aspect * top glFrustum(left, right, bottom, top, nnear, ffar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(-90., 1.0, 0., 0.); // apply camera matrix Lib3dsMatrix cmatrix; lib3ds_matrix_camera(cmatrix, camera_pos, target, roll); glMultMatrixf(&cmatrix[0][0]); // apply light set_light(); // draw 3D model for (Lib3dsNode* p = m_def->m_file->nodes; p != 0; p = p->next) { render_node(p); } // restore openGL state glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); }