欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Win32 OpenGL編程系列 2D例子 -- 七巧板圖形繪制

系統 2506 0

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

討論新聞組及文件

OpenGL系列文章都已經寫到3D部分了,但是感覺2D的例子還是少了點,特意弄個外篇,引入一些稍微復雜的例子,這些例子不適合作為概念介紹時寫入此系列文章,只好獨立成篇,自己完成一個就發布一個吧。

此次完成的是一個七巧板圖形的繪制,繪制時參考了網上的七巧板程序的顏色( 此處 ),因為我僅僅是為了加深對OpenGL的學習,沒有添加具體的真實游戲代碼,僅僅只有OpenGL圖形繪制的演示。

另外,因為作為學習OpenGL例子之用,自然要使用OpenGL來繪制啦,雖然這么簡單的圖形根本用不著OpenGL,別說我用大炮打蒼蠅,用牛刀殺雞-_-!因為是學習OpenGL嘛,所以在2D坐標系中還是使用了OpenGL的坐標系,并且,為了追求顯示的完美(主要是旋轉的),我選取了所有圖形的重心作為每個圖形的坐標系的原點,這樣旋轉時的中心就是每個圖形的中心,這樣比使用rgnbox獲取邊框然后取中心旋轉效果要好,具體的旋轉效果需要自己添加代碼去嘗試了,Rotate和RotateTo的實現已經有了。添加到繪制部分即可。

下面簡單介紹一下所有源代碼。

所有的七巧板圖形全部繼承自CGLShape,此類實現如下

      
        // 此類實現移動,旋轉,
      
      
class CGLShape
{
public :
CGLShape( void )
{
mfPosX = 0.0;
mfPosY = 0.0;
memset(mfvColor, 0, sizeof (mfvColor));
mfDegree = 0.0;
mfSize = 1.0;
}
virtual ~CGLShape( void ) { }

void SetSize(GLfloat afSize) { mfSize = afSize; }

void SetColor(GLfloat afRed, GLfloat afGreen, GLfloat afBlue, GLfloat afAlpha = 1.0)
{
mfvColor[0] = afRed;
mfvColor[1] = afGreen;
mfvColor[2] = afBlue;
mfvColor[3] = afAlpha;
}

// 相對偏移(外部坐標系長度)
void Move( int aiPosX, int aiPosY)
{
mfPosX += 2.0f * aiPosX/( float )WIDTH;
mfPosY += -(2.0f * aiPosY/( float )HEIGHT);
}

// 移動到的位置(Windows坐標系點)
void MoveTo( int aiPosX, int aiPosY)
{
mfPosX = (2.0f * aiPosX - ( float )WIDTH) / ( float )WIDTH;
mfPosY = -(2.0f * aiPosY - ( float )HEIGHT) / ( float )HEIGHT;
}

// 旋轉,以逆時針為正方向
void Rotate(GLfloat aiDegree) { mfDegree += aiDegree; }

// 旋轉到
void RotateTo(GLfloat aiDegree) { mfDegree = aiDegree; }

// OpenGL坐標系
void SetPos(GLfloat afPosX, GLfloat afPosY) { mfPosX = afPosX; mfPosY = afPosY; }
void GetPos(GLfloat& afPosX, GLfloat& afPosY) { afPosX = mfPosX; afPosY = mfPosY; }

void Draw()
{
glLoadIdentity();
glColor4fv(mfvColor);

glPushMatrix();
glTranslatef(mfPosX, mfPosY, 0.0);
glRotatef(mfDegree, 0.0, 0.0, 1.0);

DrawImp();

glPopMatrix();
}

protected :
// 重繪時需要調用的函數,由各子類實現
virtual void DrawImp() = 0;

// 位置信息,沒有用POINT是為了將來方便移植
GLfloat mfPosX;
GLfloat mfPosY;

// 顏色
GLfloat mfvColor[4];

// 旋轉度數
GLfloat mfDegree;

// 大小
GLfloat mfSize;
};

大小,顏色,旋轉角度都以成員變量的方式保存在CGLShape中,并且在Draw函數中已經實際的完成了使用,具體的DrawImp交由子類實現,完成具體圖形的繪制。(此處使用template模式)具體的各個實現按照七巧板的要求如下:

三角形:

      
class CGLTriangle : public CGLShape
{
public :
CGLTriangle() { }
virtual ~CGLTriangle() { }

// 重繪時需要調用的函數,由各子類實現
virtual void DrawImp()
{
static GLfloat fvTop[3] = { 0.0, (1.0/3.0), 0.0};
static GLfloat fvLeftBottom[3] = { -0.5, -(1.0/6.0), 0.0};
static GLfloat fvRightBottom[3] = { 0.5, -(1.0/6.0), 0.0};

GLfloat fvSizeTop[3] = {fvTop[0], fvTop[1] * mfSize, fvTop[2]};
GLfloat fvSizeLeftBottom[3] = {fvLeftBottom[0] * mfSize, fvLeftBottom[1] * mfSize, fvLeftBottom[2]};
GLfloat fvSizeRightBottom[3] = {fvRightBottom[0] * mfSize, fvRightBottom[1] * mfSize, fvRightBottom[2]};

glBegin(GL_TRIANGLES);
glVertex3fv(fvSizeTop);
glVertex3fv(fvSizeLeftBottom);
glVertex3fv(fvSizeRightBottom);
glEnd();

}
};

實際上DrawImp僅僅關心繪制一個三角形而已,這里因為其他圖形只有一個,所以不關心大小,而三角形在七巧板中有多個,所以將大小的計算放在三角形中,獨立計算大小,事實上更通用的辦法是在CShape的Draw函數中用glScale實現。三角形的3個頂點的坐標相對來說還比較容易計算。

矩形:

      
        class
      
      
 CGLRectangle: 
      
        public
      
      
 CGLShape
      
{
public :
CGLRectangle() { }
virtual ~CGLRectangle() { }

// 重繪時需要調用的函數,由各子類實現
virtual void DrawImp()
{
static GLfloat fLength = sqrt(2.0)/4.0;
static GLfloat fLengthHalf = fLength/2.0;
static GLfloat fvLeftTop[3] = { -fLengthHalf, fLengthHalf, 0.0};
static GLfloat fvRightTop[3] = { fLengthHalf, fLengthHalf, 0.0};
static GLfloat fvLeftBottom[3] = { -fLengthHalf, -fLengthHalf, 0.0};
static GLfloat fvRightBottom[3] = { fLengthHalf, -fLengthHalf, 0.0};

// TODO:因為七角板此例中方形只有一個不需要考慮大小,暫時不計算大小
glColor4fv(mfvColor);
glPushMatrix();

glBegin(GL_QUADS);
glVertex3fv(fvLeftTop);
glVertex3fv(fvRightTop);
glVertex3fv(fvRightBottom);
glVertex3fv(fvLeftBottom);
glEnd();

glPopMatrix();
}
};

很簡單,不多說了,DrawImp實現一個矩形的繪制而已。四個頂點的坐標時最容易計算的。

平行四邊形:

      
        class
      
      
 CGLParallelogram: 
      
        public
      
      
 CGLShape
      
{
public :
CGLParallelogram() { }
virtual ~CGLParallelogram() { }

// 重繪時需要調用的函數,由各子類實現
virtual void DrawImp()
{
static GLfloat fRightBottomX = 0.375;
static GLfloat fHeight = 0.25;
static GLfloat fvLeftTop[3] = { -fRightBottomX, fHeight/2.0, 0.0};
static GLfloat fvRightTop[3] = { 0.5-fRightBottomX, fHeight/2, 0.0};
static GLfloat fvLeftBottom[3] = { fRightBottomX-0.5, -fHeight/2.0, 0.0};
static GLfloat fvRightBottom[3] = { fRightBottomX, -fHeight/2.0, 0.0};

// TODO:因為七角板此例中四邊形只有一個不需要考慮大小,暫時不計算大小
glColor4fv(mfvColor);
glPushMatrix();

glRotatef(mfDegree, 0.0, 0.0, 1.0);
glBegin(GL_QUADS);
glVertex3fv(fvLeftTop);
glVertex3fv(fvRightTop);
glVertex3fv(fvRightBottom);
glVertex3fv(fvLeftBottom);
glEnd();

glPopMatrix();
}
};

繪制是同樣簡單,但是在以平行四邊形的重心為原點的坐標系中,計算平時四邊形的4個頂點的坐標需要一定的計算量,上述那幾個數值可不是隨便掰出來的啊。

將上述圖形組合在一起

      
CGLTriangle gTriBTop; // 上方的大三角形
CGLTriangle gTriBRight; // 右邊的大三角形
CGLTriangle gTriSLeft; // 左上方的小上角形
CGLTriangle gTriSMid; // 中間的小三角形
CGLTriangle gTriMLeft; // 左下方的中三角形
CGLRectangle gRectangle; // 唯一的正方形
CGLParallelogram gParal; // 唯一的平行四邊形

      
        //OpenGL初始化開始
      
      
void SceneInit( int w, int h)
{
GLenum err = glewInit();
if (err != GLEW_OK)
{
MessageBox(NULL, _T( "Error" ), _T( "Glew init failed." ), MB_OK);
exit(-1);
}

gTriBTop.SetColor(1.0, 0.0, 0.0); // 上方的大三角形,紅色,
gTriBTop.SetPos(0.0, 1.0/3.0);
gTriBTop.RotateTo(180.0);

gTriBRight.SetColor(0.0, 0.0, 1.0); // 右邊的大三角形,藍色
gTriBRight.SetPos(1.0/3.0, 0.0);
gTriBRight.RotateTo(90.0);

gTriSLeft.SetColor(1.0, 1.0, 0.0); // 左上方的小上角形,黃色
gTriSLeft.SetSize(0.5); // 小三角形只有大的一半大
gTriSLeft.SetPos(-(5.0/12.0), 0.25);
gTriSLeft.RotateTo(-90.0);

gRectangle.SetColor(1.0, 175.0/255.0, 175.0/255.0); // 唯一的正方形,不知道什么顏色
gRectangle.SetPos(-0.25, 0.0);
gRectangle.RotateTo(45.0);

gTriSMid.SetColor(0.0, 1.0, 0.0); // 中間的小三角形,綠色
gTriSMid.SetSize(0.5); // 小三角形只有大的一半大
gTriSMid.SetPos(0.0, -1.0/6.0);

gTriMLeft.SetColor(0.0, 1.0, 1.0); // 左下方的中三角形
gTriMLeft.SetSize( sqrt(2.0) / 2.0 ); // 以底邊計算,2分之根號2倍
gTriMLeft.SetPos(-0.5 + 1.0/6.0, -0.5 + 1.0/6.0 );
gTriMLeft.RotateTo(135.0);

gParal.SetColor(1.0, 0.0, 1.0); // 唯一的平行四邊形,紫色
gParal.SetPos(0.125, -0.375);

}

void ReShape( unsigned auWidth, unsigned auHeight)
{
glViewport(0, 0, auWidth, auHeight);
}

//這里進行所有的繪圖工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT); // 清空顏色緩沖區

gTriBTop.Draw();
gTriBRight.Draw();
gTriSLeft.Draw();
gRectangle.Draw();
gTriSMid.Draw();
gTriMLeft.Draw();
gParal.Draw();

glFlush();
}

上述代碼中程序邏輯非常簡單,無非就是設定好每個圖形的大小,位置,旋轉角度(三角形需要)等,每個圖形的繪制都是以其重心為原點,所以計算的實際是七巧板每個圖形的重心的位置,有一定的計算量,上述每個數值都是精確計算出來的,所以最后的圖形才能完美,實際上也可以通過移動所有圖形到一起,然后記錄下每個值的方式來完成,但是此方式可能沒有完整的數學描述精確,效果也就沒有那么完美了。顯示的截圖如下:

image

最后演示一下每個圖形的旋轉效果:

只需要將代碼改成如下形式即可:

      
        //這里進行所有的繪圖工作
      
      
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT); // 清空顏色緩沖區

gTriBTop.Draw();
gTriBRight.Draw();
gTriSLeft.Draw();
gRectangle.Draw();
gTriSMid.Draw();
gTriMLeft.Draw();
gParal.Draw();


gTriBTop.Rotate(1.0);
gTriBRight.Rotate(1.0);
gTriSLeft.Rotate(1.0);
gRectangle.Rotate(1.0);
gTriSMid.Rotate(1.0);
gTriMLeft.Rotate(1.0);
gParal.Rotate(1.0);

glFlush();
}

見視頻:

此文演示的完整代碼在博客代碼的JTTangram目錄。有興趣的可以將整個七巧板游戲完成然后再告訴我。最后,開始實際的完成稍微復雜點的圖形的繪制時就會發現,就會發現技術的學習都是比較簡單的,但是,實際的使用全靠數學撐著,此例算是比較簡單了,但是平面幾何,三角函數等東西不懂一點根本無法計算各個圖形的位置-_-!數學還是得學好啊。。。。。。。。。。。

本OpenGL系列其他文章

1. Win32 OpenGL 編程(1)Win32下的OpenGL編程必須步驟

2. 《 Win32 OpenGL編程(2) 尋找缺失的OpenGL函數

3. 《 Win32 OpenGL編程(3) 基本圖元(點,直線,多邊形)的繪制

4. 《 Win32 OpenGL編程(4) 2D圖形基礎(顏色及坐標體系進階知識)

5. 《 Win32 OpenGL編程(5)頂點數組詳細介紹

6.《 Win32 OpenGL編程(6) 踏入3D世界

完整源代碼獲取說明

由于篇幅限制,本文一般僅貼出代碼的主要關心的部分,代碼帶工程(或者makefile)完整版(如果有的話)都能用Mercurial在Google Code中下載。文章以博文發表的日期分目錄存放,請直接使用Mercurial克隆下庫:

https://blog-sample-code.jtianling.googlecode.com/hg/

Mercurial使用方法見《 分布式的,新一代版本控制系統Mercurial的介紹及簡要入門

要是僅僅想瀏覽全部代碼也可以直接到google code上去看,在下面的地址:

http://code.google.com/p/jtianling/source/browse?repo=blog-sample-code

原創文章作者保留版權 轉載請注明原作者 并給出鏈接

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

Win32 OpenGL編程系列 2D例子 -- 七巧板圖形繪制


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美激情免费在线 | 久久亚洲国产精品 | 色图综合| 亚洲精品婷婷无码成人A片在线 | 日韩18在线观看地址 | 日本黄页在线观看免费 | www.国产在线 | 日韩免费网站 | 欧美综合社区 | 九九热在线视频 | 9191精品国产免费不久久 | 国产午夜精品AV一区二区 | 中文字幕在线精品 | 精品日韩在线 | 亚洲精品第一综合99久久 | 国产日韩一区二区三区在线观看 | 欧美一区二区三区在线视频 | 仇爱电视剧泰剧在线观看免费播放 | 国产精品高清在线观看 | 久久久免费的精品 | 在线观看成人 | 久久久久日韩精品免费观看网 | 色九九| 欧美日韩一区二区三区四区五区 | 欧美黑人狂野猛交老妇 | 国产一区二区三区不卡在线观看 | 成人精品一区二区 | 亚洲激情视频 | 久久综合成人 | 亚洲国产欧美在线人成aaa | 天堂色区| 91 视频网站| 中文字幕av在线播放 | 国产精品久久一区二区三区 | 久久精品综合电影 | 日韩在线欧美 | 性爽爽 | 亚洲一区二区三 | 免费看污成人午夜网站 | 青娱乐免费 | 欧美成人三级一区二区在线观看 |