程序員吐血而死系列:VC+圖形處理=聊齋志異?

發表于:2007-07-01來源:作者:點擊數: 標簽:
首先我們看看剪貼板.翻遍msdn愣是沒找著一個例程.最后在codeproject上看到一段示例; if (FALSE==win-OpenClipboard ())return 0; HANDLE hDib=(HANDLE)::GetClipboardData(CF_DIB); HBITMAP retBmp,oldBmp; LPBITMAPINFOHEADER lpBI; lpBI = (LPBITMAPINFOHE

首先我們看看剪貼板.翻遍msdn愣是沒找著一個例程.最后在codeproject上看到一段示例;
  if (FALSE==win->OpenClipboard ())return 0;
  HANDLE hDib=(HANDLE)::GetClipboardData(CF_DIB);
  HBITMAP retBmp,oldBmp;
  LPBITMAPINFOHEADER lpBI;
  lpBI = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
  if(lpBI)
  {
   CDC memDC;
   memDC.Attach (CreateCompatibleDC(GetDC (NULL)));
   retBmp=CreateCompatibleBitmap(GetDC (NULL),
    lpBI->biWidth ,abs(lpBI->biHeight) );
   oldBmp=(HBITMAP)::SelectObject (memDC.GetSafeHdc (),retBmp);

   ::StretchDIBits(memDC.GetSafeHdc (),
    0, 0, lpBI->biWidth ,abs(lpBI->biHeight),
    0, 0, lpBI->biWidth ,abs(lpBI->biHeight),
    lpBI+1,(BITMAPINFO*)lpBI,
    DIB_RGB_COLORS, SRCCOPY);

   ::SelectObject (memDC.GetSafeHdc (),oldBmp);
   GlobalUnlock(GLOBALHANDLE(lpBI));
   CloseClipboard();
  }
  else return NULL;
 
  CloseClipboard();
  return retBmp;
還行,嗯?......用了一段日子發現不對:圖象好象偏移了一些.狂郁悶中調試,結果發現,原來是因為16位及以上的DIB位圖有三個DWORD掩碼lpBI+1應改為((char*)(lpBI+1))+12;這還沒考慮索引模式下的DIB............ 太麻煩..........查看GetClipbordData似乎有CF_BITMAP可用...也許M$會幫我們直接轉成HBITMAP? 可是試過以后你就會發現,這只不過是M$耽誤其它公司開發速度的又一手段罷了.

不只這些.在csdn中,我還發表了"為什么在opengl下紋理貼圖失敗","關于畫橢圓的問題:線寬增加回變形","請教:如何解決MDI中文檔切換的問題".至少有兩個是因為M$.
比方說線寬增加會變形,在非填充模式下畫橢圓,線寬太大時橢圓的內部可能變方的圓的菱的...連GDI+也如此.難怪mspaint只有那么一點線寬,難怪coreldraw最大線寬只用24.....原來是API太爛;
至于MDI中文檔切換會閃現一個frame,看來連VC編輯器本身都有
這個毛病.就別提M$可以解決了.曾經攔截了一下WM_ACTIVATE消息,看看能不能讓那deACTIVATE的frame不畫.結果是白費心機:原來,在NT系列中,為了給用戶圖形性能還可以的感覺,畫frame的標題欄之類是操作系統代勞,想讓它不畫都不行....干脆變成X window得了.(2004.2.9修訂:攔截WM_NCPAINT消息即可解決問題.感謝zhi_liu6)

.........考慮良久,覺得比爾實在是個天才------孜孜不倦地把垃圾推銷給世人,甚至為垃圾技術建立標準.象這種天才只涉足計算機領域實在太可惜了,回收站,廢品收購處都有他這種人,肯定可以為環境保護出一份大力.............

言歸正轉:鬼異的事還剛開始.

在矢量繪圖中,擦圖操作通常由一系列的小線段開始.于是我用STL的vector存儲點序列.在用戶連續擦了幾分鐘后系統崩潰了:沒有內存.只不過是幾M大小就會失敗了.只好用list,一開始在while循環中迭代list的節點,你猜如何?要好幾秒鐘!改成for循環就沒這問題了.又改回while循環,也沒問題了!暈~~~

還有opengl問題.根據M$的神話傳說,window 下的opengl繪圖是支持DIB位圖繪制的.就是說你用CreateDIBSection建立一個DIB,就可以使用opengl繪圖了,這樣你可以很方便的支持位圖了:比方說你可以建立一個2048*2048的大位圖.在上面進行操作,
而且可以用GDI因為你不需要window的雙緩沖.保存為位圖就太方便了:把CreateDIBSection返回的數據指針指向的數據存儲即可.高興啊.....等等,怎么這么慢!看看opengl版本:1.1;廠商:M$也!不會吧,怎么window的opengl是1.3和ATI呢!瘋狂調節各種參數...最后發現:神話就是神話.

opengl紋理貼圖為何失敗?我把這個問題提交了csdn,數字圖像網,www.opengl.org,www.gamedev.net,中國游戲開發者......
愣是沒人答出來.最后發現了:原來,在glTexImage2D調用后,你如果不調用glTexParameteri設置GL_TEXTURE_MAG_FILTER和
GL_TEXTURE_MIN_FILTER,那就可能什么也貼不上.不會報任何錯!老大你就算默認為GL_NEAREST也好啊!怎么來個干脆不畫呢!!!

各位同學,如果你們還沒吐血的話,我還有一個秘方;準保你們看得舒心,死得開心:
隨便一個hello world級別的代碼
#include "stdafx.h"
#include <windows.h>
#include <gl/gl.h>
struct glBitmap
{
static glBitmap* FromHBITMAP(HBITMAP hbmp);
};

glBitmap *glBitmap::FromHBITMAP
(HBITMAP hbmp)
{
 return 0;
}
int main()
{

}

編譯不過是不是?把#include <gl/gl.h>去掉看看:)


原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97