int Game_Main(void *parms)
{
// this is the workhorse of your game it will be called
// continuously in real-time this is like main() in C
// all the calls for you game go here!

static MATRIX4X4 mrot;   // general rotation matrix

// these are used to create a circling camera
static float view_angle = 0; 
static float camera_distance = 6000;
static VECTOR4D pos = {0,0,0,0};
static float tank_speed;
static float turning = 0;

char work_string[256]; // temp string

int index; // looping var

// start the timing clock
Start_Clock();

// clear the drawing surface 
DDraw_Fill_Surface(lpddsback, 0);

// draw the sky
Draw_Rectangle(0,0, WINDOW_WIDTH-1, WINDOW_HEIGHT/2, RGB16Bit(0,140,192), lpddsback);

// draw the ground
Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, RGB16Bit(103,62,3), lpddsback);

// read keyboard and other devices here
DInput_Read_Keyboard();

// game logic here...

// reset the render list
Reset_RENDERLIST4DV1(&rend_list);

// allow user to move camera

// turbo
if (keyboard_state[DIK_SPACE])
    tank_speed = 5*TANK_SPEED;
else
    tank_speed = TANK_SPEED;

// forward/backward
if (keyboard_state[DIK_UP])
   {
   // move forward
   cam.pos.x += tank_speed*Fast_Sin(cam.dir.y);
   cam.pos.z += tank_speed*Fast_Cos(cam.dir.y);
   } // end if

if (keyboard_state[DIK_DOWN])
   {
   // move backward
   cam.pos.x -= tank_speed*Fast_Sin(cam.dir.y);
   cam.pos.z -= tank_speed*Fast_Cos(cam.dir.y);
   } // end if

// rotate
if (keyboard_state[DIK_RIGHT])
   {
   cam.dir.y+=3;
   
   // add a little turn to object
   if ((turning+=2) > 15)
      turning=15;

   } // end if

if (keyboard_state[DIK_LEFT])
   {
   cam.dir.y-=3;

   // add a little turn to object
   if ((turning-=2) < -15)
      turning=-15;

   } // end if
else // center heading again
   {
   if (turning > 0)
       turning-=1;
   else
   if (turning < 0)
       turning+=1;

   } // end else

// generate camera matrix
Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX);

// insert the tanks in the world
for (index = 0; index < NUM_TANKS; index++)
    {
    // reset the object (this only matters for backface and object removal)
    Reset_OBJECT4DV1(&obj_tank);

    // generate rotation matrix around y axis
    Build_XYZ_Rotation_MATRIX4X4(0, tanks[index].w, 0, &mrot);

    // rotate the local coords of the object
    Transform_OBJECT4DV1(&obj_tank, &mrot, TRANSFORM_LOCAL_TO_TRANS,1);

    // set position of tank
    obj_tank.world_pos.x = tanks[index].x;
    obj_tank.world_pos.y = tanks[index].y;
    obj_tank.world_pos.z = tanks[index].z;

    // attempt to cull object   
    if (!Cull_OBJECT4DV1(&obj_tank, &cam, CULL_OBJECT_XYZ_PLANES))
       {
       // if we get here then the object is visible at this world position
       // so we can insert it into the rendering list
       // perform local/model to world transform
       Model_To_World_OBJECT4DV1(&obj_tank, TRANSFORM_TRANS_ONLY);

       // insert the object into render list
       Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_tank);
       } // end if
 
    } // end for

// insert the player into the world
// reset the object (this only matters for backface and object removal)
Reset_OBJECT4DV1(&obj_player);

// set position of tank
obj_player.world_pos.x = cam.pos.x+300*Fast_Sin(cam.dir.y);
obj_player.world_pos.y = cam.pos.y-70;
obj_player.world_pos.z = cam.pos.z+300*Fast_Cos(cam.dir.y);

// generate rotation matrix around y axis
Build_XYZ_Rotation_MATRIX4X4(0, cam.dir.y+turning, 0, &mrot);

// rotate the local coords of the object
Transform_OBJECT4DV1(&obj_player, &mrot, TRANSFORM_LOCAL_TO_TRANS,1);

// perform world transform
Model_To_World_OBJECT4DV1(&obj_player, TRANSFORM_TRANS_ONLY);

// insert the object into render list
Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_player);


// insert the towers in the world
for (index = 0; index < NUM_TOWERS; index++)
    {
    // reset the object (this only matters for backface and object removal)
    Reset_OBJECT4DV1(&obj_tower);

    // set position of tower
    obj_tower.world_pos.x = towers[index].x;
    obj_tower.world_pos.y = towers[index].y;
    obj_tower.world_pos.z = towers[index].z;

    // attempt to cull object   
    if (!Cull_OBJECT4DV1(&obj_tower, &cam, CULL_OBJECT_XYZ_PLANES))
       {
       // if we get here then the object is visible at this world position
       // so we can insert it into the rendering list
       // perform local/model to world transform
       Model_To_World_OBJECT4DV1(&obj_tower);

       // insert the object into render list
       Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_tower);
       } // end if
 
    } // end for

// seed number generator so that modulation of markers is always the same
srand(13);

// insert the ground markers into the world
for (int index_x = 0; index_x < NUM_POINTS_X; index_x++)
    for (int index_z = 0; index_z < NUM_POINTS_Z; index_z++)
        {
        // reset the object (this only matters for backface and object removal)
        Reset_OBJECT4DV1(&obj_marker);

        // set position of tower
        obj_marker.world_pos.x = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_x*POINT_SIZE;
        obj_marker.world_pos.y = obj_marker.max_radius;
        obj_marker.world_pos.z = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_z*POINT_SIZE;

        // attempt to cull object   
        if (!Cull_OBJECT4DV1(&obj_marker, &cam, CULL_OBJECT_XYZ_PLANES))
           {
           // if we get here then the object is visible at this world position
           // so we can insert it into the rendering list
           // perform local/model to world transform
           Model_To_World_OBJECT4DV1(&obj_marker);

           // insert the object into render list
           Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_marker);
           } // end if

        } // end for

// remove backfaces
Remove_Backfaces_RENDERLIST4DV1(&rend_list, &cam);

// apply world to camera transform
World_To_Camera_RENDERLIST4DV1(&rend_list, &cam);

// apply camera to perspective transformation
Camera_To_Perspective_RENDERLIST4DV1(&rend_list, &cam);

// apply screen transform
Perspective_To_Screen_RENDERLIST4DV1(&rend_list, &cam);

sprintf(work_string,"pos:[%f, %f, %f] heading:[%f] elev:[%f]", 
        cam.pos.x, cam.pos.y, cam.pos.z, cam.dir.y, cam.dir.x); 

Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-20, RGB(0,255,0), lpddsback);

// draw instructions
Draw_Text_GDI("Press ESC to exit. Press Arrow Keys to Move. Space for TURBO.", 0, 0, RGB(0,255,0), lpddsback);

// lock the back buffer
DDraw_Lock_Back_Surface();

// render the object
Draw_RENDERLIST4DV1_Wire16(&rend_list, back_buffer, back_lpitch);

// unlock the back buffer
DDraw_Unlock_Back_Surface();

// flip the surfaces
DDraw_Flip();

// sync to 30ish fps
Wait_Clock(30);

// check of user is trying to exit
if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE])
    {
    PostMessage(main_window_handle, WM_DESTROY,0,0);
    } // end if

// return success
return(1);
 
} // end Game_Main
Пример #2
0
static void display(void)
{
    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    static float view_angle = 0;
    static float camera_distance = 6000;
    static VECTOR4D pos = { 0, 0, 0, 0 };
    static float tank_speed;
    static float turning = 0;

    if (keyboard_state[VK_SPACE])
        tank_speed = 5 * TANK_SPEED;
    else
        tank_speed = TANK_SPEED;

    // forward/backward
    if (keyboard_state['W'] || keyboard_state['w'])
    {
        // move forward
        cam.pos.x -= tank_speed*Fast_Sin(cam.dir.y);
        cam.pos.z -= tank_speed*Fast_Cos(cam.dir.y);
    } // end if

    if (keyboard_state['S'] || keyboard_state['s'])
    {
        // move backward
        cam.pos.x += tank_speed*Fast_Sin(cam.dir.y);
        cam.pos.z += tank_speed*Fast_Cos(cam.dir.y);
    } // end if

    // rotate
    if (keyboard_state['D'] || keyboard_state['d'])
    {
        cam.dir.y -= TANK_ROTATE_SPEED;

        // add a little turn to object
        if ((turning -= 2) < -15)
            turning = -15;

    } // end if

    if (keyboard_state['a'] || keyboard_state['A'])
    {
        cam.dir.y += TANK_ROTATE_SPEED;

        // add a little turn to object
        if ((turning += 2) > 15)
            turning = 15;

    } // end if
    else // center heading again
    {
        if (turning > 0)
            turning -= 1;
        else if (turning < 0)
            turning += 1;

    } // end else

    //cam.dir.y += 0.05;
    //if (cam.dir.y > 360)
    //	cam.dir.y = 0;

    //Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX);
    //Rotate_XYZ_OBJECT4DV1(&obj, 0, 1, 0);
    //Model_To_World_OBJECT4DV1(&obj);
    //Reset_OBJECT4DV1(&obj);
    //Cull_OBJECT4DV1(&obj, &cam, CULL_OBJECT_X_PLANE | CULL_OBJECT_Y_PLANE | CULL_OBJECT_Z_PLANE);
    //Remove_Backfaces_OBJECT4DV1(&obj, &cam);
    //World_To_Camera_OBJECT4DV1(&obj, &cam);
    //Camera_To_Perspective_Screen_OBJECT4DV1(&obj, &cam);
    //memset(buffer, 0, sizeof(UINT)* WINDOW_WIDTH * WINDOW_HEIGHT);
    for (int i = 0; i < g_width * g_height; ++i)
    {
        buffer[i] = 0;// 0xffffffff;
    }
    //Draw_OBJECT4DV1_Solid(&obj, (UCHAR *)buffer, WINDOW_WIDTH);
    //Draw_OBJECT4DV1_Wire(&obj, (UCHAR *)buffer, WINDOW_WIDTH);
    //glBindVertexArray(VAOs[VAO_1]);
    //glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
    //glBufferData(GL_ARRAY_BUFFER, sizeof(POINT4D)* obj.num_vertices, obj.vlist_trans, GL_DYNAMIC_DRAW);
    ////glDrawArrays(GL_TRIANGLES, 0, obj.num_polys);

    //int polys = 0;
    //for (int i = 0, j = 0; i < obj.num_polys; ++i)
    //{Z
    //	if (!(obj.plist[i].state & POLY4DV1_STATE_ACTIVE) || (obj.plist[i].state & POLY4DV1_STATE_CLIPPED)
    //		|| (obj.plist[i].state & POLY4DV1_STATE_BACKFACE))
    //		continue;
    //	indexBuffer[j++] = obj.plist[i].vert[0];
    //	indexBuffer[j++] = obj.plist[i].vert[1];
    //	indexBuffer[j++] = obj.plist[i].vert[2];
    //	++polys;
    //}

    //glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)* 3 * polys, indexBuffer, GL_STATIC_DRAW);

    //glDrawElements(GL_TRIANGLES, polys * 3, GL_UNSIGNED_INT, 0);
    //glFlush();

    Reset_RENDERLIST4DV1(&rend_list);

    static MATRIX4X4 mrot;   // general rotation matrix

    // generate camera matrix
    Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX);

    // insert the tanks in the world
    for (int index = 0; index < NUM_TANKS; index++)
    {
        // reset the object (this only matters for backface and object removal)
        Reset_OBJECT4DV1(&obj_tank);

        // generate rotation matrix around y axis
        Build_XYZ_Rotation_MATRIX4X4(0, tanks[index].y, 0, &mrot);

        // rotate the local coords of the object
        Transform_OBJECT4DV1(&obj_tank, &mrot, TRANSFORM_LOCAL_TO_TRANS, 1);

        // set position of tank
        obj_tank.world_pos.x = tanks[index].x;
        obj_tank.world_pos.y = tanks[index].y;
        obj_tank.world_pos.z = tanks[index].z;

        // attempt to cull object
        if (!Cull_OBJECT4DV1(&obj_tank, &cam, CULL_OBJECT_XYZ_PLANES))
        {
            // if we get here then the object is visible at this world position
            // so we can insert it into the rendering list
            // perform local/model to world transform
            Model_To_World_OBJECT4DV1(&obj_tank, TRANSFORM_TRANS_ONLY);
            // insert the object into render list
            Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_tank);
        } // end if

    } // end for

    // insert the player into the world
    // reset the object (this only matters for backface and object removal)
    Reset_OBJECT4DV1(&obj_player);

    // set position of tank
    obj_player.world_pos.x = cam.pos.x - 300 * Fast_Sin(cam.dir.y);
    obj_player.world_pos.y = cam.pos.y - 70;
    obj_player.world_pos.z = cam.pos.z - 300 * Fast_Cos(cam.dir.y);

    // generate rotation matrix around y axis
    Build_XYZ_Rotation_MATRIX4X4(0, cam.dir.y + turning, 0, &mrot);


    //lights[0].pos.x = 300 * Fast_Sin(cam.dir.y);
    //lights[0].pos.z = 300 * Fast_Cos(cam.dir.y);

    // rotate the local coords of the object
    Transform_OBJECT4DV1(&obj_player, &mrot, TRANSFORM_LOCAL_TO_TRANS, 1);

    // perform world transform
    Model_To_World_OBJECT4DV1(&obj_player, TRANSFORM_TRANS_ONLY);

    Cull_OBJECT4DV1(&obj_player, &cam, CULL_OBJECT_XYZ_PLANES);

    // insert the object into render list
    Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_player);

    // insert the towers in the world
    for (int index = 0; index < NUM_TOWERS; index++)
    {
        // reset the object (this only matters for backface and object removal)
        Reset_OBJECT4DV1(&obj_tower);

        // set position of tower
        obj_tower.world_pos.x = towers[index].x;
        obj_tower.world_pos.y = towers[index].y;
        obj_tower.world_pos.z = towers[index].z;

        // attempt to cull object
        if (!Cull_OBJECT4DV1(&obj_tower, &cam, CULL_OBJECT_XYZ_PLANES))
        {
            // if we get here then the object is visible at this world position
            // so we can insert it into the rendering list
            // perform local/model to world transform
            Model_To_World_OBJECT4DV1(&obj_tower);

            // insert the object into render list
            Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_tower);
        } // end if

    } // end for

    // seed number generator so that modulation of markers is always the same
    srand(13);

    // insert the ground markers into the world
    for (int index_x = 0; index_x < NUM_POINTS_X; index_x++)
        for (int index_z = 0; index_z < NUM_POINTS_Z; index_z++)
        {
            // reset the object (this only matters for backface and object removal)
            Reset_OBJECT4DV1(&obj_marker);

            // set position of tower
            obj_marker.world_pos.x = RAND_RANGE(-100, 100) - UNIVERSE_RADIUS + index_x*POINT_SIZE;
            obj_marker.world_pos.y = obj_marker.max_radius;
            obj_marker.world_pos.z = RAND_RANGE(-100, 100) - UNIVERSE_RADIUS + index_z*POINT_SIZE;

            // attempt to cull object
            if (!Cull_OBJECT4DV1(&obj_marker, &cam, CULL_OBJECT_XYZ_PLANES))
            {
                // if we get here then the object is visible at this world position
                // so we can insert it into the rendering list
                // perform local/model to world transform
                Model_To_World_OBJECT4DV1(&obj_marker);

                // insert the object into render list
                Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_marker);
            } // end if

        } // end for

    // remove backfaces
    Remove_Backfaces_RENDERLIST4DV1(&rend_list, &cam);

    // apply world to camera transform
    World_To_Camera_RENDERLIST4DV1(&rend_list, &cam);

    Sort_RENDERLIST4DV1(&rend_list, SORT_POLYLIST_NEARZ);

    Light_RENDERLIST4DV1_World(&rend_list, &cam, lights, 1);

    Camera_To_Perspective_Screen_RENDERLIST4DV1(&rend_list, &cam);

    Draw_RENDERLIST4DV1_Wire(&rend_list, (UCHAR *)buffer, g_width);
    //Draw_RENDERLIST4DV1_Solid(&rend_list, (UCHAR *)buffer, g_width);

    glDrawPixels(g_width, g_height, GL_BGRA, GL_UNSIGNED_BYTE, buffer);

    glutSwapBuffers();
}