天天看點

NeHe-OpenGL-Qt5-Lesson11-注釋與學習-WavingTextureMap

通過更改頂點坐标和紋理坐标來形成随風飄揚的效果。

NeHe-OpenGL-Qt5-Lesson11-注釋與學習-WavingTextureMap

主要代碼:

for(int x = 0; x < 44; x++ )
    {
        for(int y = 0; y < 44; y++ )
        {
            float_x = float(x)/44.0f;
            float_y = float(y)/44.0f;
            float_xb = float(x+1)/44.0f;
            float_yb = float(y+1)/44.0f;
            GLfloat vertexs[] =
            {
                m_points[x][y][0], m_points[x][y][1], m_points[x][y][2],
                m_points[x+1][y][0], m_points[x+1][y][1], m_points[x+1][y][2],
                m_points[x][y+1][0], m_points[x][y+1][1], m_points[x][y+1][2],
                m_points[x+1][y+1][0], m_points[x+1][y+1][1], m_points[x+1][y+1][2]
            };
            GLfloat texCoords[] =
            {
                float_x, float_y,
                float_xb, float_y,
                float_x, float_yb,
                float_xb, float_yb
            };

            m_program->enableAttributeArray(m_posAttr);
            m_program->setAttributeArray(m_posAttr, GL_FLOAT, vertexs, 3);
            m_program->enableAttributeArray(m_texCoordAttr);
            m_program->setAttributeArray(m_texCoordAttr, GL_FLOAT, texCoords, 2);
            glCullFace(GL_BACK);
            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
            glCullFace(GL_FRONT);
            glDrawArrays(GL_LINE_LOOP, 0, 4);
        }
    }
           

通過二個循環,改變頂點和紋理的坐标,進而産生飄揚的效果。

全部代碼:

texturemappingwindow.h

#ifndef TEXTUREMAPPINGWINDOW_H
#define TEXTUREMAPPINGWINDOW_H

#include "openglwindow.h"
#include <QOpenGLShaderProgram>
#include <QtMath>

class TextureMappingWindow : public OpenGLWindow
{
    Q_OBJECT
public:
    explicit TextureMappingWindow(QWindow *parent = 0);
    ~TextureMappingWindow();
protected:
    void initialize();
    void render();
private:
    void loadGLTexture();

    void loadShader();

    void initGeometry();
private:
    QOpenGLShaderProgram *m_program;
    GLuint m_posAttr;
    GLuint m_texCoordAttr;

    GLfloat m_xrot;
    GLfloat m_yrot;
    GLfloat m_zrot;
    GLuint m_texture;
    float m_points[45][45][3];
};

#endif // TEXTUREMAPPINGWINDOW_H
           

texturemappingwindow.cpp

#include "texturemappingwindow.h"

TextureMappingWindow::TextureMappingWindow(QWindow *parent) :
    OpenGLWindow(parent), m_xrot(0.0f), m_yrot(0.0f), m_zrot(0.0f),
    m_texture(-1)
{
}

TextureMappingWindow::~TextureMappingWindow()
{
    glDeleteTextures(1, &m_texture);
}

void TextureMappingWindow::initialize()
{
    initGeometry();
    loadShader();
    loadGLTexture();
    glEnable(GL_TEXTURE_2D);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepthf(1.0f);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glDepthFunc(GL_LEQUAL);
}

void TextureMappingWindow::render()
{
    float float_x, float_y, float_xb, float_yb;
    m_program->bind();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    m_modelView.setToIdentity();
    m_modelView.translate(0.0f, 0.0f, -12.0f);
    m_modelView.rotate(m_xrot, 1.0f, 0.0f, 0.0f);
    m_modelView.rotate(m_yrot, 0.0f, 1.0f, 0.0f);
    m_modelView.rotate(m_zrot, 0.0f, 0.0f, 1.0f);
    m_program->setUniformValue("mvpMatrix", m_projection * m_modelView);
    glBindTexture(GL_TEXTURE_2D, m_texture);
    for(int x = 0; x < 44; x++ )
    {
        for(int y = 0; y < 44; y++ )
        {
            float_x = float(x)/44.0f;
            float_y = float(y)/44.0f;
            float_xb = float(x+1)/44.0f;
            float_yb = float(y+1)/44.0f;
            GLfloat vertexs[] =
            {
                m_points[x][y][0], m_points[x][y][1], m_points[x][y][2],
                m_points[x+1][y][0], m_points[x+1][y][1], m_points[x+1][y][2],
                m_points[x][y+1][0], m_points[x][y+1][1], m_points[x][y+1][2],
                m_points[x+1][y+1][0], m_points[x+1][y+1][1], m_points[x+1][y+1][2]
            };
            GLfloat texCoords[] =
            {
                float_x, float_y,
                float_xb, float_y,
                float_x, float_yb,
                float_xb, float_yb
            };

            m_program->enableAttributeArray(m_posAttr);
            m_program->setAttributeArray(m_posAttr, GL_FLOAT, vertexs, 3);
            m_program->enableAttributeArray(m_texCoordAttr);
            m_program->setAttributeArray(m_texCoordAttr, GL_FLOAT, texCoords, 2);
            glCullFace(GL_BACK);
            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
            glCullFace(GL_FRONT);
            glDrawArrays(GL_LINE_LOOP, 0, 4);
        }
    }
    m_program->release();

    for(int y = 0; y < 45; y++ )
    {
        GLfloat hold = m_points[0][y][2];
        for(int x = 0; x < 44; x++)
        {
            m_points[x][y][2] = m_points[x+1][y][2];
        }
        m_points[44][y][2]=hold;
    }
    m_xrot+=0.3f;
    m_yrot+=0.2f;
    m_zrot+=0.4f;
}

void TextureMappingWindow::loadGLTexture()
{
    QImage image(":/image/Tim.bmp");
    image = image.convertToFormat(QImage::Format_RGB888);
    image = image.mirrored();

    glGenTextures(1, &m_texture);
    glBindTexture(GL_TEXTURE_2D, m_texture);
    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 TextureMappingWindow::loadShader()
{
    m_program = new QOpenGLShaderProgram(this);
    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vertshader.glsl");
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fragshader.glsl");
    m_program->link();
    m_posAttr = m_program->attributeLocation("posAttr");
    m_texCoordAttr = m_program->attributeLocation("texCoordAttr");
}

void TextureMappingWindow::initGeometry()
{
    for(int x=0; x<45; x++)
    {
        for(int y=0; y<45; y++)
        {
            m_points[x][y][0]=float((x/5.0f)-4.5f);
            m_points[x][y][1]=float((y/5.0f)-4.5f);
            m_points[x][y][2]=float(qSin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));
        }
    }
}
           

多謝,親愛的美美。

繼續閱讀