Mercurial > hg > Members > kono > Cerium
view old/simple_pack/polygon.cpp @ 881:c81744aaa3ef
cannot load xml of 3rd screen bug fix (include init bug yet)
author | kazz <kazz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 09 Jul 2010 14:33:31 +0900 |
parents | 735f76483bb2 |
children |
line wrap: on
line source
#include <iostream> #include <SDL.h> #include <SDL_opengl.h> #include <SDL_image.h> #include <libxml/parser.h> #include "polygon.h" #include "xml.h" #include "texture.h" #include "sys.h" #include "triangle.h" #include "vertex.h" #include "span.h" #include "scene_graph_pack.h" using namespace std; //extern int decode(char *cont, char *file_name); extern int decode(char *cont, FILE *outfile); Polygon::Polygon() { xyz[0] = 0; xyz[1] = 0; xyz[2] = 0; xyz[3] = 1; c_xyz[0] = 0; c_xyz[1] = 0; c_xyz[2] = 0; c_xyz[3] = 1; angle[0] = 0; angle[1] = 0; angle[2] = 0; angle[3] = 1; next = NULL; child = NULL; parent = NULL; brother = NULL; } void Polygon::tree_check() { Polygon *t; t = this; while(t) { cout << "my_name : " << t->name << endl; if(t->child != NULL) { cout << "--move child : " << t->child->name << endl; t = t->child; } else if(t->brother != NULL) { cout << "--move brother : " << t->brother->name << endl; t = t->brother; } else { while(t) { if(t->brother != NULL) { cout << "--move brother : " << t->brother->name << endl; t = t->brother; break; } else { if(t->parent) { cout << "--move parent : " << t->parent->name << endl; } t = t->parent; } } } } } void Polygon::print_member() { //int n; cout << "size = " << size << endl; cout << "name = " << name << endl; cout << "parent_name = " << parent_name << endl; /* for(n=0; n<size*3; n+=3) { cout<<"coordinate = "<<data[n]<<" "<<data[n+1]<<" "<< data[n+2]<<endl; } */ /* for(n=size*3; n<size*6; n+=3) { cout<<"narmal = "<<data[n]<<" "<<data[n+1]<<" "<<data[n+2]<<endl; } */ cout<<"c_xyz = "<<c_xyz[0]<<" "<<c_xyz[1]<<" "<<c_xyz[2]<<endl; /* for(n=size*6; n<size*9; n+=3) { cout<<"texture = "<<data[n]<<" "<<data[n+1]<<" "<<data[n+2]<<endl; } */ /* for(n=0; n<size*3; n+=3) { cout<<"coordinate = "<<data[n]<<" "<<data[n+1]<<" "<<data[n+2]<<endl; cout<<"normal = "<<data[n+size*3]<<" "<<data[n+size*3+1]<<" "<<data[n+size*3+2]<<endl; cout<<"texture = "<<data[n+size*6]<<" "<<1-data[n+size*6+1]<<endl; } */ //cout << "image_name = " << image_name << endl; if(parent != NULL) { cout << "parent->name = " << parent->name << endl; } if(child != NULL) { cout << "child->name = " << child->name << endl; } } void Polygon::parameter_change(char *name, float x, float y, float z, float ax, float ay, float az) { Polygon *p; p = this; while(p) { if(!strcmp(p->name,name)) { p->xyz[0] = x; p->xyz[1] = y; p->xyz[2] = z; p->angle[0] = ax; p->angle[1] = ay; p->angle[2] = az; break; } p = p->next; } } /* void Polygon::load_texture(char *image_name) { SDL_Surface *image; GLfloat texcoord[4]; image = IMG_Load(image_name); //image = IMG_Load("icon.bmp"); texture = (int *)SDL_GL_LoadTexture(image, texcoord); SDL_FreeSurface(image); } */ void Polygon::draw(float *stack=NULL) { float xyz1[4],xyz2[4],xyz3[4]; get_matrix(matrix, angle, xyz, stack); for(int n=0; n<size*3; n+=9) { xyz1[0] = data[n]; xyz1[1] = data[n+1]; xyz1[2] = data[n+2]*-1; xyz1[3] = 1; xyz2[0] = data[n+3]; xyz2[1] = data[n+3+1]; xyz2[2] = data[n+3+2]*-1; xyz2[3] = 1; xyz3[0] = data[n+6]; xyz3[1] = data[n+6+1]; xyz3[2] = data[n+6+2]*-1; xyz3[3] = 1; rotate(xyz1, matrix); rotate(xyz2, matrix); rotate(xyz3, matrix); Vertex *ver1 = new Vertex(xyz1[0],xyz1[1],xyz1[2],data[n+size*6],data[n+size*6+1]); Vertex *ver2 = new Vertex(xyz2[0],xyz2[1],xyz2[2],data[n+size*6+3],data[n+size*6+3+1]); Vertex *ver3 = new Vertex(xyz3[0],xyz3[1],xyz3[2],data[n+size*6+6],data[n+size*6+6+1]); //printf("x1:%f ,%f ,%f , %f, %f\n",xyz1[0],xyz1[1],xyz1[2],data[n+size*6],data[n+size*6+1]); //printf("x2:%f ,%f ,%f , %f, %f\n",xyz2[0],xyz2[1],xyz2[2],data[n+size*6+3],data[n+size*6+3+1]); //printf("x3:%f ,%f ,%f , %f, %f\n",xyz3[0],xyz3[1],xyz3[2],data[n+size*6+6],data[n+size*6+6+1]); Triangle *tri = new Triangle(ver1,ver2,ver3); Span_c *span = new Span_c(); span->viewer = viewer; span->p = this; span->create_span(tri,texture_image); delete ver1; delete ver2; delete ver3; delete tri; delete span; //viewer->write_triangle(xyz1[0],xyz1[1],xyz2[0],xyz2[1],xyz3[0],xyz3[1],rgb); } } void Polygon::tree_draw() { Polygon *t; t = this; /* float *stack[128]; for(int i=0; i<128; i++) { stack[i] = NULL; } */ //glPushMatrix(); //int s=0; while(t) { //t->draw(stack[s-1]); if(t->parent) { t->draw(t->parent->matrix); } else { t->draw(); } if(t->child != NULL) { //stack[s++] = t->matrix; //push t = t->child; } else if(t->brother != NULL) { //stack[--s] = NULL; //pop //stack[s++] = t->matrix; //push t = t->brother; } else { while(t) { if(t->brother != NULL) { //stack[--s] = NULL; //pop //stack[s++] = t->matrix; //push t = t->brother; break; } else { t = t->parent; if(t) { //stack[--s] = NULL; //pop } } } } } //glPopMatrix(); } /* void Polygon::sgp_update() { for (int i = 0; i < sgp->info.size; i++) { //(*my_func[node->move])(node); //(*my_func[node->interaction])(node, sgp); if(sgp->node[i].pn != -1) { get_matrix(sgp->node[i].translation, sgp->node[i].angle, sgp->node[i].obj_pos, sgp->node[sgp->node[i].pn].translation); } else { get_matrix(sgp->node[i].translation, sgp->node[i].angle, sgp->node[i].obj_pos, NULL); } //get_matrix(sgp->node[i].translation, sgp->node[i].angle, sgp->node[i].obj_pos, sgp->node[sgp->node[i].pn].translation); } } */ void Polygon::draw(SceneGraphPack *sgp) { float xyz1[4],xyz2[4],xyz3[4]; /***SceneGraphUpdate***/ //sgp_update(); for (int i = 0; i < sgp->info.size; i++) { SceneGraphNode node = sgp->node[i]; /***draw***/ int n,nt; for(n=0,nt=0; n<node.size*3; n+=9,nt+=6) { xyz1[0] = node.vertex[n]; xyz1[1] = node.vertex[n+1]; xyz1[2] = node.vertex[n+2]*-1; xyz1[3] = 1; xyz2[0] = node.vertex[n+3]; xyz2[1] = node.vertex[n+3+1]; xyz2[2] = node.vertex[n+3+2]*-1; xyz2[3] = 1; xyz3[0] = node.vertex[n+6]; xyz3[1] = node.vertex[n+6+1]; xyz3[2] = node.vertex[n+6+2]*-1; xyz3[3] = 1; rotate(xyz1, node.translation); rotate(xyz2, node.translation); rotate(xyz3, node.translation); Vertex *ver1 = new Vertex(xyz1[0],xyz1[1],xyz1[2],node.texture[nt],node.texture[nt+1]); Vertex *ver2 = new Vertex(xyz2[0],xyz2[1],xyz2[2],node.texture[nt+2],node.texture[nt+2+1]); Vertex *ver3 = new Vertex(xyz3[0],xyz3[1],xyz3[2],node.texture[nt+4],node.texture[nt+4+1]); Triangle *tri = new Triangle(ver1,ver2,ver3); Span_c *span = new Span_c(); span->viewer = viewer; span->p = this; span->create_span(tri,texture_image); delete ver1; delete ver2; delete ver3; delete tri; delete span; } } } void Polygon::draw(PolygonPack *pp) { for(int n=0; n<pp->info.size; n++) { Vertex *ver1 = new Vertex(pp->tri[n].ver1.x,pp->tri[n].ver1.y,pp->tri[n].ver1.z,pp->tri[n].ver1.tex_x,pp->tri[n].ver1.tex_y); Vertex *ver2 = new Vertex(pp->tri[n].ver2.x,pp->tri[n].ver2.y,pp->tri[n].ver2.z,pp->tri[n].ver2.tex_x,pp->tri[n].ver2.tex_y); Vertex *ver3 = new Vertex(pp->tri[n].ver3.x,pp->tri[n].ver3.y,pp->tri[n].ver3.z,pp->tri[n].ver3.tex_x,pp->tri[n].ver3.tex_y); Triangle *tri = new Triangle(ver1,ver2,ver3); Span_c *span = new Span_c(); span->viewer = viewer; span->p = this; span->create_span(tri,texture_image); delete ver1; delete ver2; delete ver3; delete tri; delete span; } } void Polygon::draw(SPANPACK *sp) { for(int n=0; n<sp->info.size; n++) { int end = sp->span[n].length_x; Uint32 rgb; float tex1 = sp->span[n].tex_x1; float tex2= sp->span[n].tex_x2; float tey1 = sp->span[n].tex_y1; float tey2= sp->span[n].tex_y2; int tex_xpos; int tex_ypos; int tex_zpos; int x = sp->span[n].x; int y = sp->span[n].y; float z = sp->span[n].start_z; float zpos = sp->span[n].end_z; float tex_x,tex_y,tex_z; if(end == 1) { //printf("end == 1\n"); //printf("tex_x:%f tex_y:%f\n",tex1,tex2); //if(tex1 > 1) tex1 = 1; //if(tey1 > 1) tey1 = 1; tex_xpos = (int)((sp->span[n].tex_height-1) * tex1); tex_ypos = (int)((sp->span[n].tex_width-1) * tey1); tex_zpos = (int)z; //printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos); //printf("image->h:%d tex_x:%f\n",(int)sp->span[n].tex_height,tex1); rgb = get_rgb(tex_xpos,tex_ypos); viewer->write_pixel(x,y,zpos,rgb); }else { //printf("end != 1\n"); for(int j = 0; j < end; j++) { tex_x = tex1*(end-1-j)/(end-1) + tex2*j/(end-1); tex_y = tey1*(end-1-j)/(end-1) + tey2*j/(end-1); tex_z = z*(end-1-j)/(end-1) + zpos*j/(end-1); if(tex_x > 1) tex_x = 1; if(tex_y > 1) tex_y = 1; tex_xpos = (int)((sp->span[n].tex_height-1) * tex_x); tex_ypos = (int)((sp->span[n].tex_width-1) * tex_y); //printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos); //printf("z:%f zpos:%f tex_z:%f\n",z,zpos,tex_z); //printf("tex_x:%f tex_y:%f\n",tex_x,tex_y); rgb = get_rgb(tex_xpos,tex_ypos); viewer->write_pixel(j+x,y,tex_z,rgb); } } } } /* void Polygon::create_scene_graph_pack() { //SceneGraphPack *sgp = new SceneGraphPack; sgp = new SceneGraphPack; int i = 0; int nnpn = -1; Polygon *t; t = this; while(t) { //SceneGraphNode node; sgp->node[i].size = t->size; int d,tex; for(d=0,tex=0; d<t->size*3; d+=3,tex+=2) { sgp->node[i].vertex[d] = t->data[d]; sgp->node[i].vertex[d+1] = t->data[d+1]; sgp->node[i].vertex[d+2] = t->data[d+2]; sgp->node[i].texture[tex] = t->data[d+t->size*6]; sgp->node[i].texture[tex+1] = t->data[d+t->size*6+1]; } sgp->node[i].obj_pos[0] = 0; sgp->node[i].obj_pos[1] = 0; sgp->node[i].obj_pos[2] = 0; sgp->node[i].obj_pos[3] = 1; sgp->node[i].angle[0] = 0; sgp->node[i].angle[1] = 0; sgp->node[i].angle[2] = 0; sgp->node[i].angle[3] = 1; for(int tm=0; tm<16; tm++) { sgp->node[i].translation[tm] = 0; } sgp->node[i].id = 0; sgp->node[i].move = 0; sgp->node[i].interaction = 0; sgp->node[i].pn = nnpn; if(t->child != NULL) { nnpn = i; t = t->child; } else if(t->brother != NULL) { nnpn = sgp->node[i].pn; t = t->brother; } else { while(t) { if(t->brother != NULL) { t = t->brother; break; } else { if(t->parent == NULL) { t = NULL; break; } nnpn = sgp->node[nnpn].pn; t = t->parent; } } } //printf("sgp->node[%d].pn = %d\n", i, sgp->node[i].pn); i++; } sgp->info.size = i; //for(int s=0; s<i; s++) //{ //printf("sgp.node[%d].pn = %d\n",s,sgp.node[s].pn); //} //delete sgp; } */ void Polygon::add_next() { Polygon *p; p = new Polygon; next = p; } void Polygon::create_tree() { Polygon *list; Polygon *check_list; Polygon *p; Polygon *bros; check_list = this; for(list=this; list; list=list->next) { if(xmlStrcmp((xmlChar *)list->parent_name, (xmlChar *)"NULL")) { p = this; while(p) { if(!xmlStrcmp((xmlChar *)p->name,(xmlChar *)list->parent_name)) { list->parent = p; if(p->child == NULL) { p->child = list; } else { bros = p->child; while(bros->brother != NULL) { bros = bros->brother; } bros->brother = list; } break; } p = p->next; } } } } /* void Polygon::create_scene_graph_pack() { SceneGraphPack sgp; int i = 0; int nnpn = -1; Polygon *t; t = this; while(t) { //t->draw(); SceneGraphNode node; node.obj_pos[0] = 0; node.obj_pos[1] = 0; node.obj_pos[2] = 0; node.obj_pos[3] = 1; for(int tm=0; tm<16; tm++) { node.translation[tm] = 0; } node.id = 0; node.move = 0; node.interaction = 0; for(int a=0; a<10; a++) { node.op[a] = -1; } node.pn = nnpn; int p = 0; if(t->child != NULL) { //glPushMatrix(); //node.op[p] = PUSH; //nnpn = i; t = t->child; } else if(t->brother != NULL) { //glPopMatrix(); //glPushMatrix(); //node.op[p] = SHIFT; //nnpn = node.pn; t = t->brother; } else { while(t) { if(t->brother != NULL) { //glPopMatrix(); //glPushMatrix(); //node.op[p] = SHIFT; t = t->brother; break; } else { t = t->parent; if(t) { //glPopMatrix(); //node.op[p] = POP; //nnpn = sgp.node[nnpn].pn; p++; } } } } sgp.node[i] = node; i++; } sgp.info.size = i; for(int s=0; s<4; s++) { for(int a=0; sgp.node[s].op[a]!=-1; a++) { printf("sgp.node[%d].op[%d] = %d\n",s, a, sgp.node[s].op[a]); } //printf("sgp.node[%d].pn = %d\n",s,sgp.node[s].pn); } } */ void Polygon::pickup_coordinate(char *cont) { for(int n=0; n<size*3; n+=3) { cont = pickup_float(cont, data+n); cont = pickup_float(cont, data+n+1); cont = pickup_float(cont, data+n+2); if (cont == NULL) { cout << "Analyzing obj data failed coordinate\n"; } } } void Polygon::pickup_normal(char *cont) { for(int n=size*3;n<size*6;n+=3) { cont = pickup_float(cont,data+n); cont = pickup_float(cont,data+n+1); cont = pickup_float(cont,data+n+2); if (cont == NULL) { cout << "Analyzing obj data failed normal\n"; } } } void Polygon::pickup_model(char *cont) { cont = pickup_float(cont,c_xyz); cont = pickup_float(cont,c_xyz+1); cont = pickup_float(cont,c_xyz+2); if (cont == NULL) { cout << "Analyzing obj data failed model\n"; } } void Polygon::pickup_texture(char *cont) { for(int n=size*6; n<size*9; n+=3) { cont = pickup_float(cont,data+n); cont = pickup_float(cont,data+n+1); data[n+2] = 1.0; if (cont == NULL) { cout << "Analyzing obj data failed texture\n"; } } } char *get_pixel(int tx, int ty, SDL_Surface *texture_image) { return (char*)texture_image->pixels+(texture_image->format->BytesPerPixel*((texture_image->w)*ty+tx)); } unsigned my_ntohl(unsigned u) { // rr gg bb 00 // rr // bb gg rr //unsigned u1 = ((u&0xff)<<24) + // ((u&0xff00)<<8) + // ((u&0xff0000)>>8) + // ((u&0xff000000)>>24); unsigned u1; unsigned b = (u&0xff000000)>>24; unsigned g = (u&0xff0000)>>16; unsigned r = (u&0xff00)>>8; u1 = r + (g<<8) + (b<<16); //printf("pixel %x->%x\n",u,u1); return u1; } Uint32 Polygon::get_rgb(int tx, int ty) { SDL_PixelFormat *fmt; //Uint32 temp, pixel; Uint8 red, green, blue; fmt = texture_image->format; if (tx<0) tx = 0; if (texture_image->w-1< tx) tx = texture_image->w-1 ; if (ty<0) ty = 0; if (texture_image->h-1< ty) ty = texture_image->h-1 ; //SDL_LockSurface(texture_image); char *p = get_pixel(tx,ty,texture_image); #if 0 pixel = my_ntohl(*(Uint32*)p); //printf("pixel = %d\n", pixel); //printf("pixel %x bpp = %d ",p, fmt->BytesPerPixel); //SDL_UnlockSurface(texture_image); temp = pixel&fmt->Rmask; temp = temp>>fmt->Rshift; temp = temp<<fmt->Rloss; red = (Uint8)temp; temp = pixel&fmt->Gmask; temp = temp>>fmt->Gshift; temp = temp<<fmt->Gloss; green = (Uint8)temp; temp = pixel&fmt->Bmask; temp = temp>>fmt->Bshift; temp = temp<<fmt->Bloss; blue = (Uint8)temp; #endif blue = (Uint8) p[0]; green = (Uint8) p[1]; red = (Uint8) p[2]; //printf("tx = %d ty = %d ", tx,ty); //printf("pixel color => R: %d, G: %d, B: %d\n", red, green, blue); SDL_PixelFormat *pf; pf = viewer->screen->format; //cout << SDL_MapRGB(pf, red, green, blue) << endl; return SDL_MapRGB(pf, red, green, blue); } void Polygon::get_data(xmlNodePtr cur) { char *cont; //char *image_name; for(;cur;cur=cur->next) { if(!xmlStrcmp(cur->name,(xmlChar*)"coordinate")) { cont = (char *)xmlNodeGetContent(cur); pickup_coordinate(cont); } else if(!xmlStrcmp(cur->name,(xmlChar*)"normal")) { cont = (char *)xmlNodeGetContent(cur); pickup_normal(cont); } else if(!xmlStrcmp(cur->name,(xmlChar*)"model")) { cont = (char *)xmlNodeGetContent(cur); pickup_model(cont); } else if(!xmlStrcmp(cur->name,(xmlChar*)"texture")) { cont = (char *)xmlNodeGetContent(cur); pickup_texture(cont); } else if(!xmlStrcmp(cur->name,(xmlChar*)"image")) { char image_name[20] = "/tmp/image_XXXXXX"; int fd = mkstemp(image_name); FILE *outfile = fdopen(fd, "wb"); if(NULL == outfile) { cout << "error open file\n"; } cont = (char *)xmlNodeGetContent(cur); //decode(cont, image_name); decode(cont, outfile); fclose(outfile); texture_image = IMG_Load(image_name); //load_texture(image_name); if(unlink(image_name)) { cout << "unlink error\n"; } } } } void Polygon::create_data(xmlNodePtr cur) { size = atoi((char *)xmlGetProp(cur,(xmlChar *)"size")); name = (char *)xmlGetProp(cur,(xmlChar *)"name"); parent_name = (char *)xmlGetProp(cur,(xmlChar *)"parent"); next = NULL; data = new float[size*3*3]; get_data(cur->children); } void Polygon::set_data(char *file_name) { xmlDocPtr doc; xmlNodePtr cur; Polygon *tmp; doc = xmlParseFile(file_name); cur = xmlDocGetRootElement(doc); xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D"); tmp = this; for (cur=cur->children; cur; cur=cur->next) { if (!xmlStrcmp(cur->name,(xmlChar*)"surface")) { tmp->create_data(cur); if(cur->next->next) { tmp->add_next(); tmp = tmp->next; } } } create_tree(); //tree_check(); //create_scene_graph_pack(); xmlFreeDoc(doc); /* for(int s=0; s<sgp->info.size; s++) { printf("sgp->node[%d].pn = %d\n",s,sgp->node[s].pn); } */ //delete sgp; } void Polygon::delete_data() { Polygon *n,*m; n = this; delete [] n->data; if(next) { for(n = this->next; n; n=m) { m = n->next; delete [] n->data; delete n; } } }