游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2071|回复: 2

我在编译一个小程序时老是出错,请各位大侠指教.

[复制链接]

5

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2004-2-28 10:16:00 | 显示全部楼层 |阅读模式
正在看 Dx教程1-13,其中第三章的源代码编译的时候老是说:
project3 fatal error LNK1104: cannot open file 'libci.lib'
我不知道是怎么回事。我的系统是WinXp+VS2003,第三章原文如下:

第三章: 旋转的立方体

Introduction (序)
上一章,我们绘制了一个2D的三角形,很漂亮。这回呢,我们要创建我们的第一个3D对象:立方体。为了要显示它是真正的3D对象,呵呵,我们要旋转它,这样,你将会看到它的各个面。记住:所有的3D对象都是由三角形构成的(译者:神奇的三角形啊…读者:又来了),所以,我们的立方体是由12个三角形构成的(6个面,每个面需要2个三角形,二六一十二,乘法口诀,会不?)。


3D World Space (3D 世界空间)
上一章我们见到了左手3D迪卡尔坐标系统是怎样工作的,此坐标系统从现在开始将被我们应用。
DirectX的默认是左手坐标系统,以后我们就用左手坐标系统。至于左手坐标系统和右手坐标系统的差别,在此就不多说了,伸出手来就知道了。


Backface Culling (背面拣选)
什么是背面拣选?这是其实是一个很简单的概念。就是:所有的三角形面,面向我们的面将会被渲染出来(可见),否则将不被渲染(不可见,被拣选出来了)。多么简练的一句话,如果你没明白,我举个例子:假如空间中有一个正方形面(要想象成一块方形纸片),我们把正面涂成红色,背面涂成蓝色,你把它拿在手里,如果你没有弄弯它,那你始终只会看见面向你的那个面,而不会看见它背面(有透视眼者另当别论)。那么这个“背面拣选”在Direct3D中有什么用呢?假如我们创建了一个封闭的立方体(要想象成一个方纸盒),那末里面的六个面将不会被我们看见,所以,也不用被渲染。“背面拣选”将使渲染更有效率。

那么怎么知道那个面被渲染而哪个面被拣选(不渲染)呢?一切都在你定义的顶点的顺序上。下面的两幅图演示了如何定义“顺时针”的三角形。如果你定义的三角形是顺时针的,将会被渲染出来;但如果你把它翻过来,那它就变成逆时针的了,就不会被渲染出来。嗯,其实你可以指定哪个面将被拣选,顺时针或逆时针,但是DX默认是拣选逆时针的三角形。

   
Fig 3.1 Fig 3.2


How to make a cube (怎样创建立方体)
下面的两幅图演示了我们的立方体将被怎样创建出来。这里我们用了三个三角带:一个是顶,一个是四个连起来的面,一个是底。下面的图显示了每个三角形带及它们的顶点排列方法。顶点被排列成0到17,也会按照这个顺序被放到顶点缓冲中。还有一幅图显示了我们的立方体(Fig 3.4)。请注意图中哪些顶点重合了,还有就是除了立方体的底面之外的其它面都是顺时针的顶点排列。这是因为我们激活了上面提到的“背面拣选”。


Fig 3.3


Fig 3.4



Matrices (矩阵)
矩阵是什么呢?它其实是一个数学主题,所以,在此我只能简要地概括一下。矩阵就像是一个表格,有一定数目的行与列;每个格子中都一个数字或表达式。通过特定的矩阵,我们可以对3D对象中的顶点坐标进行运算,来实现类似移动、旋转、缩放这样的操作。详细内容请参考线性代数学。在DirectX中,矩阵都是4X4的表格。矩阵的类型有三种:World Matrix(世界矩阵)、View Matrix(视图矩阵) 和Projection Matrix(投影矩阵)。

World Matrix(世界矩阵)
你可以利用世界矩阵在3D空间(世界空间)里通过修改对象的坐标来完成它们的旋转、缩放或平移操作。所有这些操作(变换)都是关于原点(0, 0, 0)的。单一的变幻(例如平移或缩放等)可以组合起来,形成更复杂的变幻;但要注意各种变幻的顺序很重要,矩阵1X矩阵2和矩阵2X矩阵1是不同的。还有,当你完成了一项世界变幻的矩阵操作时,矩阵跟着将转变所有的顶点。要旋转两个对象,一个关于x轴,一个关于y轴,你应该先完成x轴的变幻,然后渲染第一个对象;再完成y轴的变幻,然后渲染第二个对象。

View Matrix(视图矩阵)
视图矩阵就是摄像机(或眼睛)。摄像机在世界空间中有一个位置,还有一个观察点。例如,你可以把摄像机悬置于某个对象的上面(摄像机位置),把镜头对准那个对象的中心(观察点)。你也可以指定哪面是上面,在我们下面的例子中,我们指定了y轴的正方向是上面。

Projection Matrix(投影矩阵)
投影矩阵可以被想象成摄像机的镜头,它指定了视界(field of view)和前、后裁剪平面。目前我们会在例子中保持一致的设置。



好了,第三章的源代码就在这了,又做了一些新的变化。
#include <d3dx8.h>

LPDIRECT3D8 g_pD3D = NULL;
LPDIRECT3DDEVICE8 g_pD3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER8 g_pVertexBuffer = NULL; // Buffer to hold vertices

struct CUSTOMVERTEX
{
    FLOAT x, y, z;
    DWORD colour;
};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)


#define SafeRelease(pObject) if(pObject != NULL) {pObject->Release(); pObject=NULL;}

HRESULT InitialiseD3D(HWND hWnd)
{
    //First of all, create the main D3D object. If it is created successfully we
    //should get a pointer to an IDirect3D8 interface.
    g_pD3D = Direct3DCreate8(D3D_SDK_VERSION);
    if(g_pD3D == NULL)
    {
        return E_FAIL;
    }

    //Get the current display mode
    D3DDISPLAYMODE d3ddm;
    if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
    {
        return E_FAIL;
    }

    //Create a structure to hold the settings for our device
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));

    //Fill the structure.
    //We want our program to be windowed, and set the back buffer to a format
    //that matches our current display mode
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
    d3dpp.BackBufferFormat = d3ddm.Format;

    //Create a Direct3D device.
    if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,     
                                   &g_pD3DDevice)))
    {
        return E_FAIL;
    }
   
    //Turn on back face culling.
    //This is because we want to hide the back of our polygons
    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

    //Turn off lighting because we are specifying that our vertices have colour
    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

    return S_OK;
}

HRESULT InitialiseVertexBuffer()
{
    VOID* pVertices;
   
    //Store each point of the cube together with it's colour
    //Make sure that the points of a polygon are specified in a clockwise direction,
    //this is because anti-clockwise faces will be culled
    //We will use a three triangle strips to render these polygons
    //(Top, Sides, Bottom).
    CUSTOMVERTEX cvVertices[] =
    {
        //Top Face
        {-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 0 - Blue
        {-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 1 - Red
        {5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 2 - Red
        {5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 3 - Green

        //Face 1
        {-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 4 - Red
        {-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 5 - Blue
        {5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 6 - Green
        {5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 7 - Red

        //Face 2
        {5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 8 - Blue
        {5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 9 - Green
        
        //Face 3
        {-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 10 - Green
        {-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 11 - Red

        //Face 4
        {-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 12 - Red
        {-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 13 - Blue

        //Bottom Face
        {5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 14 - Green
        {5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 15 - Blue
        {-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 16 - Red
        {-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 17 - Green
    };

    //Create the vertex buffer from our device.
    if(FAILED(g_pD3DDevice->CreateVertexBuffer(18 * sizeof(CUSTOMVERTEX),
                                               0, D3DFVF_CUSTOMVERTEX,
                                               D3DPOOL_DEFAULT, &g_pVertexBuffer)))
    {
        return E_FAIL;
    }


    //Get a pointer to the vertex buffer vertices and lock the vertex buffer
    if(FAILED(g_pVertexBuffer->Lock(0, sizeof(cvVertices), (BYTE**)&pVertices, 0)))
    {
        return E_FAIL;
    }

    //Copy our stored vertices values into the vertex buffer
    memcpy(pVertices, cvVertices, sizeof(cvVertices));

    //Unlock the vertex buffer
    g_pVertexBuffer->Unlock();

    return S_OK;
}


void SetupRotation()
{
    //Here we will rotate our world around the x, y and z axis.
    D3DXMATRIX matWorld, matWorldX, matWorldY, matWorldZ;
   
    //Create the transformation matrices
    D3DXMatrixRotationX(&matWorldX, timeGetTime()/400.0f);
    D3DXMatrixRotationY(&matWorldY, timeGetTime()/400.0f);
    D3DXMatrixRotationZ(&matWorldZ, timeGetTime()/400.0f);

    //Combine the transformations by multiplying them together
    D3DXMatrixMultiply(&matWorld, &matWorldX, &matWorldY);
    D3DXMatrixMultiply(&matWorld, &matWorld, &matWorldZ);

    //Apply the tansformation
    g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
}

void SetupCamera()
{
    //Here we will setup the camera.
    //The camera has three settings: "Camera Position", "Look at Position" and
    //"Up Direction"
    //We have set the following:
    //Camera Position: (0, 0, -30)
    //Look at Position: (0, 0, 0)
    //Up direction: Y-Axis.
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 0.0f,-30.0f), //Camera Position
                                 &D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look At Position
                                 &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); //Up Direction
    g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
}

void SetupPerspective()
{
    //Here we specify the field of view, aspect ration and near and
    //far clipping planes.
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 500.0f);
    g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}


void Render()
{
    if(g_pD3DDevice == NULL)
    {
        return;
    }

    //Clear the backbuffer to black
    g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
   
    //Begin the scene
    g_pD3DDevice->BeginScene();
   
    //Setup the rotation, camera, and perspective matrices
    SetupRotation();
    SetupCamera();
    SetupPerspective();


    //Rendering our objects
    g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, sizeof(CUSTOMVERTEX));
    g_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX);
    g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); //Top
    g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 8); //Sides
    g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 14, 2); //Bottom

    //End the scene
    g_pD3DDevice->EndScene();
   
    //Filp the back and front buffers so that whatever has been rendered on the
    //back buffer will now be visible on screen (front buffer).
    g_pD3DDevice-&gtresent(NULL, NULL, NULL, NULL);
}

void CleanUp()
{
    SafeRelease(g_pVertexBuffer);
    SafeRelease(g_pD3DDevice);
    SafeRelease(g_pD3D);
}

void GameLoop()
{
    //Enter the game loop
    MSG msg;
    BOOL fMessage;

    PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
   
    while(msg.message != WM_QUIT)
    {
        fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);

        if(fMessage)
        {
            //Process message
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            //No message to process, so render the current scene
            Render();
        }

    }
}

//The windows message handler
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        break;
        case WM_KEYUP:
            switch (wParam)
            {
                case VK_ESCAPE:
                    //User has pressed the escape key, so quit
                    DestroyWindow(hWnd);
                    return 0;
                break;
            }
        break;

    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}

//Application entry point
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
    //Register the window class
    WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L,
                     GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                     "DX Project 3", NULL};
    RegisterClassEx(&wc);

    //Create the application's window
    HWND hWnd = CreateWindow("DX Project 3", "www.andypike.com: Tutorial 3",
                              WS_OVERLAPPEDWINDOW, 50, 50, 500, 500,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL);

    //Initialize Direct3D
    if(SUCCEEDED(InitialiseD3D(hWnd)))
    {
        //Show our window
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);

        //Initialize Vertex Buffer
        if(SUCCEEDED(InitialiseVertexBuffer()))
        {
            //Start game running: Enter the game loop
            GameLoop();
        }
    }
   
    CleanUp();

    UnregisterClass("DX Project 3", wc.hInstance);
   
    return 0;
}


运行例子,你将会得到下面这样的屏幕:
  
怎么样?一个旋转的、多彩的立方体!



那末,我们都改动了什么呢?

Include and lib files
我们用新的头文件“d3dx8.h”代替了原来的“d3d8.h”。
项目设置中我们要加入两个Lib文件,“d3d8x.lib”和“winmm.lib”。

CUSTOMVERTEX
我们自定义的顶点格式,还记得吗?这回我们改动了它:只包含x,y,z 和 颜色值。这可以使我们在3D空间中指定一个顶点和它的颜色。

D3DFVF_CUSTOMVERTEX
为了和上面我们自定义的顶点各式相匹配,我们当然还要改动我们的FVF。这回我们用了两个标识: D3DFVF_XYZ和D3DFVF_DIFFUSE。


InitaliseD3D
在此,我们用SetRenderState函数激活了背面拣选。记住我们用D3DCULL_CCW符号指定了DirectX拣选逆时针的面。
我们又用了SetRenderState函数去除了灯光,因为我们为每个顶点都设置了颜色(灯光)。

InitaliseVertexBuffer
在此我们为我们的18个顶点设了值。每个顶点都有注解和标号,和上面的图中是一样的。立方体的中心是(0, 0, 0),它的长宽高都是10。

SetupRotation
一个新的函数,在此我们调用了D3DXMatrixRotationX、D3DXMatrixRotationY和D3DXMatrixRotationZ函数产生了3个矩阵而且分别将它们保存在了3个D3DXMATRIX结构中;然后我们将它们相乘后形成了世界矩阵;我们又调用了SetTransform函数为我们的顶点应用了此变换。

SetupCamera
又一个新的函数,在这里我们设置摄像机。我们将摄像机放在了(0, 0, -30)处,然后将观察点设置为(0, 0, 0)。(我们已经把立方体放在原点了)我们还设置了y轴的正方向为“上面”。我们用D3DXMatrixLookAtLH生成了视图矩阵然后调用了SetTransform应用了变换。

SetupPerspective
又一个新函数。在这里我们设置摄像机的镜头:我们确定了视界为PI/4(正常)而横纵比为1。我们还确定了前、后裁剪平面分别为1和500,这意味着范围之外的三角形将会被裁剪掉。

Render
在此渲染函数里,我们调用了三个新的函数:SetupRotation, SetupCamera和SetupPerspective,这些函数会在我们渲染三角形之前被调用。
还记得吗?我们用了三个三角形带:一个是顶,一个是四个连起来的面,一个是底。

Summary (摘要)
让老外说先:
That's it for another tutorial. In this tutorial we learnt about Backface Culling, Matrices, 3D World Space and how a cube is made up using triangular polygons. In the next tutorial, we will arrange our code so far into classes and make our application full screen.

第三章的教程就到这了,真是累死我了!老外写的东西毕竟不像是直接读中文那样好理解,就像是编译执行与解释执行那样差别很大!不过,我已经把它编译好了,你可以直接运行了!:) 我可是尽力翻译好了,不知道对你有没有帮助?什么?有的地方弄错了?欢迎与我联系:E-mail: Chaoyu_JIANG@hotmail.com QQ:15852673,Aman 就是我了。嗯,此章中,我们了解了背面拣选、矩阵、3D世界空间还有怎样用三角形制作立方体,你一定已经学会了吧?呵呵,下一张有更精彩的内容等着你!

8

主题

44

帖子

70

积分

注册会员

Rank: 2

积分
70
发表于 2004-3-3 10:27:00 | 显示全部楼层

Re:我在编译一个小程序时老是出错,请各位大侠指教.

cannot open file 'libci.lib'

你有libci.lib 没有当然会报错

13

主题

145

帖子

149

积分

注册会员

Rank: 2

积分
149
发表于 2004-3-4 14:16:00 | 显示全部楼层

Re:我在编译一个小程序时老是出错,请各位大侠指教.

呵呵,2003里没有,在vc6里搜索,然后拷过来就行了。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-5-14 20:47

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表