void draw3DSNode(Lib3dsNode *node) { Lib3dsNode *n; for(n=node->childs;n!=NULL;n=n->next) draw3DSNode(n); if(node->type==LIB3DS_OBJECT_NODE) { int i; Lib3dsMesh *mesh=NULL; Lib3dsVector *normals=NULL; Lib3dsMatrix M; if(strcmp(node->name,"$$$DUMMY")==0) return; mesh=lib3ds_file_mesh_by_name(file,node->name); if(!mesh) return; /* apply mesh transformation */ lib3ds_matrix_copy(M,mesh->matrix); lib3ds_matrix_inv(M); glMultMatrixf(&M[0][0]); /* calculate normals */ normals=malloc(3*sizeof(Lib3dsVector)*mesh->faces); lib3ds_mesh_calculate_normals(mesh,normals); for(i=0;i<mesh->faces;i++) { Lib3dsFace *face=&mesh->faceL[i]; Lib3dsMaterial *mat=NULL; /* materials */ if(face->material[0]) mat=lib3ds_file_material_by_name(file,face->material); if(mat) { float shine; glMaterialfv(GL_FRONT,GL_AMBIENT,mat->ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat->diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat->specular); shine=pow(2.0,10.0*mat->shininess); if(shine>128.0) shine=128.0; glMaterialf(GL_FRONT,GL_SHININESS,shine); } else { static GLfloat amb[4]={0.2,0.2,0.2,1.0}; static GLfloat diff[4]={0.8,0.8,0.8,1.0}; static GLfloat spec[4]={0.0,0.0,0.0,1.0}; glMaterialfv(GL_FRONT,GL_AMBIENT,amb); glMaterialfv(GL_FRONT,GL_DIFFUSE,diff); glMaterialfv(GL_FRONT,GL_SPECULAR,spec); } /* vertices */ srelBegin(GL_TRIANGLES); srelNormal3fv(normals[3*i]); srelVertex3fv(mesh->pointL[face->points[0]].pos); srelNormal3fv(normals[3*i+1]); srelVertex3fv(mesh->pointL[face->points[1]].pos); srelNormal3fv(normals[3*i+2]); srelVertex3fv(mesh->pointL[face->points[2]].pos); srelEnd(); } free(normals); } }
// what is basicly does is, set the properties of the texture for our mesh void Model::ApplyTexture(Lib3dsMesh *mesh) { for(unsigned int i = 0;i < mesh->faces;i++) { Lib3dsFace *f = &mesh->faceL[i]; if(! f->material[0]) continue; GLbyte *pBytes; GLint iWidth, iHeight, iComponents; GLenum eFormat; Lib3dsMaterial *mat; bool found = false; mat = lib3ds_file_material_by_name(file, f->material); for(unsigned int i = 0;i < textureFilenames.size();i++) { if(strcmp(mat->texture1_map.name, textureFilenames.at(i).c_str()) == 0) { textureIndices.push_back(textureIndices.at(i)); textureFilenames.push_back(mat->texture1_map.name); found = true; break; } } if(!found) { textureFilenames.push_back(mat->texture1_map.name); string tempfilename; tempfilename.append(mat->texture1_map.name); //tempfilename.append(".tga"); pBytes = gltLoadTGA(tempfilename.c_str(), &iWidth, &iHeight, &iComponents, &eFormat); //glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes); //gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes); if(!pBytes) { cout << "3DS error" << endl; cout << "Error loading 3ds texture, perhaps file format not supported? "<< tempfilename << endl; exit(1); } //img = QGLWidget::convertToGLFormat(img); GLuint tmpIndex; // temporary index to old the place of our texture glGenTextures(1, &tmpIndex); // allocate memory for one texture textureIndices.push_back(tmpIndex); // add the index of our newly created texture to textureIndices glBindTexture(GL_TEXTURE_2D, tmpIndex); // use our newest texture //gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, img.width() , img.height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); // genereate MipMap levels for our texture //gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes); glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // give the best result for texture magnification glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //give the best result for texture minification glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // don't repeat texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // don't repeat texture } } }
// what is basicly does is, set the properties of the texture for our mesh void Model::ApplyTexture(Lib3dsMesh *mesh) { for(unsigned int i = 0;i < mesh->faces;i++) { Lib3dsFace *f = &mesh->faceL[i]; if(! f->material[0] ) continue; int x,y,n; Lib3dsMaterial *mat; bool found = false; mat = lib3ds_file_material_by_name(file, f->material); for(unsigned int j = 0;j < textureFilenames.size();j++) { if(strcmp(mat->texture1_map.name, textureFilenames.at(j).c_str()) == 0) { assert(j < textureIndices.size()); textureIndices.push_back(textureIndices.at(j)); textureFilenames.push_back(mat->texture1_map.name); found = true; break; } } if(!found) { unsigned char *data = stbi_load(mat->texture1_map.name, &x, &y, &n, 0); if(!data) { textureIndices.push_back(-1); textureFilenames.push_back(mat->texture1_map.name); continue; } GLuint tmpIndex; // temporary index to old the place of our texture glGenTextures(1,&tmpIndex); // allocate memory for one texture textureIndices.push_back(tmpIndex); // add the index of our newly created texture to textureIndices textureFilenames.push_back(mat->texture1_map.name); printf("Binded %d to %s, %dx%d.\n",tmpIndex,mat->texture1_map.name,x,y); glBindTexture(GL_TEXTURE_2D, tmpIndex); // use our newest texture gluBuild2DMipmaps(GL_TEXTURE_2D, 3, x, y, GL_RGB, GL_UNSIGNED_BYTE, data); // genereate MipMap levels for our texture #if 0 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // give the best result for texture magnification glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //give the best result for texture minification glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // don't repeat texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // don't repeat texture #endif stbi_image_free(data); } } }
void x3ds_instance::create_mesh_list(Lib3dsMesh* mesh) { Lib3dsVector* normalL = (Lib3dsVector*) malloc(3 * sizeof(Lib3dsVector) * mesh->faces); Lib3dsMatrix m; lib3ds_matrix_copy(m, mesh->matrix); lib3ds_matrix_inv(m); glMultMatrixf(&m[0][0]); lib3ds_mesh_calculate_normals(mesh, normalL); Lib3dsMaterial* prev_mat = NULL; for (Uint32 p = 0; p < mesh->faces; ++p) { Lib3dsFace* f = &mesh->faceL[p]; Lib3dsMaterial* mat = f->material[0] ? lib3ds_file_material_by_name(m_def->m_file, f->material) : NULL; if (prev_mat != mat) { set_material(mat); } glBegin(GL_TRIANGLES); glNormal3fv(f->normal); for (int i = 0; i < 3; ++i) { glNormal3fv(normalL[3 * p + i]); if (mesh->texelL) { bind_material(mat, mesh->texelL[f->points[i]][1], mesh->texelL[f->points[i]][0]); } glVertex3fv(mesh->pointL[f->points[i]].pos); } glEnd(); glDisable(GL_TEXTURE_2D); } free(normalL); }
static void face_array_read(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io) { Lib3dsChunk c; uint16_t chunk; int i; uint16_t nfaces; lib3ds_chunk_read_start(&c, CHK_FACE_ARRAY, io); lib3ds_mesh_resize_faces(mesh, 0); nfaces = lib3ds_io_read_word(io); if (nfaces) { lib3ds_mesh_resize_faces(mesh, nfaces); for (i = 0; i < nfaces; ++i) { mesh->faces[i].index[0] = lib3ds_io_read_word(io); mesh->faces[i].index[1] = lib3ds_io_read_word(io); mesh->faces[i].index[2] = lib3ds_io_read_word(io); mesh->faces[i].flags = lib3ds_io_read_word(io); } lib3ds_chunk_read_tell(&c, io); while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { switch (chunk) { case CHK_MSH_MAT_GROUP: { char name[64]; unsigned n; unsigned i; int index; int material; lib3ds_io_read_string(io, name, 64); material = lib3ds_file_material_by_name(file, name); n = lib3ds_io_read_word(io); for (i = 0; i < n; ++i) { index = lib3ds_io_read_word(io); if (index < mesh->nfaces) { mesh->faces[index].material = material; } else { // TODO warning } } break; } case CHK_SMOOTH_GROUP: { int i; for (i = 0; i < mesh->nfaces; ++i) { mesh->faces[i].smoothing_group = lib3ds_io_read_dword(io); } break; } case CHK_MSH_BOXMAP: { lib3ds_io_read_string(io, mesh->box_front, 64); lib3ds_io_read_string(io, mesh->box_back, 64); lib3ds_io_read_string(io, mesh->box_left, 64); lib3ds_io_read_string(io, mesh->box_right, 64); lib3ds_io_read_string(io, mesh->box_top, 64); lib3ds_io_read_string(io, mesh->box_bottom, 64); break; } default: lib3ds_chunk_unknown(chunk,io); } } } lib3ds_chunk_read_end(&c, io); }
static void create_node(Lib3dsFile *f, Lib3dsNode *node, FILE *o) { Lib3dsMesh *mesh; if ((node->type==LIB3DS_OBJECT_NODE) && (strcmp(node->name,"$$$DUMMY")!=0)) { mesh=lib3ds_file_mesh_by_name(f, node->name); ASSERT(mesh); if (mesh) { Lib3dsObjectData *d=&node->data.object; fprintf(o, "\n\n##\n## Object: %s\n##\n", node->name); fprintf(o, "AttributeBegin\n"); { Lib3dsMatrix N,M,X; lib3ds_matrix_copy(N, node->matrix); lib3ds_matrix_translate_xyz(N, -d->pivot[0], -d->pivot[1], -d->pivot[2]); lib3ds_matrix_copy(M, mesh->matrix); lib3ds_matrix_inv(M); lib3ds_matrix_mul(X,N,M); rib_concat_transform(o, X); } { unsigned p; int i, j; Lib3dsVector *normalL=malloc(3*sizeof(Lib3dsVector)*mesh->faces); lib3ds_mesh_calculate_normals(mesh, normalL); Lib3dsMaterial *lastmat = NULL; int nalloc = 256, nfaces = 0; float *P = (float *)malloc(nalloc*9*sizeof(float)); float *N = (float *)malloc(nalloc*9*sizeof(float)); float *uv = (float *)malloc(nalloc*6*sizeof(float)); for (p=0; p<mesh->faces; ++p) { Lib3dsFace *face=&mesh->faceL[p]; Lib3dsMaterial *mat=lib3ds_file_material_by_name(f, face->material); if (mat && mat != lastmat) { char *Kdmap = NULL, *Omap = NULL; flushpp(o, P, N, uv, nfaces); nfaces = 0; lastmat = mat; if (mat->texture1_map.name[0]) { Kdmap = GetTexture(o, mat->texture1_map.name, mat->texture1_mask.name, 0); char *scale = malloc(strlen(Kdmap)+20); strcpy(scale, Kdmap); strcat(scale, "-scale"); fprintf(o, "Texture \"%s\" \"color\" \"scale\" \"texture tex1\" \"%s\" " "\"color tex2\" [.8 .8 .8]\n", scale, Kdmap); Kdmap = scale; } if (mat->opacity_map.name[0]) Omap = GetTexture(o, mat->opacity_map.name, mat->opacity_mask.name, 0); char *bumpScale = NULL; if (mat->bump_map.name[0]) { char *Bmap = GetTexture(o, mat->bump_map.name, mat->bump_mask.name, 1); bumpScale = malloc(strlen(Bmap)+20); strcpy(bumpScale, Bmap); strcat(bumpScale, "-scale"); fprintf(o, "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" \"%s\" " "\"float tex2\" [.05]\n", bumpScale, Bmap); } fprintf(o, "Material \"uber\" "); if (Kdmap) fprintf(o, "\"texture Kd\" \"%s\" ", Kdmap); else fprintf(o, "\"color Kd\" [%f %f %f] ", mat->diffuse[0], mat->diffuse[1], mat->diffuse[2]); if (Omap) fprintf(o, "\"texture opacity\" \"%s\" ", Omap); else fprintf(o, "\"color opacity\" [%f %f %f] ", 1.f - mat->transparency, 1.f - mat->transparency, 1.f - mat->transparency); fprintf(o, "\"color Ks\" [%f %f %f] " "\"float roughness\" [%f] ", mat->specular[0]*mat->shin_strength, mat->specular[1]*mat->shin_strength, mat->specular[2]*mat->shin_strength, mat->shininess ); //CO dumptex(o, "tex2", &mat->texture2_map); //CO dumptex(o, "tex2mask", &mat->texture2_mask); //CO dumptex(o, "specular", &mat->specular_map); //CO dumptex(o, "specularmask", &mat->specular_mask); //CO dumptex(o, "shininess", &mat->shininess_map); //CO dumptex(o, "shininessmask", &mat->shininess_mask); //CO dumptex(o, "reflection", &mat->reflection_map); //CO dumptex(o, "reflectionmask", &mat->reflection_mask); fprintf(o, "\n"); if (bumpScale) fprintf(o, "\"float bumpmap\" \"%s\"\n", bumpScale); } if (nfaces+1 == nalloc) { nalloc *= 2; P = (float *)realloc(P, nalloc*9*sizeof(float)); N = (float *)realloc(N, nalloc*9*sizeof(float)); uv = (float *)realloc(uv, nalloc*6*sizeof(float)); } for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { P[9*nfaces+3*i+j] = mesh->pointL[face->points[i]].pos[j]; N[9*nfaces+3*i+j] = normalL[3*p+i][j]; if (j != 2 && mesh->texelL) uv[6*nfaces+2*i+j] = mesh->texelL[face->points[i]][j]; } if (!mesh->texelL) { uv[6*nfaces+0] = 0; uv[6*nfaces+1] = 0; uv[6*nfaces+2] = 0; uv[6*nfaces+3] = 1; uv[6*nfaces+4] = 1; uv[6*nfaces+5] = 0; } } ++nfaces; } flushpp(o, P, N, uv, nfaces); free(P); free(N); free(uv); free(normalL); } nTextures = 0; fprintf(o, "AttributeEnd\n"); } } { Lib3dsNode *n; for (n=node->childs; n; n=n->next) { create_node(f,n,o); } } }
TextureInformation Loader3dsInternal::loadTextureInformation(Lib3dsNode* node) { if (!node) { return TextureInformation(); } if (node->type != LIB3DS_OBJECT_NODE) { return TextureInformation(); } if (strcmp(node->name, "$$$DUMMY") == 0) { // AB: nodes with this name are only transformation nodes, i.e. they // don't have a mesh, only a matrix. return TextureInformation(); } Lib3dsMesh* mesh = lib3ds_file_mesh_by_name(mFile, node->name); if (!mesh) { std::cout << "Cannot find mesh " << node->name << " in 3ds file" << std::endl; return TextureInformation(); } if (mesh->faces < 1) { std::cerr << "No faces in mesh " << node->name << std::endl; return TextureInformation(); } if (mesh->texelL == 0) { // mesh not textured. return TextureInformation(); } if (mesh->texels != mesh->points) { std::cerr << "ERROR: mesh->texels != mesh->points, with non-NULL mesh->texelL" << std::endl; return TextureInformation(); } if (mesh->faceL[0].material[0] == 0) { return TextureInformation(); } // AB: at this point we assume that the mesh uses a single material // only. see checkUniqueMeshMaterial() Lib3dsMaterial* mat = lib3ds_file_material_by_name(mFile, mesh->faceL[0].material); TextureInformation textureInformation; textureInformation.setTextured(true); std::vector<dcollide::Vector3> texels; texels.reserve(mesh->texels); dcollide::Matrix textureMatrix; Lib3dsTextureMap* t = &mat->texture1_map; if (t->scale[0] && t->scale[1]) { // AB: see boson's bobmfloader/loaders/loader-3ds.cpp for details // (remark: yes, I have permission to relicense to BSD!) textureMatrix.translate((dcollide::real)((1.0 - t->scale[0]) / 2.0), (dcollide::real)((1.0 - t->scale[1]) / 2.0), (dcollide::real) 0.0); textureMatrix.scale(t->scale[0], t->scale[1], 1.0); } if (t->rotation != 0.0) { textureMatrix.rotate(-t->rotation, 0.0, 0.0, 1.0); } textureMatrix.translate(-t->offset[0], -t->offset[1], 0.0); textureMatrix.translate(mesh->map_data.pos[0], mesh->map_data.pos[1], mesh->map_data.pos[2]); float scale = mesh->map_data.scale; if (scale != 0.0) { textureMatrix.scale(scale, scale, 1.0); } dcollide::Vector3 tmp1; dcollide::Vector3 tmp2; for (unsigned int i = 0; i < mesh->texels; i++) { tmp1.set((dcollide::real)(mesh->texelL[i])[0], (dcollide::real)(mesh->texelL[i])[1], (dcollide::real)0.0); textureMatrix.transform(&tmp2, tmp1); texels.push_back(tmp2); } textureInformation.setTexels(texels); textureInformation.setTextureFileName(mat->texture1_map.name); return textureInformation; }
// this code is rewritten from player.c example that came with lib3ds // what it does is render a node from our model void Model::renderNode(Lib3dsNode *node) { ASSERT(file); //this is for debugging { Lib3dsNode *tmp; for(tmp = node->childs;tmp != 0;tmp = tmp->next) renderNode(tmp); //render all child nodes of this note } if(node->type == LIB3DS_OBJECT_NODE) //check wheter the node is a 3ds node { if(! node->user.d) //Wheter we have a list or not, if not we're gonna create one { Lib3dsMesh *mesh = lib3ds_file_mesh_by_name(file, node->name); //get all the meshes of the current node ASSERT(mesh); //for debugging in case we don't have a mesh if(! mesh) return; node->user.d = glGenLists(1); //alocate memory for one list ///////////////////////////////////////////////////////////// if(glGetError() != GL_NO_ERROR) { cout << "ERROR!\n"; exit(0); } ///////////////////////////////////////////////////////////// glNewList(node->user.d, GL_COMPILE); //here we create our list { unsigned p; Lib3dsVector *normals; normals = static_cast<float(*)[3]> (std::malloc (3*sizeof(Lib3dsVector)*mesh->faces)); //alocate memory for our normals { Lib3dsMatrix m; lib3ds_matrix_copy(m, mesh->matrix); //copy the matrix of the mesh in our temporary matrix lib3ds_matrix_inv(m); glMultMatrixf(&m[0][0]); //adjust our current matrix to the matrix of the mesh } lib3ds_mesh_calculate_normals(mesh, normals); //calculate the normals of the mesh int j = 0; for(p = 0;p < mesh->faces;p++) { Lib3dsFace *f = &mesh->faceL[p]; Lib3dsMaterial *mat=0; if(f->material[0]) //if the face of the mesh has material properties mat = lib3ds_file_material_by_name(file, f->material); //read material properties from file if(mat) //if we have material { static GLfloat ambient[4] = { 0.0, 0.0, 0.0, 1.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); // Ambient color glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); //diffuse color glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); //specular color float shine; shine = pow(2, 10.0 * mat->shininess); if(shine > 128.0) shine = 128.0; glMaterialf(GL_FRONT, GL_SHININESS, shine); } else // if we do not have material properties, we have to set them manually { GLfloat diff[4] = { 0.75, 0.75, 0.75, 1.0 }; // color: white/grey GLfloat amb[4] = { 0.25, 0.25, 0.25, 1.0 }; //color: black/dark gray GLfloat spec[4] = { 0.0, 0.0, 0.0, 1.0 }; //color: completly black glMaterialfv(GL_FRONT, GL_DIFFUSE, diff); glMaterialfv(GL_FRONT, GL_AMBIENT, amb); glMaterialfv(GL_FRONT, GL_AMBIENT, spec); } { if(mesh->texels) { glBindTexture(GL_TEXTURE_2D, textureIndices.at(j)); j++; } glBegin(GL_TRIANGLES); for(int i = 0;i < 3;i++) { glNormal3fv(normals[3*p+i]); //set normal vector of that point if(mesh->texels) glTexCoord2f(mesh->texelL[f->points[i]][0], mesh->texelL[f->points[i]][1]); glVertex3fv(mesh->pointL[f->points[i]].pos); //Draw the damn triangle } glEnd(); } } free(normals); //free up memory } glEndList(); // end of list } if(node->user.d) // if we have created a link list(with glNewList) { Lib3dsObjectData *tmpdat; glPushMatrix(); //save transformation values tmpdat = &node->data.object; // get the position data glMultMatrixf(&node->matrix[0][0]); //adjust matrix according to the node glTranslatef(-tmpdat->pivot[0], -tmpdat->pivot[1], -tmpdat->pivot[2]); //move to the right place; glCallList(node->user.d); //render node glPopMatrix(); //return transformation original values } } }
void Object_3DS::renderNode(Lib3dsNode *node) { #ifdef HAS_LIB3DS for (Lib3dsNode* p=node->childs; p!=0; p=p->next) renderNode(p); if (node->type == LIB3DS_OBJECT_NODE) { if (strcmp(node->name,"$$$DUMMY")==0) return; if (!node->user.d) { Lib3dsMesh *mesh=lib3ds_file_mesh_by_name(file, node->name); if (!mesh) return; MSG_INFO("Rendering node %s",node->name); MSG_INFO("Face number: %d",mesh->faces); // return ; node->user.d = glGenLists(1); glNewList(node->user.d, GL_COMPILE); Lib3dsVector *normalL = new Lib3dsVector[3*mesh->faces]; Lib3dsMatrix M; lib3ds_matrix_copy(M, mesh->matrix); lib3ds_matrix_inv(M); glMultMatrixf(&M[0][0]); lib3ds_mesh_calculate_normals(mesh, normalL); for (unsigned int p=0; p<mesh->faces; ++p) { Lib3dsFace *f=&mesh->faceL[p]; Lib3dsMaterial *mat=0; if (f->material[0]) mat=lib3ds_file_material_by_name(file, f->material); if (mat) { static GLfloat a[4]={0,0,0,1}; float s; glMaterialfv(GL_FRONT, GL_AMBIENT, a); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); s = pow(2, 10.0*mat->shininess); if (s>128.0) s=128.0; glMaterialf(GL_FRONT, GL_SHININESS, s); } else { Lib3dsRgba a={0.2, 0.2, 0.2, 1.0}; Lib3dsRgba d={0.8, 0.8, 0.8, 1.0}; Lib3dsRgba s={0.0, 0.0, 0.0, 1.0}; glMaterialfv(GL_FRONT, GL_AMBIENT, a); glMaterialfv(GL_FRONT, GL_DIFFUSE, d); glMaterialfv(GL_FRONT, GL_SPECULAR, s); } glBegin(GL_TRIANGLES); glNormal3fv(f->normal); for (int i=0; i<3; ++i) { glNormal3fv(normalL[3*p+i]); glVertex3fv(mesh->pointL[f->points[i]].pos); } glEnd(); } delete[] normalL; glEndList(); } if (node->user.d) { glPushMatrix(); Lib3dsObjectData* d = &node->data.object; glMultMatrixf(&node->matrix[0][0]); glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]); glCallList(node->user.d); glPopMatrix(); } } #endif }
/*! * Render node recursively, first children, then parent. * Each node receives its own OpenGL display list. */ static void render_node(Lib3dsNode *node) { ASSERT(file); { Lib3dsNode *p; for (p=node->childs; p!=0; p=p->next) { render_node(p); } } if (node->type==LIB3DS_OBJECT_NODE) { Lib3dsMesh *mesh; if (strcmp(node->name,"$$$DUMMY")==0) { return; } mesh = lib3ds_file_mesh_by_name(file, node->data.object.morph); if( mesh == NULL ) mesh = lib3ds_file_mesh_by_name(file, node->name); if (!mesh->user.d) { ASSERT(mesh); if (!mesh) { return; } mesh->user.d=glGenLists(1); glNewList(mesh->user.d, GL_COMPILE); { unsigned p; Lib3dsVector *normalL=malloc(3*sizeof(Lib3dsVector)*mesh->faces); Lib3dsMaterial *oldmat = (Lib3dsMaterial *)-1; { Lib3dsMatrix M; lib3ds_matrix_copy(M, mesh->matrix); lib3ds_matrix_inv(M); glMultMatrixf(&M[0][0]); } lib3ds_mesh_calculate_normals(mesh, normalL); for (p=0; p<mesh->faces; ++p) { Lib3dsFace *f=&mesh->faceL[p]; Lib3dsMaterial *mat=0; #ifdef USE_SDL Player_texture *pt = NULL; int tex_mode = 0; #endif if (f->material[0]) { mat=lib3ds_file_material_by_name(file, f->material); } if( mat != oldmat ) { if (mat) { if( mat->two_sided ) glDisable(GL_CULL_FACE); else glEnable(GL_CULL_FACE); glDisable(GL_CULL_FACE); /* Texturing added by Gernot < *****@*****.** > */ if (mat->texture1_map.name[0]) { /* texture map? */ Lib3dsTextureMap *tex = &mat->texture1_map; if (!tex->user.p) { /* no player texture yet? */ char texname[1024]; pt = malloc(sizeof(*pt)); tex->user.p = pt; //snprintf(texname, sizeof(texname), "%s/%s", datapath, tex->name); strcpy(texname, datapath); strcat(texname, "/"); strcat(texname, tex->name); #ifdef DEBUG printf("Loading texture map, name %s\n", texname); #endif /* DEBUG */ #ifdef USE_SDL #ifdef USE_SDL_IMG_load pt->bitmap = IMG_load(texname); #else pt->bitmap = IMG_Load(texname); #endif /* IMG_Load */ #else /* USE_SDL */ pt->bitmap = NULL; fputs("3dsplayer: Warning: No image loading support, skipping texture.\n", stderr); #endif /* USE_SDL */ if (pt->bitmap) { /* could image be loaded ? */ /* this OpenGL texupload code is incomplete format-wise! * to make it complete, examine SDL_surface->format and * tell us @lib3ds.sf.net about your improvements :-) */ int upload_format = GL_RED; /* safe choice, shows errors */ #ifdef USE_SDL int bytespp = pt->bitmap->format->BytesPerPixel; void *pixel = NULL; glGenTextures(1, &pt->tex_id); #ifdef DEBUG printf("Uploading texture to OpenGL, id %d, at %d bytepp\n", pt->tex_id, bytespp); #endif /* DEBUG */ if (pt->bitmap->format->palette) { pixel = convert_to_RGB_Surface(pt->bitmap); upload_format = GL_RGBA; } else { pixel = pt->bitmap->pixels; /* e.g. this could also be a color palette */ if (bytespp == 1) upload_format = GL_LUMINANCE; else if (bytespp == 3) upload_format = GL_RGB; else if (bytespp == 4) upload_format = GL_RGBA; } glBindTexture(GL_TEXTURE_2D, pt->tex_id); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_XSIZE, TEX_YSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pt->bitmap->w, pt->bitmap->h, upload_format, GL_UNSIGNED_BYTE, pixel); pt->scale_x = (float)pt->bitmap->w/(float)TEX_XSIZE; pt->scale_y = (float)pt->bitmap->h/(float)TEX_YSIZE; #endif /* USE_SDL */ pt->valid = 1; } else { fprintf(stderr, "Load of texture %s did not succeed " "(format not supported !)\n", texname); pt->valid = 0; } } else { pt = (Player_texture *)tex->user.p; } tex_mode = pt->valid; } else { tex_mode = 0; } glMaterialfv(GL_FRONT, GL_AMBIENT, mat->ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); glMaterialf(GL_FRONT, GL_SHININESS, pow(2, 10.0*mat->shininess)); } else { static const Lib3dsRgba a={0.7, 0.7, 0.7, 1.0}; static const Lib3dsRgba d={0.7, 0.7, 0.7, 1.0}; static const Lib3dsRgba s={1.0, 1.0, 1.0, 1.0}; glMaterialfv(GL_FRONT, GL_AMBIENT, a); glMaterialfv(GL_FRONT, GL_DIFFUSE, d); glMaterialfv(GL_FRONT, GL_SPECULAR, s); glMaterialf(GL_FRONT, GL_SHININESS, pow(2, 10.0*0.5)); } oldmat = mat; } else if (mat != NULL && mat->texture1_map.name[0]) { Lib3dsTextureMap *tex = &mat->texture1_map; if (tex != NULL && tex->user.p != NULL) { pt = (Player_texture *)tex->user.p; tex_mode = pt->valid; } } { int i; if (tex_mode) { //printf("Binding texture %d\n", pt->tex_id); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, pt->tex_id); } glBegin(GL_TRIANGLES); glNormal3fv(f->normal); for (i=0; i<3; ++i) { glNormal3fv(normalL[3*p+i]); if (tex_mode) { glTexCoord2f(mesh->texelL[f->points[i]][1]*pt->scale_x, pt->scale_y - mesh->texelL[f->points[i]][0]*pt->scale_y); } glVertex3fv(mesh->pointL[f->points[i]].pos); } glEnd(); if (tex_mode) glDisable(GL_TEXTURE_2D); } } free(normalL); } glEndList(); } if (mesh->user.d) { Lib3dsObjectData *d; glPushMatrix(); d=&node->data.object; glMultMatrixf(&node->matrix[0][0]); glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]); glCallList(mesh->user.d); /* glutSolidSphere(50.0, 20,20); */ glPopMatrix(); if( flush ) glFlush(); } } }
/*! * */ static void render_node(Lib3dsNode *node) { ASSERT(file); { Lib3dsNode *p; for (p=node->childs; p!=0; p=p->next) { render_node(p); } } if (node->type==LIB3DS_OBJECT_NODE) { if (strcmp(node->name,"$$$DUMMY")==0) { return; } if (!node->user.d) { Lib3dsMesh *mesh=lib3ds_file_mesh_by_name(file, node->name); ASSERT(mesh); if (!mesh) { return; } node->user.d=glGenLists(1); glNewList(node->user.d, GL_COMPILE); { unsigned p; Lib3dsVector *normalL=malloc(3*sizeof(Lib3dsVector)*mesh->faces); { Lib3dsMatrix M; lib3ds_matrix_copy(M, mesh->matrix); lib3ds_matrix_inv(M); glMultMatrixf(&M[0][0]); } lib3ds_mesh_calculate_normals(mesh, normalL); for (p=0; p<mesh->faces; ++p) { Lib3dsFace *f=&mesh->faceL[p]; Lib3dsMaterial *mat=0; if (f->material[0]) { mat=lib3ds_file_material_by_name(file, f->material); } if (mat) { float s[1]; s[0]=1.0; glMaterialfv(GL_FRONT, GL_AMBIENT, mat->ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); glMaterialf(GL_FRONT, GL_SHININESS, 11.0-0.2*mat->shininess); } else { Lib3dsRgba a={0.2, 0.2, 0.2, 1.0}; Lib3dsRgba d={0.8, 0.8, 0.8, 1.0}; Lib3dsRgba s={0.0, 0.0, 0.0, 1.0}; glMaterialfv(GL_FRONT, GL_AMBIENT, a); glMaterialfv(GL_FRONT, GL_DIFFUSE, d); glMaterialfv(GL_FRONT, GL_SPECULAR, s); } { int i; glBegin(GL_TRIANGLES); glNormal3fv(f->normal); for (i=0; i<3; ++i) { glNormal3fv(normalL[3*p+i]); glVertex3fv(mesh->pointL[f->points[i]].pos); } glEnd(); } } free(normalL); } glEndList(); } if (node->user.d) { Lib3dsObjectData *d; glPushMatrix(); d=&node->data.object; glMultMatrixf(&node->matrix[0][0]); glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]); glCallList(node->user.d); /*glutSolidSphere(50.0, 20,20);*/ glPopMatrix(); } } }
static void create_node(Lib3dsFile *f, Lib3dsNode *node, FILE *o) { Lib3dsMesh *mesh; if ((node->type==LIB3DS_OBJECT_NODE) && (strcmp(node->name,"$$$DUMMY")!=0)) { mesh=lib3ds_file_mesh_by_name(f, node->name); ASSERT(mesh); if (mesh) { Lib3dsObjectData *d=&node->data.object; fprintf(o, "AttributeBegin\n"); fprintf(o, "Surface \"matte\" \"Kd\" [0.75]\n"); fprintf(o, "Color 1 1 1\n"); { Lib3dsMatrix N,M,X; lib3ds_matrix_copy(N, node->matrix); lib3ds_matrix_translate_xyz(N, -d->pivot[0], -d->pivot[1], -d->pivot[2]); lib3ds_matrix_copy(M, mesh->matrix); lib3ds_matrix_inv(M); lib3ds_matrix_mul(X,N,M); rib_concat_transform(o, X); } { unsigned p; Lib3dsVector *normalL=malloc(3*sizeof(Lib3dsVector)*mesh->faces); lib3ds_mesh_calculate_normals(mesh, normalL); for (p=0; p<mesh->faces; ++p) { Lib3dsFace *face=&mesh->faceL[p]; Lib3dsMaterial *mat=lib3ds_file_material_by_name(f, face->material); if (mat) { fprintf(o, "Color [%f %f %f]\n", mat->diffuse[0], mat->diffuse[1], mat->diffuse[2] ); fprintf(o, "Surface " "\"lib3dsmaterial\" " "\"color specularcolor\" [%f %f %f] " "\"float shininess \" [%f] " "\"float shin_stength \" [%f] " "\n", mat->specular[0], mat->specular[1], mat->specular[2], mat->shininess, mat->shin_strength ); } fprintf(o, "Polygon \"P\" [%f %f %f %f %f %f %f %f %f] ", mesh->pointL[face->points[0]].pos[0], mesh->pointL[face->points[0]].pos[1], mesh->pointL[face->points[0]].pos[2], mesh->pointL[face->points[1]].pos[0], mesh->pointL[face->points[1]].pos[1], mesh->pointL[face->points[1]].pos[2], mesh->pointL[face->points[2]].pos[0], mesh->pointL[face->points[2]].pos[1], mesh->pointL[face->points[2]].pos[2] ); fprintf(o, "\"N\" [%f %f %f %f %f %f %f %f %f] ", normalL[3*p+0][0], normalL[3*p+0][1], normalL[3*p+0][2], normalL[3*p+1][0], normalL[3*p+1][1], normalL[3*p+1][2], normalL[3*p+2][0], normalL[3*p+2][1], normalL[3*p+2][2] ); } free(normalL); } fprintf(o, "AttributeEnd\n"); } } { Lib3dsNode *n; for (n=node->childs; n; n=n->next) { create_node(f,n,o); } } }
//! Create 3DRep from a Lib3dsNode GLC_3DRep GLC_3dsToWorld::create3DRep(Lib3dsMesh* p3dsMesh) { QString meshName(p3dsMesh->name); if (m_LoadedMeshes.contains(meshName)) { // This mesh as been already loaded QList<GLC_3DViewInstance*> instancesList(m_pWorld->collection()->instancesHandle()); GLC_3DViewInstance* pCurrentInstance= NULL; int currentIndex= -1; do { pCurrentInstance= instancesList[++currentIndex]; } while (pCurrentInstance->name() != meshName); // return an instance. //qDebug() << "instance"; return pCurrentInstance->representation(); } GLC_Mesh * pMesh= new GLC_Mesh(); pMesh->setName(p3dsMesh->name); // The mesh normals const int normalsNumber= p3dsMesh->faces * 3; Lib3dsVector *normalL= new Lib3dsVector[normalsNumber]; lib3ds_mesh_calculate_normals(p3dsMesh, normalL); // Position vector QVector<float> position(normalsNumber * 3); // Normal Vector QVector<float> normal(normalsNumber * 3); memcpy((void*)normal.data(), normalL, normalsNumber * 3 * sizeof(float)); // Texel Vector QVector<float> texel; if (p3dsMesh->texels > 0) { texel.resize(normalsNumber * 2); } int normalIndex= 0; for (unsigned int i= 0; i < p3dsMesh->faces; ++i) { IndexList triangleIndex; Lib3dsFace *p3dsFace=&p3dsMesh->faceL[i]; for (int i=0; i < 3; ++i) { triangleIndex.append(normalIndex); // Add vertex coordinate memcpy((void*)&(position.data()[normalIndex * 3]), &p3dsMesh->pointL[p3dsFace->points[i]], 3 * sizeof(float)); // Add texel if (p3dsMesh->texels > 0) { memcpy((void*)&(texel.data()[normalIndex * 2]), &p3dsMesh->texelL[p3dsFace->points[i]], 2 * sizeof(float)); } ++normalIndex; } // Load the material // The material current face index GLC_Material* pCurMaterial= NULL; if (p3dsFace->material[0]) { Lib3dsMaterial* p3dsMat=lib3ds_file_material_by_name(m_pLib3dsFile, p3dsFace->material); if (NULL != p3dsMat) { // Check it this material as already been loaded const QString materialName(p3dsFace->material); if (!m_Materials.contains(materialName)) { // Material not already loaded, load it loadMaterial(p3dsMat); } pCurMaterial= m_Materials.value(materialName); } } pMesh->addTriangles(pCurMaterial, triangleIndex); } pMesh->addVertice(position); pMesh->addNormals(normal); if (p3dsMesh->texels > 0) { pMesh->addTexels(texel); } // free normal memmory delete[] normalL; // Compute loading progress ++m_CurrentMeshNumber; m_CurrentQuantumValue = static_cast<int>((static_cast<double>(m_CurrentMeshNumber) / m_NumberOfMeshes) * (100 - m_InitQuantumValue)) + m_InitQuantumValue; if (m_CurrentQuantumValue > m_PreviousQuantumValue) { emit currentQuantum(m_CurrentQuantumValue); } m_PreviousQuantumValue= m_CurrentQuantumValue; pMesh->finish(); return GLC_3DRep(pMesh); }
static bool load_material(Lib3dsFile *file, const char *name, Material *mat) { Lib3dsMaterial *m; if(!name || !*name || !(m = lib3ds_file_material_by_name(file, name))) { return false; } mat->name = name; mat->ambient_color = CONV_RGBA(m->ambient); mat->diffuse_color = CONV_RGBA(m->diffuse); mat->specular_color = CONV_RGBA(m->specular) * m->shin_strength; if(m->self_illum) { std::cerr << "self illuminating material: " << name << std::endl; mat->emissive_color = 1.0; } scalar_t s = pow(2.0, 10.0 * m->shininess); mat->specular_power = s > 128.0 ? 128.0 : s; mat->alpha = 1.0 - m->transparency; if(m->shading == LIB3DS_WIRE_FRAME || m->use_wire) { mat->wireframe = true; } if(m->shading == LIB3DS_FLAT) { mat->shading = SHADING_FLAT; } // load the textures Texture *tex = 0, *detail = 0, *env = 0, *light = 0, *bump = 0; const char *tpath; tpath = tex_path(m->texture1_map.name); if(tpath && (tex = get_texture(tpath))) { mat->set_texture(tex, TEXTYPE_DIFFUSE); } tpath = tex_path(m->texture2_map.name); if(tpath && (detail = get_texture(tpath))) { mat->set_texture(detail, TEXTYPE_DETAIL); } tpath = tex_path(m->reflection_map.name); if(tpath && (env = get_texture(tpath))) { mat->set_texture(env, TEXTYPE_ENVMAP); mat->env_intensity = m->reflection_map.percent; } tpath = tex_path(m->bump_map.name); if(tpath && (bump = get_texture(tpath))) { //FIXME: make dot3 work first mat->set_texture(bump, TEXTYPE_BUMPMAP); } tpath = tex_path(m->self_illum_map.name); if(tpath && (light = get_texture(tpath))) { mat->set_texture(light, TEXTYPE_LIGHTMAP); } if(m->autorefl_map.flags & LIB3DS_USE_REFL_MAP) { mat->env_intensity = m->reflection_map.percent; int cube_sz = m->autorefl_map.size; if(!is_pow_two(cube_sz)) { warning("Material \"%s\" specifies a non power of 2 cube map and won't render correctly!", m->name); } Texture *cube_tex = new Texture(cube_sz, cube_sz, TEX_CUBE); add_texture(cube_tex); mat->set_texture(cube_tex, TEXTYPE_ENVMAP); if(m->autorefl_map.flags & LIB3DS_READ_FIRST_FRAME_ONLY || m->autorefl_map.flags & 0x8 || m->autorefl_map.frame_step == 1000) { mat->auto_refl = false; } mat->auto_refl_upd = m->autorefl_map.frame_step; } return true; }
/* * The "realize" signal handler for copter. * One-time OpenGL initialization should be performed here. */ void on_copter_realize (GtkWidget *copter, gpointer data) { GdkGLContext *glContext; GdkGLDrawable *glDrawable; Lib3dsMesh * mesh; int i, cface; int tfaces = 0; // Don't continue if we get fed a dud window type. if (copter->window == NULL) { return; } copter_model = lib3ds_file_load(copter_filename); // If loading the model failed, we throw an exception if (!copter_model) { fprintf(stderr, "open %s error\n", THREED_MODEL_FILENAME); return; } // Loop through every mesh for(mesh = copter_model->meshes; mesh != NULL; mesh = mesh->next) { // Add the number of faces this mesh has to the total faces copter_faces += mesh->faces; } copter_normals = (Lib3dsVector*)malloc(sizeof(Lib3dsVector) * copter_faces * 3); copter_vertices = (Lib3dsVector*)malloc(sizeof(Lib3dsVector) * copter_faces * 3); copter_colors = (Lib3dsRgba*)malloc(sizeof(Lib3dsRgba) * copter_faces); if (!copter_normals || !copter_vertices || !copter_colors) return; // Loop through all the meshes for(mesh = copter_model->meshes; mesh != NULL; mesh = mesh->next) { lib3ds_mesh_calculate_normals(mesh, (copter_normals + 3 * tfaces)); // Loop through every face for(cface = 0; cface < mesh->faces; cface++) { Lib3dsFace * face = &mesh->faceL[cface]; Lib3dsMaterial *mat = NULL; mat = lib3ds_file_material_by_name(copter_model, face->material); if (mat) memcpy(copter_colors + tfaces, mat->diffuse, sizeof(Lib3dsRgba)); for(i = 0;i < 3;i++) { memcpy(copter_vertices + tfaces * 3 + i, mesh->pointL[face->points[i]].pos, sizeof(Lib3dsVector)); } tfaces++; } } lib3ds_file_free(copter_model); glContext = gtk_widget_get_gl_context (copter); glDrawable = gtk_widget_get_gl_drawable (copter); // Signal to gdk the start OpenGL operations. if (!gdk_gl_drawable_gl_begin (glDrawable, glContext)) { return; } /* Your one-time OpenGL initialization code goes here */ glEnable(GL_TEXTURE_2D); // Enables Depth Testing glEnable(GL_DEPTH_TEST); // Enables Depth Testing glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading glViewport (0, 0, copter->allocation.width, copter->allocation.height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Reset The Projection Matrix gluPerspective(45.0f,(GLfloat)copter->allocation.width/(GLfloat)copter->allocation.height, 0.1f,100.0f); // Calculate The Aspect Ratio Of The Window glMatrixMode(GL_MODELVIEW); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); // Signal to gdk we're done with OpenGL operations. gdk_gl_drawable_gl_end (glDrawable); gdk_window_invalidate_rect (gtk_widget_get_parent_window (copter), &copter->allocation, TRUE); }
void m3ds::render_node(Lib3dsNode* node) { assert(m_file); { Lib3dsNode* p; for (p = node->childs; p != 0; p = p->next) render_node(p); } if (node->type == LIB3DS_OBJECT_NODE) { if (!strcmp(node->name, "$$$DUMMY")) return; if (!node->user.d) { Lib3dsMesh* mesh = lib3ds_file_mesh_by_name(m_file, node->name); assert(mesh); if (!mesh) return; node->user.d = glGenLists(1); glNewList(node->user.d, GL_COMPILE); { unsigned int p; Lib3dsVector* normalL = new Lib3dsVector[3 * mesh->faces]; { Lib3dsMatrix M; lib3ds_matrix_copy(M, mesh->matrix); lib3ds_matrix_inv(M); glMultMatrixf(&M[0][0]); } lib3ds_mesh_calculate_normals(mesh, normalL); for (p = 0; p < mesh->faces; ++p) { Lib3dsFace* f = &mesh->faceL[p]; Lib3dsMaterial* mat = 0; if (f->material[0]) { mat = lib3ds_file_material_by_name(m_file, f->material); if (mat->texture1_map.name[0]) { std::string str = mat->texture1_map.name; std::map<std::string, texture*>::iterator ite; ite = texlib::instance()->find(str); if (ite == texlib::instance()->end()) { texture* pt = NULL; char str2[512]; memset(str2, 0, 512); sprintf(str2, "%s%s", s_prefix, str.c_str()); char* ext = &str2[strlen(str2) - 3]; ext[0] = tolower(ext[0]); ext[1] = tolower(ext[1]); ext[2] = tolower(ext[2]); if (!strcmp(ext, "tga")) { tga_tex* tex = new tga_tex(str2); if (tex->get_tex_id() != -1) { pt = tex; texlib::instance()->insert(texlib::value_type(str, pt)); } } else if (!strcmp(ext, "bmp")) { bmp_tex* tex = new bmp_tex(str2); if (tex->get_tex_id() != -1) { pt = tex; texlib::instance()->insert(texlib::value_type(str, pt)); } } else if (!strcmp(ext, "pcx")) { pcx_tex* tex = new pcx_tex(str2); if (tex->get_tex_id() != -1) { pt = tex; texlib::instance()->insert(texlib::value_type(str, pt)); } } else { ext[0] = 't'; ext[1] = 'g'; ext[2] = 'a'; tga_tex* tex = new tga_tex(str2); // str = str2; if (tex->get_tex_id() != -1) { pt = tex; } else { pt = texlib::instance()->operator[]("default.tga"); } texlib::instance()->insert(texlib::value_type(str, pt)); } glBindTexture(GL_TEXTURE_2D, (pt) ? pt->get_tex_id() : ((*texlib::instance())["default.tga"])->get_tex_id()); } else { glBindTexture(GL_TEXTURE_2D, (ite->second)->get_tex_id()); } } } if (mat) { static GLfloat a[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float s; glMaterialfv(GL_FRONT, GL_AMBIENT, a); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); s = pow(2.0f, 10.0f * mat->shininess); if (s > 128.0) s = 128.0; glMaterialf(GL_FRONT, GL_SHININESS, s); } else { Lib3dsRgba a = {0.2f, 0.2f, 0.2f, 1.0f}; Lib3dsRgba d = {0.8f, 0.8f, 0.8f, 1.0f}; Lib3dsRgba s = {0.0f, 0.0f, 0.0f, 1.0f}; glMaterialfv(GL_FRONT, GL_AMBIENT, a); glMaterialfv(GL_FRONT, GL_DIFFUSE, d); glMaterialfv(GL_FRONT, GL_SPECULAR, s); } glBegin(GL_TRIANGLES); glNormal3fv(f->normal); for (int i = 0; i < 3; ++i) { assert(mesh); if (mesh->texelL) glTexCoord2fv(mesh->texelL[f->points[i]]); glNormal3fv(normalL[3 * p + i]); glVertex3fv(mesh->pointL[f->points[i]].pos); } glEnd(); } delete [] normalL; } glEndList(); } if (node->user.d) { Lib3dsObjectData* d; glPushMatrix(); d = &node->data.object; glMultMatrixf(&node->matrix[0][0]); glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]); glCallList(node->user.d); glPopMatrix(); } } }