閃爍的星星(Nehe)

來源:互聯網
上載者:User

 以下代碼示範與Nehe教程第九課中一樣的效果。第十課中三維的暫不實現。主要使用紋理貼圖相關方面知識。

WStar.h

#pragma once<br />#include <QtOpenGL/QtOpenGL></p><p>/** @brief星星描述*/<br />class WStar<br />{<br />public:<br />WStar(void);<br />~WStar(void);</p><p>/** 顏色分量*/<br />int m_iR;<br />int m_iG;<br />int m_iB;</p><p>// 距離中心距離<br />GLfloat m_dDistance;</p><p>// 所處角度<br />GLfloat m_dAngle;<br />};  

 

WStar.cpp

#include "WStar.h"</p><p>WStar::WStar(void)<br />: m_iR(0)<br />, m_iG(0)<br />, m_iB(0)<br />, m_dDistance(0.0)<br />, m_dAngle(0.0)<br />{<br />}</p><p>WStar::~WStar(void)<br />{<br />}

wglwidget.h

#ifndef WGLWIDGET_H<br />#define WGLWIDGET_H</p><p>#include <QtGui/QWidget><br />#include <QtOpenGL/QtOpenGL><br />#include "ui_wglwidget.h"<br />#include "wstar.h"</p><p>class WGLWidget : public QGLWidget , public Ui::WGLWidgetClass<br />{<br />Q_OBJECT</p><p>public:<br />WGLWidget(QWidget *parent = 0, const QGLWidget* shareEidget = 0,Qt::WFlags flags = 0);<br />~WGLWidget();</p><p>protected:<br />virtual void initializeGL();<br />virtual void resizeGL(int w, int h);<br />virtual void paintGL();</p><p>virtual void keyPressEvent(QKeyEvent *event);<br />virtual void timerEvent(QTimerEvent *event);<br />virtual void mouseDoubleClickEvent(QMouseEvent *event);<br />virtual void closeEvent(QCloseEvent *event);</p><p>private:<br />/** @brief建立紋理*/<br />boolmakeGLTexture();</p><p>/** @brief初始化星星狀態*/<br />voidinitStarts();</p><p>private:<br />GLfloatm_dZoom;///< 星星Z值<br />boolm_bTwinkle;///< 星星是否閃爍<br />GLfloatm_dTilt;///< 星星傾角<br />GLfloat m_dSpin;///< 星星自傳角度</p><p>QVector<WStar>m_vecStars;///< 儲存所有星星</p><p>enum WTexture<br />{<br />texStar = 1<br />};</p><p>GLuintm_uiTexture[texStar];</p><p>staticconst int m_iNum = 50;///< 星星個數<br />};</p><p>#endif // WGLWIDGET_H

 

wglwidget.cpp

 

 #include "wglwidget.h"<br />#include <math.h></p><p>const GLfloat PI = 3.1415926536f;</p><p>WGLWidget::WGLWidget(QWidget *parent /* = 0 */, const QGLWidget* shareEidget /* = 0 */,Qt::WFlags flags /* = 0 */)<br />: QGLWidget(parent, shareEidget, flags)<br />, m_bTwinkle(false)<br />, m_dZoom(-15.0)<br />, m_dTilt(90.0)<br />, m_dSpin(0.0)<br />{<br />setupUi(this);</p><p>setMinimumSize(320,240);</p><p>resize(640,480);<br />setWindowTitle(tr("星星動畫"));</p><p>initStarts();</p><p>startTimer(10);<br />}</p><p>WGLWidget::~WGLWidget()<br />{</p><p>}</p><p>void WGLWidget::initializeGL()<br />{<br />glShadeModel(GL_SMOOTH);</p><p>glClearColor(0.0,0.0,0.0,0.0);<br />glClearDepth(1.0);</p><p>glEnable(GL_DEPTH_TEST);</p><p>glDepthFunc(GL_LEQUAL);<br />glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);</p><p>// 載入紋理<br />makeGLTexture();</p><p>// 啟用紋理<br />glEnable(GL_TEXTURE_2D);</p><p>// 啟用混合<br />glBlendFunc(GL_SRC_ALPHA,GL_ONE);// 設定混色函數取得半透明效果<br />glEnable(GL_BLEND);// 啟用混色<br />}<br />void WGLWidget::resizeGL(int w, int h)<br />{<br />glViewport(0,0,(GLint)width(),(GLint)height());</p><p>glMatrixMode(GL_PROJECTION);<br />glLoadIdentity();</p><p>gluPerspective(45.0,(GLfloat)width() / (GLfloat)height(),0.1,100.0);<br />glMatrixMode(GL_MODELVIEW);</p><p>glLoadIdentity();<br />}<br />void WGLWidget::paintGL()<br />{<br />glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);</p><p>glPushMatrix();</p><p>glBindTexture(GL_TEXTURE_2D,m_uiTexture[0]);<br />for (int loop=0;loop<m_iNum;loop++)// 迴圈設定所有的星星<br />{<br />glPushMatrix();// 繪製每顆星星之前,重設模型觀察矩陣<br />glTranslatef(0.0f,0.0f,m_dZoom);// 深入螢幕裡面<br />glRotatef(m_dTilt,1.0f,0.0f,0.0f);// 傾斜視角</p><p>glRotatef(m_vecStars[loop].m_dAngle,0.0f,1.0f,0.0f);// 旋轉至當前所畫星星的角度<br />glTranslatef(m_vecStars[loop].m_dDistance,0.0f,0.0f);// 沿X軸正向移動</p><p>glRotatef(-m_vecStars[loop].m_dAngle,0.0f,1.0f,0.0f);// 取消當前星星的角度<br />glRotatef(-m_dTilt,1.0f,0.0f,0.0f);// 取消螢幕傾斜</p><p>if (m_bTwinkle)// 啟用閃爍效果<br />{<br />// 使用byte型數值指定一個顏色<br />glColor4ub(m_vecStars[(m_iNum-loop)-1].m_iR,m_vecStars[(m_iNum-loop)-1].m_iG,m_vecStars[(m_iNum-loop)-1].m_iB,255);<br />glBegin(GL_QUADS);// 開始繪製紋理映射過的四邊形<br />glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);<br />glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f);<br />glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);<br />glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);<br />glEnd();// 四邊形繪製結束<br />}</p><p>glRotatef(m_dSpin,0.0f,0.0f,1.0f);// 繞z軸旋轉星星<br />// 使用byte型數值指定一個顏色<br />glColor4ub(m_vecStars[loop].m_iR,m_vecStars[loop].m_iG,m_vecStars[loop].m_iB,255);<br />glBegin(GL_QUADS);// 開始繪製紋理映射過的四邊形<br />glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);<br />glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f);<br />glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);<br />glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);<br />glEnd();// 四邊形繪製結束</p><p>m_dSpin +=0.01f;// 星星的公轉<br />m_vecStars[loop].m_dAngle += float(loop)/m_iNum;// 改變星星的自轉角度<br />m_vecStars[loop].m_dDistance -= 0.01f;// 改變星星離中心的距離</p><p>if (m_vecStars[loop].m_dDistance < 0.0f)// 星星到達中心了麼<br />{<br />m_vecStars[loop].m_dDistance +=5.0f;// 往外移個單位<br />m_vecStars[loop].m_iR = rand()%256;// 賦一個新紅色分量<br />m_vecStars[loop].m_iG = rand()%256;// 賦一個新綠色分量<br />m_vecStars[loop].m_iB = rand()%256;// 賦一個新藍色分量<br />}</p><p>glPopMatrix();<br />}</p><p>glPopMatrix();<br />}</p><p>void WGLWidget::timerEvent(QTimerEvent *event)<br />{<br />update();<br />}</p><p>void WGLWidget::mouseDoubleClickEvent(QMouseEvent *event)<br />{<br />if(windowState() & Qt::WindowFullScreen)<br />showNormal();<br />else<br />showFullScreen();<br />}</p><p>void WGLWidget::keyPressEvent(QKeyEvent *event)<br />{<br />switch(event->key())<br />{<br />case Qt::Key_T:<br />{<br />m_bTwinkle = !m_bTwinkle;<br />}<br />break;<br />case Qt::Key_Home:<br />m_dZoom -= 0.2;<br />break;<br />case Qt::Key_End:<br />m_dZoom += 0.2;<br />break;<br />case Qt::Key_Up:<br />m_dTilt += 0.5;<br />break;<br />case Qt::Key_Down:<br />m_dTilt -= 0.5;<br />break;<br />default:<br />break;<br />}<br />}</p><p>void WGLWidget::closeEvent(QCloseEvent *event)<br />{<br />QMessageBox box;<br />box.setWindowTitle(tr("退出"));<br />box.setIcon(QMessageBox::Warning);<br />box.setText(tr("確定要關閉OpenGL視窗嗎?"));<br />box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);<br />if(QMessageBox::No == box.exec())<br />{<br />event->ignore();<br />return;<br />}</p><p>QWidget::closeEvent(event);<br />}</p><p>bool WGLWidget::makeGLTexture()<br />{<br />QImage tex,buffer;<br />QString str("Image/Star.bmp");</p><p>if(!buffer.load(str))<br />{<br />QMessageBox::warning(this,tr("提示"),tr("載入紋理圖片失敗,程式將異常顯示!"));<br />return false;<br />}</p><p>tex = QGLWidget::convertToGLFormat(buffer);</p><p>glGenTextures(texStar,&m_uiTexture[0]);<br />glBindTexture(GL_TEXTURE_2D,m_uiTexture[0]);<br />glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,tex.width(),tex.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,tex.bits());<br />glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);<br />glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);</p><p>return true;<br />}</p><p>void WGLWidget::initStarts()<br />{<br />m_vecStars.resize(m_iNum);</p><p>// 建立迴圈設定全部星星<br />for(int loop=0;loop<m_iNum;++loop)<br />{<br />m_vecStars[loop].m_dAngle = 0.0f;// 所有星星都從零角度開始<br />m_vecStars[loop].m_dDistance = (float(loop)/m_iNum)*5.0f;// 計算星星離中心的距離<br />m_vecStars[loop].m_iR = rand()%256;// 設定隨機紅色分量<br />m_vecStars[loop].m_iG = rand()%256;// 設定隨機紅色分量<br />m_vecStars[loop].m_iB = rand()%256;// 設定隨機紅色分量<br />}<br />}

 


程式運行效果

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.