前面一篇已經簡單的介紹了如何利用gcc編譯c源代碼,這篇說一下gcc的具體編譯過程
- 預處理
預處理的工作主要是處理#include語句等,然后生成*.i文件。如果不加參數“-o *.i”,則會將預處理的結果輸出到標準輸出。
gcc -E *.c -o *.i #使用gcc的E參數進行預處理
cpp *c - o *.i #使用cpp命令進行預處理
這兩條命令預處理的結果一樣,因為gcc使用-E參數實際上也是調用了cpp指令。
2.生成匯編代碼
gcc -S *c -o *.s #將C代碼匯編為匯編語言代碼
gcc -S *.i -o *.s #將i文件匯編為匯編語言代碼
3.編譯
gcc -c *.c -o *.o
gcc -c *.s -o *o
as *.s -o *.o
cc -c *.c -o *.o
4.鏈接
gcc *.o -o *out
GCC高級技巧
1.指定頭文件位置
一是在源碼中指定頭文件的絕對路徑,簡單直觀但缺乏靈活性,二是在編譯時使用“-I”參數來指定頭文件的路徑,實際工作中,一般選擇第二種。
使用第二種方法將resolv.c編譯為resolv.out的命令如下:
gcc resolv.c -I /home/myname/code/header -o resolv.out 如果找不到會按照代碼所在目錄或系統目錄尋找頭文件
gcc resolv.c -I /home/myname/code/header -I /home/myname/code/header2 -o resolv.out 多個路徑
2.定義符號常量
在代碼中會使用一些常量來控制程序的行為,如#define WIRELESS 211 等等一系列,怎么來檢驗定義了符號常量與為定義符號常量的區別,一般在編譯時使用-D參數來指定符號常量,命令如下:gcc -D WIRELESS -I /home/myname/code/header resolv.c -o resolv.out
3.定義警告級別
最常用的警告選項是-Wall選項。其意思是warning all。使用如下命令顯示特定警告信息來編譯test.c,命令如下:
gcc -Wall test.c -o test
4.其他GCC選項
gcc [option] [filename]
- -c:只將源代碼編譯為以.o為后綴的目標文件,而不是直接將這些文件連接可執行文件。通常用于不包含主程序(man函數)的子程序代碼。
- -o:filename: 指定輸出文件名。如果不用這個選項,gcc會將文件輸出到a.out,而不管輸出文件的類型
- -g:產生調試信息。如果要使用gdb進行調式,則必須使用該選項。但是該選項所產生的調式符號,并不能被其他調式器識別。
- -O:在程序編譯、連接過程中對代碼進行優化。
- -O2:比-O更好的優化編譯、連接。
- -L dir:在程序連接時,會首先在dir目錄尋找類庫文件,然后在系統預設路徑中尋找類庫。也可以使用多個-L參數指定多個類庫存放的目錄。
- -lname:在程序連接時加載名為libname.a的函數庫。如-lmath 表示連接名為libmath.a的數學函數庫。
- --sysboot=dir:讓目錄dir作為頭文件和庫文件的根目錄
- -B dir:將目錄dir添加到編譯器的搜索路徑中。
- -b:指定gcc編譯的目標機器架構,如ARM、DEC、GNU/Linux、IA64、MIPS等,這也可以看出gcc的超級跨平臺性。
- -V n1.n2:使用n1.n2指定版本的gcc進行編譯
- -E:僅作預處理,不能進行編譯等工作,生成i文件
- -S:將源碼編譯為匯編語言代碼
- -x lang:將源代碼依照特定語言進行編譯,可以取得值包括但不限于C、C++、Objective-C、Objective-C++、Assembler、Ada、java等。在一系列的編譯中,該選項會一直保持,知道另一個-x lang出現,指定另一種編譯語言。如果是none,意味著讓gcc一句文件的后綴來自動判斷語言種類。
在Linux 下面,如果要編譯一個C 語言源程序,我們要使用GNU 的gcc 編譯器。下面
我們以一個實例來說明如何使用gcc 編譯器。假設我們有下面一個非常簡單的源程序
(hello.c):
int main(int argc,char **argv)
{
printf("Hello Linux\n");
}
要編譯這個程序,我們只要在命令行下執行:
gcc -o hello hello.c
下面就詳細說一下gcc的編譯過程
gcc由C語言源代碼文件生成可執行文件的過程,一般來說分為四個階段:預處理(也稱預編譯Preprocessing)、編譯(compilation)、匯編(Assembly)和鏈接(linking)。這四個階段分別由gcc調用不同的程序來實現。
- 預處理是調用cpp程序來實現的,預處理主要是對包含語句、宏定義等進行處理。
- 編譯是調用cc來實現的,它是源文件變為后綴為.o的目標文件的過程。
- 匯編過程是對匯編語言的操作,通過調用as來實現,匯編同樣也生成目標文件。
- 鏈接是通過用ld來實現的。這是最為關鍵的步驟,在該階段,ld會將各程序的執行代碼放置在程序的適合位置,同時,程序調用的庫函數也會以適當的方法設置調用接口。
gcc編譯時,如果在命令行沒有指定其他參數,則gcc會完成編譯、鏈接的過程,然后在當前目錄中生成一個名為a.out的可執行文件。一般來說,linux并不依賴文件的后綴來識別文件是否為可執行程序,其判斷文件是否可執行依據的是文件的屬性。如果對于當前用戶而言,文件有運行權限,則該文件為一個可執行程序。
對于gcc而言,判斷文件的類型主要是依據文件的后綴名。所以,要使用gcc編譯代碼,正確使用文件后綴是保證編譯正確的前提。如果寫了一個C++代碼,卻使用了.c為后綴,gcc在編譯該文件時會將該文件按照C語言代碼來處理,一般會出錯。
一些gcc常用的文件后綴名:
- c: C語言源代碼文件
- a:由目標文件構成的檔案庫文件
- .C、.cc 或.cxx:c++源代碼文件
- h:頭文件
- i:經過預處理的C源代碼文件
- ii:經過預處理的C++源代碼文件
- m:Objective-C源代碼文件
- o:編譯后的目標文件
- s:匯編語言源代碼文件
- S:經過預編譯的匯編語言源代碼文件
gcc hello.c編譯通過后,就可以簡單的使用a.out調用該程序,使用命令如下:./a.out - 注意:這里不能直接使用a.out來調用該程序,因為shell在尋找可執行程序時,并不在當前目錄中尋找,所以必須用“./”來顯示指定該文件的路徑是當前目錄
1.關于創建Direct3D設備對象
創建Direct3D設備對象時,需要先創建Direct3D對象,然后再調用Direct3D對象的接口函數IDirect3D9::CreateDevice創建Direct3D設備對象。通過同一個Direct3D對象創建的所有Direct3D設備對象共享相同的物理資源(顯卡)。因為共享同一硬件,所以如果通過一個Direct3D對象創建多個Direct3D渲染設備對象會明顯降低系統性能。
在創建Direct3D設備對象之前,還需要先初始化D3DPRESENT_PARAMENTERS結構,該結構用于創建Direct3D設備對象。此結構將會影響Direct3D設備的顯示方法。
D3DPRESENT_PARAMETERS
Describes the presentation parameters.
typedef struct D3DPRESENT_PARAMETERS {
UINT BackBufferWidth, BackBufferHeight;
D3DFORMAT BackBufferFormat;
UINT BackBufferCount;
D3DMULTISAMPLE_TYPE MultiSampleType;
DWORD MultiSampleQuality;
D3DSWAPEFFECT SwapEffect;
HWND hDeviceWindow;
BOOL Windowed;
BOOL EnableAutoDepthStencil;
D3DFORMAT AutoDepthStencilFormat;
DWORD Flags;
UINT FullScreen_RefreshRateInHz;
UINT PresentationInterval;
} D3DPRESENT_PARAMETERS, *LPD3DPRESENT_PARAMETERS;
Members
- BackBufferWidth, BackBufferHeight
- Width and height of the new swap chain's back buffers, in pixels. If Windowed is FALSE (the presentation is full-screen), these values must equal the width and height of one of the enumerated display modes found through IDirect3D9::EnumAdapterModes. If Windowed is TRUE and either of these values is zero, the corresponding dimension of the client area of the hDeviceWindow (or the focus window, if hDeviceWindow is NULL) is taken.
- BackBufferFormat
- The back buffer format. For more information about formats, see D3DFORMAT. This value must be one of the render-target formats as validated by IDirect3D9::CheckDeviceType. You can use IDirect3DDevice9::GetDisplayMode to obtain the current format.
In fact, D3DFMT_UNKNOWN can be specified for the BackBufferFormat while in windowed mode. This tells the runtime to use the current display-mode format and eliminates the need to call IDirect3DDevice9::GetDisplayMode.
For windowed applications, the back buffer format no longer needs to match the display-mode format because color conversion can now be done by the hardware (if the hardware supports color conversion). The set of possible back buffer formats is constrained, but the runtime will allow any valid back buffer format to be presented to any desktop format. (There is the additional requirement that the device be operable in the desktop mode; devices typically do not operate in 8 bits per pixel modes.)
Full-screen applications cannot do color conversion.
- BackBufferCount
- This value can be between 0 and D3DPRESENT_BACK_BUFFERS_MAX (or D3DPRESENT_BACK_BUFFERS_MAX_EX when using Direct3D 9Ex). Values of 0 are treated as 1. If the number of back buffers cannot be created, the runtime will fail the method call and fill this value with the number of back buffers that could be created. As a result, an application can call the method twice with the same D3DPRESENT_PARAMETERS structure and expect it to work the second time.
The method fails if one back buffer cannot be created. The value of BackBufferCount influences what set of swap effects are allowed. Specifically, any D3DSWAPEFFECT_COPY swap effect requires that there be exactly one back buffer.
- MultiSampleType
- Member of the D3DMULTISAMPLE_TYPE enumerated type. The value must be D3DMULTISAMPLE_NONE unless SwapEffect has been set to D3DSWAPEFFECT_DISCARD. Multisampling is supported only if the swap effect is D3DSWAPEFFECT_DISCARD.
- MultiSampleQuality
- Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by IDirect3D9::CheckDeviceMultiSampleType. Passing a larger value returns the error D3DERR_INVALIDCALL. Paired values of render targets or of depth stencil surfaces and D3DMULTISAMPLE_TYPE must match.
- SwapEffect
- Member of the D3DSWAPEFFECT enumerated type. The runtime will guarantee the implied semantics concerning buffer swap behavior; therefore, if Windowed is TRUE and SwapEffect is set to D3DSWAPEFFECT_FLIP, the runtime will create one extra back buffer and copy whichever becomes the front buffer at presentation time.
D3DSWAPEFFECT_COPY requires that BackBufferCount be set to 1.
D3DSWAPEFFECT_DISCARD will be enforced in the debug runtime by filling any buffer with noise after it is presented.
Differences between Direct3D9 and Direct3D9Ex
In Direct3D9Ex, D3DSWAPEFFECT_FLIPEX is added to designate when an application is adopting flip mode. That is, whan an application's frame is passed in window's mode (instead of copied) to the Desktop Window Manager(DWM) for composition. Flip mode provides more efficient memory bandwidth and enables an application to take advantage of full-screen-present statistics. It does not change full screen behavior. Flip mode behavior is available beginning with Windows 7. |
- hDeviceWindow
- The device window determines the location and size of the back buffer on screen. This is used by Direct3D when the back buffer contents are copied to the front buffer during IDirect3DDevice9::Present.
-
For a full-screen application, this is a handle to the top window (which is the focus window).
For applications that use multiple full-screen devices (such as a multimonitor system), exactly one device can use the focus window as the device window. All other devices must have unique device windows.
- For a windowed-mode application, this handle will be the default target window for IDirect3DDevice9::Present. If this handle is NULL, the focus window will be taken.
Note that no attempt is made by the runtime to reflect user changes in window size. The back buffer is not implicitly reset when this window is reset. However, the IDirect3DDevice9::Present method does automatically track window position changes.
- Windowed
- TRUE if the application runs windowed; FALSE if the application runs full-screen.
- EnableAutoDepthStencil
- If this value is TRUE, Direct3D will manage depth buffers for the application. The device will create a depth-stencil buffer when it is created. The depth-stencil buffer will be automatically set as the render target of the device. When the device is reset, the depth-stencil buffer will be automatically destroyed and recreated in the new size.
If EnableAutoDepthStencil is TRUE, then AutoDepthStencilFormat must be a valid depth-stencil format.
- AutoDepthStencilFormat
- Member of the D3DFORMAT enumerated type. The format of the automatic depth-stencil surface that the device will create. This member is ignored unless EnableAutoDepthStencil is TRUE.
- Flags
- One of the D3DPRESENTFLAG constants.
- FullScreen_RefreshRateInHz
- The rate at which the display adapter refreshes the screen. The value depends on the mode in which the application is running:
- For windowed mode, the refresh rate must be 0.
- For full-screen mode, the refresh rate is one of the refresh rates returned by IDirect3D9::EnumAdapterModes.
- PresentationInterval
- The maximum rate at which the swap chain's back buffers can be presented to the front buffer. For a detailed explanation of the modes and the intervals that are supported, see D3DPRESENT.
Requirements
Header: Declared in D3D9Types.h.
幾個重要的參數加以解釋說明一下,其中BackBufferWidth和BackBufferHeight指定后臺緩存區的寬高(以像素為單位)。如果圖形以窗口方式顯示并且該成員變量被設置為0,則系統自動使用顯示窗口客戶區的寬高作為后臺緩沖區的寬高。BackBufferCount指定后臺緩沖區的數量。該值可以為0、1、2、3,其中0和1時都表示創建一個后臺緩沖區。通常使用一個后臺緩沖區和一個主緩存,主緩存將其顯示在屏幕上。
這兩天考慮把DirectX 版本升級,同時把相關的功能也升級,比如畫圖,之前用的是DirectDraw比較老,現在想改用Direct2D。
Direct2D是DirectX11中的新特性,可以說是DirectDraw的升級版。DirectX最新版本
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=6812,當然要想使用DirectX11需要系統支持,win7中就已帶DirectX11,而vista中使用就需要Update,以下來自MSDN文檔
Direct3D 11 Runtime
To obtain the Direct3D 11 runtime, please install the release version of Windows 7 or Windows Server 2008 R2. Windows Vista users can follow the procedure described in
KB 971644 (or
KB 971512 for corporate network users).
http://support.microsoft.com/kb/971644具體如何去實現一個DirectX2D Application 參見DirectX 2010.6 版本中SDK文檔——Windows DirectX Graphics Documention——Direct2D
Direct2D入門:
http://blog.pfan.cn/lym51/52200.html使用Direct2D繪圖
http://msdn.microsoft.com/zh-cn/magazine/ee413543.aspx
1、為什么要進行傅里葉變換,其物理意義是什么?
傅立葉變換是數字信號處理領域一種很重要的算法。要知道傅立葉變換算法的意義,首先要了解傅立葉原理的意義。傅立葉原理表明:任何連續測量的時序或信號,都可以表示為不同頻率的正弦波信號的無限疊加。而根據該原理創立的傅立葉變換算法利用直接測量到的原始信號,以累加方式來計算該信號中不同正弦波信號的頻率、振幅和相位。
和傅立葉變換算法對應的是反傅立葉變換算法。該反變換從本質上說也是一種累加處理,這樣就可以將單獨改變的正弦波信號轉換成一個信號。
因此,可以說,傅立葉變換將原來難以處理的時域信號轉換成了易于分析的頻域信號(信號的頻譜),可以利用一些工具對這些頻域信號進行處理、加工。最后還可以利用傅立葉反變換將這些頻域信號換成時域信號。
從現代數學的眼光來看,傅里葉變換是一種特殊的積分變換。它能將滿足一定條件的某個函數表示成正弦基函數的線性組合或者積分。在不同的研究領域,傅里葉變換具有多種不同的變體形式,如連續傅里葉變換和離散傅里葉變換。
在數學領域,盡管最初傅立葉分析是作為熱過程的解析分析的工具,但是其思想方法仍然具有典型的還原論和分析主義的特征。"任意"的函數通過一定的分解,都能夠表示為正弦函數的線性組合的形式,而正弦函數在物理上是被充分研究而相對簡單的函數類:1. 傅立葉變換是線性算子,若賦予適當的范數,它還是酉算子;2. 傅立葉變換的逆變換容易求出,而且形式與正變換非常類似;3. 正弦基函數是微分運算的本征函數,從而使得線性微分方程的求解可以轉化為常系數的代數方程的求解.在線性時不變雜的卷積運算為簡單的乘積運算,從而提供了計算卷積的一種簡單手段;5. 離散形式的傅立葉的物理系統內,頻率是個不變的性質,從而系統對于復雜激勵的響應可以通過組合其對不同頻率正弦信號的響應來獲取;4. 著名的卷積定理指出:傅立葉變換可以化復變換可以利用數字計算機快速的算出(其算法稱為快速傅立葉變換算法(FFT))。
正是由于上述的良好性質,傅里葉變換在物理學、數論、組合數學、信號處理、概率、統計、密碼學、聲學、光學等領域都有著廣泛的應用。
2、圖像傅立葉變換的物理意義
圖像的頻率是表征圖像中灰度變化劇烈程度的指標,是灰度在平面空間上的梯度。如:大面積的沙漠在圖像中是一片灰度變化緩慢的區域,對應的頻率值很低;而對于地表屬性變換劇烈的邊緣區域在圖像中是一片灰度變化劇烈的區域,對應的頻率值較高。傅立葉變換在實際中有非常明顯的物理意義,設f是一個能量有限的模擬信號,則其傅立葉變換就表示f的譜。從純粹的數學意義上看,傅立葉變換是將一個函數轉換為一系列周期函數來處理的。從物理效果看,傅立葉變換是將圖像從空間域轉換到頻率域,其逆變換是將圖像從頻率域轉換到空間域。換句話說,傅立葉變換的物理意義是將圖像的灰度分布函數變換為圖像的頻率分布函數,傅立葉逆變換是將圖像的頻率分布函數變換為灰度分布函數
傅立葉變換以前,圖像(未壓縮的位圖)是由對在連續空間(現實空間)上的采樣得到一系列點的集合,我們習慣用一個二維矩陣表示空間上各點,則圖像可由z=f(x,y)來表示。由于空間是三維的,圖像是二維的,因此空間中物體在另一個維度上的關系就由梯度來表示,這樣我們可以通過觀察圖像得知物體在三維空間中的對應關系。
為什么要提梯度?因為實際上對圖像進行二維傅立葉變換得到頻譜圖,就是圖像梯度的分布圖,當然頻譜圖上的各點與圖像上各點并不存在一一對應的關系,即使在不移頻的情況下也是沒有。傅立葉頻譜圖上我們看到的明暗不一的亮點,實際上圖像上某一點與鄰域點差異的強弱,即梯度的大小,也即該點的頻率的大小(可以這么理解,圖像中的低頻部分指低梯度的點,高頻部分相反)。一般來講,梯度大則該點的亮度強,否則該點亮度弱。這樣通過觀察傅立葉變換后的頻譜圖,也叫功率圖,我們首先就可以看出,圖像的能量分布,如果頻譜圖中暗的點數更多,那么實際圖像是比較柔和的(因為各點與鄰域差異都不大,梯度相對較小),反之,如果頻譜圖中亮的點數多,那么實際圖像一定是尖銳的,邊界分明且邊界兩邊像素差異較大的。對頻譜移頻到原點以后,可以看出圖像的頻率分布是以原點為圓心,對稱分布的。將頻譜移頻到圓心除了可以清晰地看出圖像頻率分布以外,還有一個好處,它可以分離出有周期性規律的干擾信號,比如正弦干擾,一副帶有正弦干擾,移頻到原點的頻譜圖上可以看出除了中心以外還存在以某一點為中心,對稱分布的亮點集合,這個集合就是干擾噪音產生的,這時可以很直觀的通過在該位置放置帶阻濾波器消除干擾
另外我還想說明以下幾點:
1、圖像經過二維傅立葉變換后,其變換系數矩陣表明:
若變換矩陣Fn原點設在中心,其頻譜能量集中分布在變換系數短陣的中心附近(圖中陰影區)。若所用的二維傅立葉變換矩陣Fn的原點設在左上角,那么圖像信號能量將集中在系數矩陣的四個角上。這是由二維傅立葉變換本身性質決定的。同時也表明一股圖像能量集中低頻區域。
2 、變換之后的圖像在原點平移之前四角是低頻,最亮,平移之后中間部分是低頻,最亮,亮度大說明低頻的能量大(幅角比較大)
BOOL CD3DCameraViewWnd::GetImageInfo(DWORD* pPixelBuffer, int& width,int& height)
{
BOOL result = FALSE;
IDirect3DSurface9 *_surfaceback = NULL;
if (FAILED(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &_surfaceback)))
{
result = FALSE;
}
D3DSURFACE_DESC surfaceDesc;
if (!FAILED(_surfaceback->GetDesc(&surfaceDesc)))
{
width = surfaceDesc.Width;
height = surfaceDesc.Height;
}
D3DLOCKED_RECT lockedRect;
HRESULT hr = _surfaceback->LockRect( &lockedRect,0, 0); /* pointer to receive locked data指向申請到的內存區域*/ /* lock entire surface*/// no lock flags specified
if (!FAILED(hr))
{
pPixelBuffer = (DWORD*)lockedRect.pBits;
result = TRUE;
}
_surfaceback->UnlockRect();
_surfaceback->Release();
return result;
}
但是這樣存在著性能的問題,經測試獲取一幀需要200ms左右,為什么會存在這樣的問題?因為這邊有資源鎖定操作。
現在關鍵的問題就在于,資源鎖定的操作速度總是非常之慢.當然,你會跟我提, OpenGL似乎能夠快捷地完成這項任務.但是,在Direct3D中,資源鎖定操作確實是很慢的.這里面一個主要的原因是,API,驅動,以及硬件要處理一些不可回避的后臺操作.那就是GPU與CPU是并行運行的,若不加任何措施,將引起類似多線程程序同步時的競態條件的問題.
如果你試圖去修改的資源正同時被一個位于GPU處理序列中的指令使用,那么整個渲染流程就會因為你的資源鎖定而停頓或強制刷新(stalls and flushes).停頓(stall)會一直持續到你完成了對資源的修改并調用Unlock().而強制刷新(flush)則會要求GPU在你得到這個資源的訪問權之前完成目前所有的任務.
如何去解決這個問題?下面的參考資料中有一些解決方案,我沒有經過認真測試,我試了其中一個GetRenderTargetData 這樣的一種方法 ,感覺不太好用,why請看Reference3
下面給出我的解決方案
BOOL CD3DCameraViewWnd::GetImageInfo(DWORD* pPixelBuffer, int& width,int& height)
{
BOOL result = FALSE;
IDirect3DSurface9 *_surfaceback = NULL;
if (FAILED(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &_surfaceback)))
{
result = FALSE;
}
D3DSURFACE_DESC surfaceDesc;
if (!FAILED(_surfaceback->GetDesc(&surfaceDesc)))
{
width = surfaceDesc.Width;
height = surfaceDesc.Height;
}
LPDIREC3DSURFACE9 surf;
if(FAILED(m_pDevice->CreateOffscreenPlainSurface(width, height,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM, &surf,NULL)))
{
result = FALSE;
}
D3DXLoadSurfaceFromSurface(surf, NULL,NULL,_surfaceback,NULL,NULL,D3DX_FILTER_NONE,0);
D3DLOCKED_RECT lockedRect;
HRESULT hr = surf->LockRect( &lockedRect,0, 0); /* pointer to receive locked data指向申請到的內存區域*/ /* lock entire surface*/// no lock flags specified
if (!FAILED(hr))
{
pPixelBuffer = (DWORD*)lockedRect.pBits;
result = TRUE;
}
surf->UnlockRect();
surf->Release();
_surfaceback->Release();
return result;
}
參考資料:Reference1.http://www.cnblogs.com/mixiyou/archive/2010/02/25/1673060.html
Reference 2.http://www.cnblogs.com/mixiyou/archive/2010/02/25/1673425.html
Reference 3.http://blog.csdn.net/Nightmare/article/details/1707362
Reference 4.http://www.cnblogs.com/lancidie/archive/2011/3/14.html
摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->////////////////////////////////////////////////////////////////////////////////// CppSQLite3&nbs...
閱讀全文