導航:首頁 > 編程語言 > opengl畫正方體編程

opengl畫正方體編程

發布時間:2022-11-27 18:49:28

1. 在QT環境下用OpenGL繪制一個邊長為5的立方體,並為立方體貼上自定義紋理。寫出實現該功能的具體

void MyGLWidget::loadGLTexture()
{
QImage image(":/dog.jpg");
image = image.convertToFormat(QImage::Format_RGB888);
image = image.mirrored();
glGenTextures(1, &mTexture[0]);

glBindTexture(GL_TEXTURE_2D,mTexture[0]);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
image.width(), image.height(), 0,
GL_RGB, GL_UNSIGNED_BYTE,
image.bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度緩存
glLoadIdentity(); // 重置當前的模型觀察矩陣
glTranslatef(0.0f,0.0f,-5.0f); // 移入屏幕 5 個單位
//下面三行使立方體繞X、Y、Z軸旋轉。旋轉多少依賴於變數 xrot , yrot 和 zrot 的值。
glRotatef(mXRotate,1.0f,0.0f,0.0f); // X軸旋轉
glRotatef(mYRotate,0.0f,1.0f,0.0f); // Y軸旋轉
glRotatef(mZRotate,0.0f,0.0f,1.0f); // Z軸旋轉

//下一行代碼選擇我們使用的紋理。
//如果您在您的場景中使用多個紋理,您應該使用來 glBindTexture(GL_TEXTURE_2D, texture[ 所使用紋理對應的數字 ]) 選擇要綁定的
//紋理。當您想改變紋理時,應該綁定新的紋理。有一點值得指出的是,您不能在 glBegin() 和 glEnd() 之間綁定紋理,必須在 glBegin()
//之前或 glEnd() 之後綁定。注意我們在後面是如何使用 glBindTexture 來指定和綁定紋理的。
glBindTexture(GL_TEXTURE_2D, mTexture[0]); // 選擇紋理
//為了將紋理正確的映射到四邊形上,您必須將紋理的右上角映射到四邊形的右上角,紋理的左上角映射到四邊形的左上角,
//紋理的右下角映射到四邊形的右下角,紋理的左下角映射到四邊形的左下角。
//如果映射錯誤的話,圖像顯示時可能上下顛倒,側向一邊或者什麼都不是。
//glTexCoord2f 的第一個參數是X坐標。 0.0f 是紋理的左側。 0.5f 是紋理的中點, 1.0f 是紋理的右側。
//glTexCoord2f 的第二個參數是Y坐標。 0.0f 是紋理的底部。 0.5f 是紋理的中點, 1.0f 是紋理的頂部。
//所以紋理的左上坐標是 X:0.0f,Y:1.0f ,四邊形的左上頂點是 X: -1.0f,Y:1.0f 。其餘三點依此類推。
//試著玩玩 glTexCoord2f X, Y坐標參數。把 1.0f 改為 0.5f 將只顯示紋理的左半部分,把 0.0f 改為 0.5f 將只顯示紋理的右半部分。
glBegin(GL_QUADS);
// 前面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 紋理和四邊形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 紋理和四邊形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 紋理和四邊形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 紋理和四邊形的左上
// 後面
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 紋理和四邊形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 紋理和四邊形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 紋理和四邊形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 紋理和四邊形的左下
// 頂面
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 紋理和四邊形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 紋理和四邊形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 紋理和四邊形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 紋理和四邊形的右上
// 底面
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 紋理和四邊形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 紋理和四邊形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 紋理和四邊形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 紋理和四邊形的右下

// 右面
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 紋理和四邊形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 紋理和四邊形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 紋理和四邊形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 紋理和四邊形的左下

// 左面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 紋理和四邊形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 紋理和四邊形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 紋理和四邊形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 紋理和四邊形的左上
glEnd();

}

void MyGLWidget::timerEvent(QTimerEvent *event)
{
//現在增加 xrot , yrot 和 zrot 的值。嘗試變化每次各變數的改變值來調節立方體的旋轉速度,或改變+/-號來調節立方體的旋轉方向。
mXRotate += 0.3f; // X 軸旋轉
mYRotate += 0.2f; // Y 軸旋轉
mZRotate += 0.4f; // Z 軸旋轉

updateGL();

QGLWidget::timerEvent(event);
}

void MyGLWidget::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_F2:
{
mFullScreen = !mFullScreen;
if(mFullScreen) {
showFullScreen();
}
else {
showNormal();
}
updateGL();
break;
}
case Qt::Key_Escape:
{
qApp->exit();
break;
}
}
}

#include "myglwidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyGLWidget w;
w.show();

return a.exec();

————————————————
版權聲

2. OpenGL如何使用固定管線下的著色器渲染一個正方形,並用特殊鍵控制移動

雙緩沖窗口 、 RGBA顏色模式 、 深度測試 、 模板緩沖區 。

GLUT 內部運行著一個本地消息循環,用來調用我們不同時間注冊進來的回調函數。我們可以注冊2個回調函數:1,為窗口改變大小而設置的一個回調函數;2,包含OpenGL渲染的回調函數。

注冊的重塑函數 changeSize 方法的實現,通過 glViewport (GLint x, GLint y, GLsizei width, GLsizei height); 來重新設置窗口的大小,x,y 參數代表窗口中視圖的左下角坐標,而寬度、高度是像素,為表示,通常x,y 都是為0。

注冊的顯示函數 void RenderScene(void) 實現,顯示函數的具體實現步驟
第一步 : 在該方法中我們需要清除一個或者一組特定的緩存區;
緩存區是一塊存著圖像信息的存儲空間,紅色、綠色、藍色和alpha分量通常一起作為顏色緩存區或像素緩存區引用。OpenGL 中不止一種緩沖區(顏色緩存區、深度緩存區和模板緩存區)清除緩存區對數值進行預置; 參數:指定將要清除的緩存的 GL_COLOR_BUFFER_BIT :指示當前激活的用來進行顏色寫入緩沖區 GL_DEPTH_BUFFER_BIT :指示深度緩存區 GL_STENCIL_BUFFER_BIT:指示模板緩沖區。
第二步 :使用一組浮點數來表示紅色,設置繪制需要的顏色
第三步 :將設置的顏色傳遞到存儲著色器,即 GLT_SHADER_IDENTITY 著色器,這個著色器只是使用指定顏色以默認笛卡爾坐標第在屏幕上渲染幾何圖形
第四步 :提交著色器
第五步 :將後台緩沖區進行渲染,然後結束後交換給前台, 在開始的設置openGL 窗口的時候,我們指定要一個雙緩沖區的渲染環境。這就意味著將在後台緩沖區進行渲染,渲染結束後交換給前台。這種方式可以防止觀察者看到可能伴隨著動畫幀與動畫幀之間的閃爍的渲染過程。緩沖區交換平台將以平台特定的方式進行。

第一步 :設置清屏顏色
第二步 :沒有著色器,在OpenGL 核心框架中是無法進行任何渲染的。初始化一個渲染管理器。
第三步 :指定頂點。

3. 怎麼用OpenGL畫兩個立方體

使用壓棧和退棧,glPushMatrix壓棧,可以存儲當前矩陣,glPopMatrix可以彈出上次存儲的矩陣,比如你畫正方形的代碼寫成一個DrawCube()函數,每次調用都調用的是同一個畫正方形的代碼,所以如果你連續調用兩次會把第二個正方形覆蓋第一個,所以你只能看到一個正方形。如果你把代碼改成如下:
glPushMatrix();
DrawCube();// 畫第一個正方形
glTranslatef(10,0,0);// 移動坐標,用於繪制第二個正方形
DrawCube();
glPopMatrix();
這樣就可以顯示兩個正方形了。

4. OpenGL 實現正方形繪制,鍵盤控制移動(三)

其實,在上一次繪制完一個三角形之後,正方形的繪制流程大致是一樣,只是需要控制正方形的移動,我們需要多注冊一個特殊函數,用於監聽方向鍵的移動,並根據移動方向,平移正方形,首先看一下最後實現的效果,當然gif倍速了,將就看吧😓

首先,我們要實現的是一個可以移動的的正方形,而不在是一個靜態的圖形,那麼圖形的頂點數據就不是一個不變的值;那我們應該怎麼設置頂點數據? 一開始,我們的正方形有一個初始位置,當每按壓一次方向鍵(上/下/左/右),那麼整個正方形上的所有點朝某一個方向移動一個步長(每一次移動的量stepSize),移動後的位置都是原來的坐標值加上一個步長,當然,方向不同,stepSize有正負之分,那麼問題可以轉化為 :頂點數據 = 初始頂點數據 + 移動量。這樣我們就可以先將正方形個頂點的坐標先記錄下來,再用兩個變數分別記錄圖形在左右方向、上下方向的移動量記錄下來,即可得到我們實時的正方形頂點位置,也就可以繪制移動的正方形;准備以上數據如下:

從以上初始化數據,我們可以得到如下圖中的正方形,在窗口中的坐標系中的位置,如下圖,圖中的A、B、C、D的坐標,對應於正方形的頂點數據,圖中的原點O的坐標為(0,0,0),我們將這個點選為我們移動的參照點,及通過它移動後的坐標剛好對應(xPos,yPos, 0);以通過它來做邊界碰撞的判斷;

接下來看主函數的工作:主函數中我們需要:1、初始化GLUT庫;2、設置窗口模式、大小、標題;3.注冊需要回調的函數;4、設置渲染環境;5、啟動GLUT Roop;

在主函數中注冊的三個函數:ChangeSize、RenderScene、SpecialKey會在GLUT Roop收到對應的消息時,觸發回調,其流程如下

接下來看一下具體函數的實現,首先看主函數

設置渲染環境的setupRC,這里頂點的鏈接模式,我們改為了平面鏈接模式GL_TRIANGLE_FAN,並且頂點為4個

窗口的初始化或大小發生改變的回調函數,ChangeSize函數;

需要渲染時的函數RenderScene的實現

當我們按下方向鍵時,觸發的的時SpecialKeys,當按一次左方向鍵,圖形發生如下改變,很容易得到這個時候的移動量的值,xPos -=stepSize;同理可得到向右移動一次時,xPos += stepSize;我們也同樣可以得到向上或向下移動的yPos的變化,向上移動一次 yPos += stepSize;向下移動時 yPos -= stepSize;

我們想要正方形只在窗口中移動,那麼當正方向碰到邊時,我們應該讓其停下來,我們知道x軸方向和y軸方向的坐標范圍都為[-1.0f,1.0f],下圖中畫出了正方形移動到各端邊界時的直觀圖,當然不一定只在x軸方向、或y軸移動,圖示只是為了理解邊界碰撞的坐標判斷,我們一直以中心點為移動量基準點,所以圖中4個紅點的位置,即是正方形在各方向的最大移動量的情況,我們想要正方形不超出最左端,那必須xPos>= -1.0 + blockSize,不超出最右端的條件時 xPos <= 1.0 - blockSize;同理,不超出最頂點yPos <= 1.0 - blockSize; 不超出最底端 yPos >= -1.0 + blockSize;

邊界效果

SpecialKeys的具體實現:

5. 怎麼用OpenGL繪制一個紅色的正方形

int DrawGLScene(GLvoid) // 此過程中包括所有的繪制代碼 { glColor3f(0.5f,0.5f,1.0f); // 一次性將當前色設置為藍色 glBegin(GL_QUADS); // 繪制正方形 glVertex3f(-1.0f, 1.0f, 0.0f); // 左上 glVertex3f( 1.0f, 1.0f, 0.0f); // 右上 glVertex3f( 1.0f,-1.0f, 0.0f); // 左下 glVertex3f(-1.0f,-1.0f, 0.0f); // 右下 glEnd(); // 正方形繪制結束 return TRUE; // 繼續運行 } if (keys[VK_F1]) { keys[VK_F1]=FALSE; KillGLWindow(); fullscreen=!fullscreen; if (!CreateGLWindow("NeHe"s Color Tutorial",640,480,16,fullscreen)) { return 0; } }

6. android 中opengl畫正方體,其頂底坐標還有索引是怎麼計算和定義的

opengl es畫圖形都是通過三角形來畫的,當然還可以畫直線和點
畫圖形的時候有兩種方法:glDrawArrays( ) 和glDrawElements( )

比如畫一個由2個三角形組成的正方形,左上角坐標是l,t,右下角坐標是r,b
使用glDrawArrays繪制時,畫2個三角形,需要這樣傳:
(l,t),(r,t),(l,b)
(r,t),(r,b),(l,b)
也就是說傳的頂點數據就是按照順時針或者逆時針排好順序的,兩個三角形的6個頂點

而用glDrawElements畫的話可以這樣
float coord[4][2]={{l,t},{r,t},{r,b},{l,b}};
繪制時用索引指定頂點順序:
0,1,3
1,2,3

也就是說glDrawArrays傳輸或指定的數據是最終的真實數據,在繪制時效能更好
而glDrawElements指定的是真實數據的調用索引,在內存/顯存佔用上更節省

7. 如何使用OPENGL繪制立方體可以的話將代碼寫一下

#include <GL/glut.h>
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
glutWireCube(0.5);
glutSwapBuffers();
}
void reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-4.0,4.0,-4.0,4.0,-4.0,4.0);
}
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
glColor3f(0.0,0.0,0.0);
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("cube");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
init();
glutMainLoop();
}

8. 如何使用OPENGL繪制立方體

#include void display() { glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0); glutWireCube(0.5); glutSwapBuffers(); } void reshape(int w,int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-4.0,4.0,-4.0,4.0,-4.0,4.0); } void init() { glClearColor(1.0,1.0,1.0,1.0); glColor3f(0.0,0.0,0.0); } int main(int argc,char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("cube"); glutReshapeFunc(reshape); glutDisplayFunc(display); init(); glutMainLoop(); }

9. opengl怎麼畫正方形和園編程

有個專門畫矩形的函數,可以實現正方形的繪制。

圓,可以用線來繪制,先確定圓上的點,然後用線把點連接起來,點越多,圓越圓。

10. opengl下怎麼畫立方體

#include <GL/glut.h>
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
glutWireCube(0.5);
glutSwapBuffers();
}
void reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-4.0,4.0,-4.0,4.0,-4.0,4.0);
}
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
glColor3f(0.0,0.0,0.0);
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("cube");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
init();
glutMainLoop();
}

閱讀全文

與opengl畫正方體編程相關的資料

熱點內容
上海石化哪裡下app 瀏覽:335
滑鼠宏定義編程 瀏覽:298
吉利帝豪用什麼手機連接伺服器 瀏覽:923
javajson自定義 瀏覽:252
51單片機串口多機通信 瀏覽:873
單片機實習生啥也不會 瀏覽:347
手機app拼多多回復率在哪裡看 瀏覽:365
java字元串是否迴文 瀏覽:191
sbtspark源碼 瀏覽:397
緩解壓力的飲料有哪些 瀏覽:608
書信選pdf 瀏覽:674
主機和雲伺服器的介面 瀏覽:963
鋼鐵能被壓縮么 瀏覽:90
程序員多久可以提漲工資 瀏覽:814
公司購買阿里雲伺服器幹嘛用 瀏覽:426
php如何導入excel文件 瀏覽:237
同撈同煲哪個app可以看 瀏覽:861
微信查卷優惠券源碼 瀏覽:480
伺服器光碟機線怎麼插 瀏覽:12
新生兒下載哪個app好 瀏覽:487