arled
arled

Reputation: 2690

How can i draw a simple space craft shape in 3d?

i have a program that draws a simple pyramid like shape that i can rotate with my arrow keys but i want to transform this shape into a simple aircraft and instead of rotating i want it to move (fly) still with the arrow keys. how i can achieve this?

Here's what I have so far:

#include "shared/gltools.h"   // GLTools

#include "shared/math3d.h"    // 3D Math Library

// Rotation amounts
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;


// Change viewing volume and viewport.  Called when window is resized
void ChangeSize(int w, int h)
    {
    GLfloat fAspect;

    // Prevent a divide by zero
    if(h == 0)
        h = 1;

    // Set Viewport to window dimensions
    glViewport(0, 0, w, h);

    fAspect = (GLfloat)w/(GLfloat)h;

    // Reset coordinate system
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // Produce the perspective projection
    gluPerspective(35.0f, fAspect, 1.0, 40.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    }




// This function does any needed initialization on the rendering
// context.  Here it sets up and initializes the lighting for
// the scene.
void SetupRC()
    {
    GLbyte *pBytes;
    GLint iWidth, iHeight, iComponents;
    GLenum eFormat;

    // Light values and coordinates
    GLfloat  whiteLight[] = { 0.05f, 0.05f, 0.05f, 1.0f };
    GLfloat  sourceLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };
    GLfloat  lightPos[] = { -10.f, 5.0f, 5.0f, 1.0f };

    glEnable(GL_DEPTH_TEST);    // Hidden surface removal
    glFrontFace(GL_CCW);        // Counter clock-wise polygons face out
    glEnable(GL_CULL_FACE);     // Do not calculate inside

    // Enable lighting
    glEnable(GL_LIGHTING);

    // Setup and enable light 0
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
    glLightfv(GL_LIGHT0,GL_AMBIENT,sourceLight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    glEnable(GL_LIGHT0);

    // Enable color tracking
    glEnable(GL_COLOR_MATERIAL);

    // Set Material properties to follow glColor values
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

    // Black background
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

    // Load texture
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);



    pBytes = gltLoadTGA("stone.tga", &iWidth, &iHeight, &iComponents, &eFormat);        
    glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
    free(pBytes);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//try these too
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);   

    glEnable(GL_TEXTURE_2D);
    }

// Respond to arrow keys
void SpecialKeys(int key, int x, int y)
    {
    if(key == GLUT_KEY_UP)
        xRot-= 5.0f;

    if(key == GLUT_KEY_DOWN)
        xRot += 5.0f;

    if(key == GLUT_KEY_LEFT)
        yRot -= 5.0f;

    if(key == GLUT_KEY_RIGHT)
        yRot += 5.0f;

        xRot = (GLfloat)((const int)xRot % 360);
        yRot = (GLfloat)((const int)yRot % 360);

    // Refresh the Window
    glutPostRedisplay();
    }


// Called to draw scene
void RenderScene(void)
    {
    M3DVector3f vNormal;
        //defines the corner vertices of the pyramid
    M3DVector3f vCorners[5] = {
                            { 0.0f, 0.3f, 0.0f },     // Top          0

                              { -0.25f, 0.0f, -.25f },    // Back left     1

                              { 0.5f, 0.0f, -0.50f },    // Back right    2

                              { 0.25f, 0.0f, 0.25f },           // Front right   3


                              { -0.99f, 0.0f, 0.99f }};    // Front left    4

    // Clear the window with current clearing color
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Save the matrix state and do the rotations
    glPushMatrix();
        // Move object back and do in place rotation
        glTranslatef(0.0f, -0.25f, -4.0f);
        glRotatef(xRot, 1.0f, 0.0f, 0.0f);
        glRotatef(yRot, 0.0f, 1.0f, 0.0f);

        // Draw the Pyramid
        //try different colours
        glColor3f(1.0f, 1.0f, 1.0f);//a white pyramid
       // glColor3f(1.0f, 0.0f, 0.0f); // a red pyramid 
        //glColor3f(1.0,0.7,0.7);//reddish
        glBegin(GL_TRIANGLES);

            // Bottom section - two triangles

            glNormal3f(0.0f, -1.0f, 0.0f);
            glTexCoord2f(1.0f, 1.0f);
            glVertex3fv(vCorners[2]);

            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[4]);

            glTexCoord2f(0.0f, 1.0f);
            glVertex3fv(vCorners[1]);


            glTexCoord2f(1.0f, 1.0f);
            glVertex3fv(vCorners[2]);

            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[3]);

            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[4]);

        //Faces

            // Front Face
            m3dFindNormal(vNormal, vCorners[0], vCorners[4], vCorners[3]);
            glNormal3fv(vNormal);
            glTexCoord2f(0.5f, 1.0f);//notice the 0.5 here
            glVertex3fv(vCorners[0]);
            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[4]);
            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[3]);

            // Left Face
            m3dFindNormal(vNormal, vCorners[0], vCorners[1], vCorners[4]);
            glNormal3fv(vNormal);
             glTexCoord2f(0.5f, 1.0f);
            glVertex3fv(vCorners[0]);
            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[1]);
            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[4]);

            // Back Face
            m3dFindNormal(vNormal, vCorners[0], vCorners[2], vCorners[1]);
            glNormal3fv(vNormal);
            glTexCoord2f(0.5f, 1.0f);
            glVertex3fv(vCorners[0]);

            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[2]);

            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[1]);

            // Right Face
            m3dFindNormal(vNormal, vCorners[0], vCorners[3], vCorners[2]);
            glNormal3fv(vNormal);
            glTexCoord2f(0.5f, 1.0f);
            glVertex3fv(vCorners[0]);
            glTexCoord2f(0.0f, 0.0f);
            glVertex3fv(vCorners[3]);
            glTexCoord2f(1.0f, 0.0f);
            glVertex3fv(vCorners[2]);
        glEnd();


    // Restore the matrix state
    glPopMatrix();

    // Buffer swap
    glutSwapBuffers();
    }



int main(int argc, char *argv[])
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Textured Pyramid");
    glutReshapeFunc(ChangeSize);
    glutSpecialFunc(SpecialKeys);
    glutDisplayFunc(RenderScene);
    SetupRC();
    glutMainLoop();

    return 0;
    }

Upvotes: 0

Views: 997

Answers (3)

Michael Dorgan
Michael Dorgan

Reputation: 12515

{0,0,0},{3,3,0},{-3,3,0}

There's a vertice list for a very simple 3D splaceship - a triangle. You can use this to create a VBO, or just plug it in manually and glDrawArray() it. :)

Upvotes: 0

jheriko
jheriko

Reputation: 3113

This is a pretty big question... and spectacularly lazy.

Other answers have covered the modelling aspect... although not very well. For something more complicated than the triangle (which is an excellent start point, as suggested, to get things working) I'd suggest an OBJ loader. The format is simple, uses text and can be loaded using simple string manipulation to extract the values.

Now, to make the thing move you need to either dynamically update your model's vertices or learn about transformations and the vertex pipeline. You can either move the camera or move the world around the camera - either way is equivalent. glRotate, glTranslate or glTransform can help, as can passing matrices into shaders.

Hopefully this is enough that with some thought or Googling you can fill in the rather large gaps. You are not likely to get a handholding through this to completion... if you have a rudimentary understanding of geometry (cartesian coordinates) and a little bit of API knowledge (glTranslate) it is not too hard though.

Upvotes: 0

cli_hlt
cli_hlt

Reputation: 7164

Well, you will have to model your "aircraft" or whatever it is in terms of vertices and connections thereof (i.e. triangles). Unless your brain is capable of imagining all the coordinates, I'm afraid, you will have to use some sort of software to do this for you (and I assume you are some kind of artist as well).

Then all you have to do is to write a loader for the file format your modeling software used to save your "aircraft", transform it to your coordinate system put the resulting vertices into your renderer and you will be good to go. Easy, isn't it?

Upvotes: 1

Related Questions