[4E6] Libertine

Started by
71 comments, last by XDigital 16 years ago
Wings3D has an own format, but it is possible to export your mesh in ASCII Wavefront format. I wrote a little obj-loader capable of reading the model. Here is the source, if you are interested - unfortunately there are some dependancies in this code, so that you have to modify it a little bit. But it should not be that difficult:

//---------------------------------------------------------------------------X_IO *X_ReadMeshWavefront(const char *filename){//---------------------------------------------------------------------------   int iXyz, iUv, iNrm, iTri;   int iLine,nLines;   X_IO *io = new X_IO;      printf("Reading Wavefront from file: %s ...",filename);   ifstream file(filename);      //Zaehlen der Vertexe und Dreiecke      iXyz = iUv = iNrm = iTri = 0;   iLine = nLines = 0;   if (!file.fail()){      string line, tmp;            io->t.nXyz = 0;      io->t.nUv  = 0;      io->t.nNrm = 0;      io->t.nTri = 0;            while (!file.eof()){         getline(file,line);         tmp = line.substr(0,3);                  if (!strcmp(line.substr(0,2).c_str(),"o "))  {;}         if (!strcmp(line.substr(0,2).c_str(),"v "))  {io->t.nXyz++; if (!iXyz) iXyz = iLine; }         if (!strcmp(line.substr(0,3).c_str(),"vt ")) {io->t.nUv++;  if (!iUv)  iUv  = iLine; }         if (!strcmp(line.substr(0,3).c_str(),"vn ")) {io->t.nNrm++; if (!iNrm) iNrm = iLine; }         if (!strcmp(line.substr(0,2).c_str(),"g "))  {;}         if (!strcmp(line.substr(0,2).c_str(),"f "))  {io->t.nTri++; if (!iTri) iTri = iLine; }         iLine++;      }            nLines = iLine;         io->t.bXyz        = true;      io->t.bUv         = true;      io->t.bSmoothNorm = true;      io->t.bTri        = true;      io->t.bSmoothTri  = true;      io->t.bNorm       = true;      io->t.bMid        = false;      io->t.bIndexXyz   = false;      io->t.bIndexTri   = false;      io->t.bScale      = true;   //Keine Skalierung         io->t.xyz        = new float*[io->t.nXyz];      io->t.uv         = new float*[io->t.nUv];      io->t.norm       = new float*[io->t.nTri];      io->t.smoothNorm = new float*[io->t.nNrm];      io->t.tri        = new int  *[io->t.nTri];      io->t.smoothTri = new int **[io->t.nTri];      io->t.mid        = new float*[io->t.nTri];         for (int i=0;i<io->t.nXyz;i++) io->t.xyz        = new float[3];      for (int i=0;i<io->t.nUv;i++)  io->t.uv         = new float[3];      for (int i=0;i<io->t.nTri;i++) io->t.norm       = new float[3];      for (int i=0;i<io->t.nNrm;i++) io->t.smoothNorm = new float[3];      for (int i=0;i<io->t.nTri;i++) io->t.tri        = new int[3];      for (int i=0;i<io->t.nTri;i++) io->t.smoothTri  = new int*[3];      for (int i=0;i<io->t.nTri;i++) io->t.mid        = new float[3];            for (int i=0;i<io->t.nTri;i++)         for (int j=0;j<3;j++)            io->t.smoothTri[j] = new int[3];   }   file.close();         FILE *fid;      fid = fopen(filename,"r");   iLine = 0;   if (fid){      while (iLine < nLines){         if (iLine >= nLines) break;         char temp_string[256];         if (iLine == iXyz){            for (int i=0;i<io->t.nXyz;i++){               fscanf(fid,"v %f %f %f\n",&io->t.xyz[0],&io->t.xyz[1],&io->t.xyz[2]);               iLine++;            }         }         if (iLine == iUv){            for (int i=0;i<io->t.nUv;i++){               fscanf(fid,"vt %f %f\n",&io->t.uv[0],&io->t.uv[1]);               iLine++;            }         }         if (iLine == iNrm){            for (int i=0;i<io->t.nNrm;i++){               fscanf(fid,"vn %f %f %f\n",&io->t.smoothNorm[0],&io->t.smoothNorm[1],&io->t.smoothNorm[2]);               iLine++;            }         }         if (iLine == iTri){            for (int i=0;i<io->t.nTri;i++){               fscanf(fid,"f %d/%d/%d %d/%d/%d %d/%d/%d\n",&io->t.smoothTri[0][0],&io->t.smoothTri[0][1],&io->t.smoothTri[0][2],                                                           &io->t.smoothTri[1][0],&io->t.smoothTri[1][1],&io->t.smoothTri[1][2],                                                           &io->t.smoothTri[2][0],&io->t.smoothTri[2][1],&io->t.smoothTri[2][2]);               iLine++;            }           }         iLine++;           fgets(temp_string,256,fid);      }            for (int i=0;i<io->t.nTri;i++)         for (int j=0;j<3;j++)            for (int k=0;k<3;k++)               io->t.smoothTri[j][k]--;      CheckMesh(io);            fclose(fid);            printf(" done.\n");      return io;   }   printf(" error.\n");      return NULL;}


The rendering function looks like this. I use display lists to render the meshes:

//------------------------------------------------------------------------void X_PrepareSmoothMeshList(X_IO *mesh, unsigned int listID){//------------------------------------------------------------------------   float norm1[3],norm2[3],norm3[3];   float xyz1[3],xyz2[3],xyz3[3];   float uv1[2],uv2[2],uv3[2];   int   tri1[3], tri2[3], tri3[3];   glNewList(listID,GL_COMPILE);      glPushMatrix();         for (int i=0;i<mesh->t.nTri;i++){            tri1[0] = mesh->t.smoothTri[0][0];            tri1[1] = mesh->t.smoothTri[1][0];            tri1[2] = mesh->t.smoothTri[2][0];            tri2[0] = mesh->t.smoothTri[0][1];            tri2[1] = mesh->t.smoothTri[1][1];            tri2[2] = mesh->t.smoothTri[2][1];            tri3[0] = mesh->t.smoothTri[0][2];            tri3[1] = mesh->t.smoothTri[1][2];            tri3[2] = mesh->t.smoothTri[2][2];            norm1[0] = mesh->t.smoothNorm[tri3[0]][0];            norm1[1] = mesh->t.smoothNorm[tri3[0]][1];            norm1[2] = mesh->t.smoothNorm[tri3[0]][2];            norm2[0] = mesh->t.smoothNorm[tri3[1]][0];            norm2[1] = mesh->t.smoothNorm[tri3[1]][1];            norm2[2] = mesh->t.smoothNorm[tri3[1]][2];            norm3[0] = mesh->t.smoothNorm[tri3[2]][0];            norm3[1] = mesh->t.smoothNorm[tri3[2]][1];            norm3[2] = mesh->t.smoothNorm[tri3[2]][2];            xyz1[0] = mesh->t.xyz[tri1[0]][0];            xyz1[1] = mesh->t.xyz[tri1[0]][1];            xyz1[2] = mesh->t.xyz[tri1[0]][2];            xyz2[0] = mesh->t.xyz[tri1[1]][0];            xyz2[1] = mesh->t.xyz[tri1[1]][1];            xyz2[2] = mesh->t.xyz[tri1[1]][2];            xyz3[0] = mesh->t.xyz[tri1[2]][0];            xyz3[1] = mesh->t.xyz[tri1[2]][1];            xyz3[2] = mesh->t.xyz[tri1[2]][2];            uv1[0]  = mesh->t.uv[tri2[0]][0];            uv1[1]  = mesh->t.uv[tri2[0]][1];            uv2[0]  = mesh->t.uv[tri2[1]][0];            uv2[1]  = mesh->t.uv[tri2[1]][1];            uv3[0]  = mesh->t.uv[tri2[2]][0];            uv3[1]  = mesh->t.uv[tri2[2]][1];            glBegin(GL_TRIANGLES);               glNormal3fv(norm1); glTexCoord2fv(uv1); glVertex3fv(xyz1);               glNormal3fv(norm2); glTexCoord2fv(uv2); glVertex3fv(xyz2);               glNormal3fv(norm3); glTexCoord2fv(uv3); glVertex3fv(xyz3);            glEnd();         }      glPopMatrix();   glEndList();   }
Advertisement
Quote:Original post by XDigital
you have to modify it a little bit. But it should not be that difficult


Okay.. I'll just go hide under my bed and after I come back the code will modify itself and tell me that "obj-loader" and "ASCII Wavefront format" are just some random words I shouldn't be afraid of.. They can't hurt me.. If they come I'll just hide under my bed where no one can find me, and wait.. haha, ha.. :]


No but seriously.. Thanks, it was really generous of you to share that.. Keep up your good work, and best luck in the contest..

PS: If you need me, I'm under the bed.. (Don't tell anyone!)
Hmm. What I wanted to say with "not that difficult" is, that you have to make your own X_IO structure. This structure is part of my function conglomeration (I do not want to call it engine). You can also skip the "CheckMesh(io)" function call, it is just to calculate normals and similar stuff for different mesh formates (milkshape has less information than wavefront). Attached you find the X_IO structure with comments in native Mandarin if you are able to read...

have fun

typedef struct{   float **mat;   int row, col;} MATRIX;typedef struct{   bool    bTri,bXyz,bNorm,bMid,bUv,bIndexTri,bIndexXyz; //Schalter fuer MakeMesh   bool    bSmoothNorm,bScale,bSmoothTri;                //Schalter fuer MakeMesh   int     nTri,nXyz,nUv,nNrm;                           //Anzahl der Dreiecke, Koordinaten, Texturkoordinaten, Normalenvektoren   float   scale;                                        //Skalierung   int   **tri;                                          //Triangulierung   int   ***smoothTri;                                   //Erweiterte Triangulierung mit Normalenvektor und Texturkoordinaten   float **xyz;                                          //Kooridnaten   float **norm;                                         //Normalenvektor   float **smoothNorm;                                   //Normalenvektor auf Vertex   float **mid;                                          //Mittelpunktskoordinaten   float **uv;                                           //Texturkoordinaten   int   *indexTri;                                      //Index der Triangulierung   int   *indexXyz;                                      //Index der Vertexe} TRIANGLES;typedef struct{   GLubyte *imageData;                                   // Image Data (Up To 32 Bits)   GLuint  bpp;                                          // Image Color Depth In Bits Per Pixel.   GLuint  width;                                        // Image Width   GLuint  height;                                       // Image Height   GLuint  texID;    GLuint  base;                                         // Texture ID Used To Select A Texture} TEXTURE;typedef struct{   MATRIX    m;   TRIANGLES t;   TEXTURE   tex;} X_IO;
The following screen shots show the basic quest functionality. You can see three outtakes from the logbook. The first at the beginning with the initial quest, the second on Holstein with the reward from the quest and the third right before the Hay Nebula. Its kinda buggy but the first steps are done. This is going to be the first playable item of Libertine. I'm a little bit proud, because it becomes more and more a "game".



Follow the link, if you like. I posted some issues on my blog http://gevatter.wordpress.com
Hey XDigital, I'm aersixb9 and I'm making a game that's almost the same as yours! You can read about it in the "Space Ponies" thread. I had a few questions about your game, that I couldn't tell from the screenshots - what kind of draw distance (clip distance?) are you using in your game? I saw some planets that looked pretty cool, so I assume you're using nice big maps just like me! I think we need more space games. Also, what kind of flight physics are you using? Newtonian? If you're not using Newtonian physics, you really should!!! Anyways, if you want to use WWII physics like wing commander, that's okay too.

How did you solve the problem of the map being too big?

Are warp drives REALLY necessary? Could you just have ships with sufficient thrust to travel between planets instead?

From what I've read about you, you seem to be a great programmer. I give your design skills a C+. Good enough for industry, and probably good enough to pwn me in this contest..actually, maybe a B-...although I still don't know very much about your game, except what you've written here.

Anyways, I'll keep commenting on your game, if you don't mind too much. How long until I get a playable version? I'm on WinXP, if that matters. :)

Have you tried easier APIs than OpenGL? I'm using Dark GDK and Visual Studio 2008 express, and I find the Dark GDK lets me focus on the game and design, and much less on hacking vertex code, although you've probably already wrapped the vertex/index functions with your own functions that make it a bit easier. Why aren't you employed full time as a programmer (are you?), and how do you have enough time to write complex 3D games in your spare time? Have you ever tried selling a game, either to a company or via the web? I got a great offer once from a local games company after I sent my "resume" (actually a 3D program I wrote in C# and D3D) around to a bunch of companies. I'm not college trained, but I can hack code in 3D :) I would have joined that company, but they wanted me to work 50+ hours per week, and I'm more of a 10 hour per week programmer. ;0

*-----------------------sig------------Visit my web site (Free source code and games!) @ http://SpaceRacer2025.blogspot.com--------------------------------------*
hi aersixb9,
thanks for the feedback. Here are some answers to the loads of questions:
The physics used is finished in theory but not in game. I'm going to use a selfmade multi body kinetics algorithm, which should be possible to handle the complete KI "just" with body interaction and influence spheres. Newtonian is at least a derivative of these interaction equations (6 degrees of freedom each body). This ODE system shall calculate for each element in space the next position and a control law for each body tries to accelerate, yaw, pitch etc the spacecraft to reach this point. It's kinda tough brainf*ck, but should be managable (hopefully). Right now, my complete physics library has to be ported to <vector> template class, which I started using a few weeks ago.

Quote:
Are warp drives REALLY necessary? Could you just have ships with sufficient thrust to travel between planets instead?


The complete game is designed to play it in 20 hours (I think this is mentioned in the rules). Therefor the player has not the time to wait until the spacecraft is accelerated to lightspeed to fly from one planet to another. It would be great, if one mission just takes less than 10 minutes to complete. The warpdrive is a way to fullfill this design criteria. However, my brain is too little to think about visual effects during light speed.

Quote:
From what I've read about you, you seem to be a great programmer. I give your design skills a C+. Good enough for industry, and probably good enough to pwn me in this contest..actually, maybe a B-...although I still don't know very much about your game, except what you've written here.


Well, ehm. Thanks. To be honest. I am the worst C++ programmer on earth. What you see on the screens is just OpenGL code of the shelf. I never tried shaders nor templates. Don't ask me about properties in classes and char* is my personal antichrist.

Quote:
Have you tried easier APIs than OpenGL? I'm using Dark GDK and Visual Studio 2008 express, and I find the Dark GDK lets me focus on the game and design, and much less on hacking vertex code, although you've probably already wrapped the vertex/index functions with your own functions that make it a bit easier.


Hmm, Visual Studio is not cross platform, OpenGL and Eclipse is. Creating a game just from scratch is a big challenge and I learn very much out of it. Using libraries like Ogre or other stuff would be like using a black box. That's not enough fun. You might finish a game, but have you learned creating a quest class? Do you know afterwards how to design a mesh loader? Have you knwoledge of making a LOD algorithm? Do you know the advantages of display lists, vertex arrays or triangle classes?

Ok, christmas vacation started yesterday. Times running.
See you in space.
XDigital
Quote:Original post by aersixb9
The warpdrive is a way to fullfill this design criteria. However, my brain is too little to think about visual effects during light speed.


Doppler shifts would make the colors of objects around you change. Objects that are coming towards the ship would be blueshifted (your destination would probably be blueshifted into the ultraviolet at lightspeed, and possibly even the cosmic microwave background might be visible) and objects going away from you (i.e. behind the ship) would be redshifed.

The rest is of course speculation, depending on how quickly your ship is actually moving.
What if you just ignore einstein (since we're using newtonian physics) and accelerate smoothly through the speed of light as if it's not even there? That is to say, if your thrust is 3*10^9 m/(s^2), and you accelerate for 3 seconds... (that's using the big engine, of course!) Then you'd get there much faster than the speed of light.

Anyways, warp drives are cool too. I didn't really get that physics explanation - how is the ship piloted? What are the controls like? If you stop thrusting and rotate, do you keep moving in the original direction? Is there friction? If you keep thrusting, does your speed keep increasing, or is your speed capped at a maximum speed? If you stop thrusting, does the pony continue at the same speed as it was going at the time you stopped thrusting, requiring reverse-thrust for an equal amount of time as the original thrust?

Edit: I read the rules, and I don't see a 20 hour limit...I hope my game is fun for that long, though! :) It currently takes anywhere between 1 minute and 25 minutes to fly from the earth to the moon if you're a good pilot (or at least as good as me) and using the thrust of the range of engines provided (currently) in my game...I'm thinking of a "sandbox" style game where you can trade goods with earth and the moon, attack/rob other ships, and fight off police ships that attack you, and also fight off other ships that attack you (the pirates)...are missions and/or quests a requirement? I was just going to have a "good" ai (we'll see how good it is...) that controls each of the 500 AI ships, each with their own agenda - ferrying goods, protecting ships, or raiding ships...I guess the protectors will fly towards explosions and attack the player if he's attacking another ship, although I want them to "see" what's going on, and not just notice it magically...although they might just notice it magically! That wouldn't be as neat, though. Naturally you accumulate currency through trading/robbing/protecting which you can use to upgrade your pony or buy new, bigger horsies, giving the game some replay value. If time permits, I'd also like to make an MMO version, with maybe 100-500 player caps (depending on things like the network speed and how good I can optimize the network code and how fast the server is)...maybe 60 players...heh...okay, okay, with my programming skills I'll be lucky to get 3 or 4 people in there at the same time...:)

PS - I totally disagree with reinventing the wheel and learning vertex programming. I mean I don't wind the wire and smelt the transistors for my microprocessor, I just buy it and plug it in. I think APIs should be that way too. :) If I never see vertexes again I'll be happy!
*-----------------------sig------------Visit my web site (Free source code and games!) @ http://SpaceRacer2025.blogspot.com--------------------------------------*
Hey XDigital, sorry to bother you, but I have a question that was disturbing me earlier.. I saw your 4e5 entry on your site when I was looking at some of the other stuff you did. It looks really nice, I'm just wondering how you did and why it didn't get first place? (I'm just going by the screenshot as I don't have access to the game itself from gamedev).

Good luck on Libertine btw.. it's coming together quite nice! I couldn't pull off a space game to save my life =/
I made a Logo for Libertine. What is a game without a Logo?!??
What do you think?



@xlinear: to win a contest, you have to enter... the last year entry was not finished.

This topic is closed to new replies.

Advertisement