qt5.6.0 opengl —— 纹理贴图

对于CUBE这个例子,之前分析了它的框架,至于图怎么弄上去的还怎么细看。现在尝试弄了一下。首先分析它怎么对应的,原本是一张图,怎么分成六面的。于是像高中时代那样开始了计算理解

      这样就清楚多了,一张图,划分为6个块,一个面一块。

      至于归一化,可能是

    // Wrap texture coordinates by repeating
    // f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2)
    texture->setWrapMode(QOpenGLTexture::Repeat);

这句话在起作用。


      再前一篇的框架下修改

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #ifndef GLWIGDET_H  
  2. #define GLWIGDET_H  
  3.   
  4. #include <QOpenGLWidget>  
  5. #include <QOpenGLFunctions>  
  6. #include <QOpenGLShaderProgram>  
  7.   
  8. #include <QMouseEvent>  
  9. #include <QTimerEvent>  
  10. #include <QKeyEvent>  
  11. #include <QBasicTimer>  
  12. #include <QVector3D>  
  13. #include <QVector2D>  
  14.   
  15. /* 从OpenGL 3开始,编程模式被分为3种: 
  16.  * 1.兼容模式:即传统的方式 
  17.  * 2.核心模式:完全新式纯可编程流水线模式,但兼容废弃特性。(注:API不兼容旧的) 
  18.  * 3.核心向前兼容模式:完全不兼容废弃特性,其它同核心模式。(主要表现在线宽、线调色板这一类,其它同核心模式) 
  19.  *******************************************************************************************/  
  20.   
  21. class GLWigdet : public QOpenGLWidget, protected QOpenGLFunctions  
  22. {  
  23.     Q_OBJECT  
  24. public:  
  25.     GLWigdet(QWidget *parent = 0);  
  26.   
  27. protected:  
  28.     void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;  
  29.     void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE;  
  30.     void timerEvent(QTimerEvent *e) Q_DECL_OVERRIDE;  
  31.     void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE;  
  32.   
  33.     void initializeGL() Q_DECL_OVERRIDE;  
  34.     void resizeGL(int w, int h) Q_DECL_OVERRIDE;  
  35.     void paintGL() Q_DECL_OVERRIDE;  
  36.   
  37.     void initShaders();  
  38.   
  39.     virtual void do_init() {}  
  40.     virtual void do_paint() {}  
  41.     virtual void do_resize() {}  
  42.   
  43.     int attribLocation(const char *name) {  
  44.         return program.attributeLocation(name);  
  45.     }  
  46.   
  47.     void enableAttribArray(int location) {  
  48.         program.enableAttributeArray(location);  
  49.     }  
  50.   
  51.     void setAttribBuffer  
  52.             (int location, GLenum type, int offset, int tupleSize, int stride = 0)  
  53.     {  
  54.         program.setAttributeBuffer(location, type, offset, tupleSize, stride);  
  55.     }  
  56.   
  57.     void setUnifValue(const char *name, GLfloat value)  
  58.     {  
  59.         program.setUniformValue(name, value);  
  60.     }  
  61.   
  62. private:  
  63.     QBasicTimer timer;  
  64.     QVector2D mousePressPosition;  
  65.     QVector3D rotationAxis;  
  66.     qreal angularSpeed;  
  67.     QQuaternion rotation;  
  68.     QMatrix4x4 m_proj;   /* 投影矩阵 */  
  69.     QOpenGLShaderProgram program;  
  70. };  
  71.   
  72. #endif // GLWIGDET_H  
      

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #ifndef DRAWTRIANGLE_H  
  2. #define DRAWTRIANGLE_H  
  3.   
  4. #include "glwigdet.h"  
  5.   
  6. #include <QOpenGLBuffer>  
  7. #include <QOpenGLVertexArrayObject>  
  8. #include <QOpenGLTexture>  
  9.   
  10. class DrawTriangle : public GLWigdet  
  11. {  
  12. public:  
  13.     DrawTriangle(QWidget *parent = 0);  
  14.     ~DrawTriangle();  
  15.   
  16. protected:  
  17.     void initTextures();  
  18.     void do_init() Q_DECL_OVERRIDE;  
  19.     void do_paint() Q_DECL_OVERRIDE;  
  20.   
  21. private:  
  22.     int num;  
  23.     QOpenGLBuffer arrayBuf;  
  24.     QOpenGLShaderProgram *program;  
  25.   
  26.     QOpenGLTexture *texture;  
  27. };  
  28.   
  29. #endif // DRAWTRIANGLE_H  

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include "drawtriangle.h"  
  2.   
  3. #include <QVector>  
  4.   
  5. DrawTriangle::DrawTriangle(QWidget *parent)  
  6.     : GLWigdet(parent), num(0),  
  7.       arrayBuf(QOpenGLBuffer::VertexBuffer)  
  8. {  
  9.     setWindowTitle("绘制三角形");  
  10.   
  11.     program = NULL;  
  12.     texture = NULL;  
  13. }  
  14.   
  15. DrawTriangle::~DrawTriangle()  
  16. {  
  17.     // Make sure the context is current when deleting the buffers.  
  18.     makeCurrent();  
  19.     arrayBuf.destroy();  
  20.     if(texture)  
  21.         delete texture;  
  22.     doneCurrent();  
  23. }  
  24.   
  25. void DrawTriangle::initTextures()  
  26. {  
  27.     // Load cube.png image  
  28.     texture = new QOpenGLTexture(QImage(":/textures/uname.jpg").mirrored());  
  29.   
  30.     // Set nearest filtering mode for texture minification  
  31.     texture->setMinificationFilter(QOpenGLTexture::Nearest);  
  32.   
  33.     // Set bilinear filtering mode for texture magnification  
  34.     texture->setMagnificationFilter(QOpenGLTexture::Linear);  
  35.   
  36.     // Wrap texture coordinates by repeating  
  37.     // f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2)  
  38.     texture->setWrapMode(QOpenGLTexture::Repeat);  
  39. }  
  40.   
  41. void DrawTriangle::do_init()  
  42. {  
  43.     initializeOpenGLFunctions();  
  44.   
  45.     // Enable back face culling  
  46.     glEnable(GL_CULL_FACE);  
  47.   
  48.     initTextures();  
  49.   
  50.     GLfloat vertData[] = {  
  51.         0.0f, 0.0f, 0.0f,  
  52.         1.0f, 0.0f, 0.0f,  
  53.         0.0f, 1.0f, 0.0f,  
  54.         1.0f, 1.0f, 0.0f,  
  55.     };  
  56.   
  57.     num = 4;  
  58.     /* arrayBuf should create here */  
  59.     // Transfer vertex data to VBO 0  
  60.     arrayBuf.create();  
  61.     arrayBuf.bind();  
  62.     arrayBuf.allocate(vertData, num * 3 * sizeof(GLfloat));  
  63.     arrayBuf.release();  
  64. }  
  65.   
  66. void DrawTriangle::do_paint()  
  67. {  
  68.     // Tell OpenGL which VBOs to use  
  69.     texture->bind();  
  70.     arrayBuf.bind();  
  71.   
  72.     // Use texture unit 0 which contains cube.png  
  73.     setUnifValue("texture", 0);  
  74.   
  75.     // Tell OpenGL programmable pipeline how to locate vertex position data  
  76.     int a_pos = attribLocation("a_position");  
  77.     enableAttribArray(a_pos);  
  78.     setAttribBuffer(a_pos, GL_FLOAT, 0, 3, 3 * sizeof(GLfloat));  
  79.   
  80.     // Tell OpenGL programmable pipeline how to locate vertex texture coordinate data  
  81.     int a_tex = attribLocation("a_texcoord");  
  82.     enableAttribArray(a_tex);  
  83.     setAttribBuffer(a_tex, GL_FLOAT, 0, 2, 3 * sizeof(GLfloat));  
  84.   
  85.     // Draw cube geometry using indices from VBO 1  
  86.     //glDrawElements(GL_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, NULL);  
  87.   
  88.     /* 三角形 */  
  89.     glDrawArrays(GL_TRIANGLE_STRIP, 0, num);  
  90.   
  91.     arrayBuf.release();  
  92.     texture->release();  
  93.   
  94.     glFlush();  
  95. }  

      成功之前一直纠结于“程序异常退出”、出现窗体了但没有图像画出来。

      原来在我的这个框架下,

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. arrayBuf.create();  
需要放在init()中才会去创建,放在构造函数里不行。


      结果:


      修改为锥体,这里有个问题,也是个巧点。

      如果以锥体底面圆心为坐标原点,而纹理图的坐标原点是左下角的顶点。这样,如果学cube例子

struct VertexData
{
    QVector3D position;
    QVector2D texCoord;
};

     因为点比较多,不可能向cube那样一个一个列出来,肯定要用什么存储起来

QVector<VertexData> vertData,若这样做,最后出来的锥体是白色的,没有纹理。


     所以,将坐标原点设置和纹理原点一样,同时纹理归一化了,将半径r设置为0.5f,这样,纹理相应点的坐标就是锥体相应点的坐标的二维。


     最后的效果:



      





from: http://blog.csdn.net/fu851523125/article/details/51626948

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值