OpenGL dibuja un cono

    Para dibujar un cono no he encontrado un modelo para dibujarlo completo, por el momento utilizo dos objetos para empalmarlo: un círculo y una superficie de cono.

Desventaja: esto requiere dibujar dos veces para dibujar el cono con éxito.

#include "cone.h"
#include <QTimer>
#include <QDateTime>
#include <QImage>
#include <glm-master/glm/gtc/matrix_transform.hpp>
#include <glm-master/glm/gtc/type_ptr.hpp>
#include <QtMath>

#define POINT_COUNT (362)

static float circleVertices[POINT_COUNT*3];

static float coneVertices[POINT_COUNT*3];


Cone::Cone(QWidget* parent)
{
    QTimer * timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(17);
    mProjectionMatrix = glm::mat4(1.0f);
    mViewMatrix = glm::mat4(1.0f);
    mModelMatrix = glm::mat4(1.0f);

    //center
    circleVertices[0] = 0;
    circleVertices[1] = 0;
    circleVertices[2] = 0;
    coneVertices[0] = 0;
    coneVertices[1] = 0;
    coneVertices[2] = 1.0;
    float r = 0.5f;

    for(int i = 1; i <= POINT_COUNT - 1; i++) {
        int index = i*3;
        circleVertices[index] = r * sin(i * M_PI/ 180.0f);
        circleVertices[index+1] = r * cos(i * M_PI/ 180.0f);
        circleVertices[index+2] = 0;

        coneVertices[index] = r * sin(i * M_PI/ 180.0f);
        coneVertices[index+1] = r * cos(i * M_PI/ 180.0f);
        coneVertices[index+2] = 0;
    }
}

void Cone::initializeGL()
{
    bool enabled = initializeOpenGLFunctions();
    qDebug() << "initializeGL" << enabled;

    glGenVertexArrays(1, &mCircleVAO);
    glGenBuffers(1, &mCircleVBO);
    glBindVertexArray(mCircleVAO);

    glBindBuffer(GL_ARRAY_BUFFER, mCircleVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(circleVertices), circleVertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);


    glGenVertexArrays(1, &mConeVAO);
    glGenBuffers(1, &mConeVBO);
    glBindVertexArray(mConeVAO);

    glBindBuffer(GL_ARRAY_BUFFER, mConeVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(coneVertices), coneVertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    mConeProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/cone.vsh");
    mConeProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/cone.fsh");
    bool success = mConeProgram.link();
    if(!success){
        qDebug() << "ERR: " << mConeProgram.log();
    }
    mCircleProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/circle.vsh");
    mCircleProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/circle.fsh");
    success = mCircleProgram.link();
    if(!success){
        qDebug() << "ERR: " << mCircleProgram.log();
    }

    mConeProjectionLoc = mConeProgram.uniformLocation("projection");
    mConeViewLoc = mConeProgram.uniformLocation("view");
    mConeModelLoc = mConeProgram.uniformLocation("model");

    mCircleProjectionLoc = mCircleProgram.uniformLocation("projection");
    mCircleViewLoc = mCircleProgram.uniformLocation("view");
    mCircleModelLoc = mCircleProgram.uniformLocation("model");
}

void Cone::resizeGL(int w, int h)
{
    mViewMatrix  = glm::translate(mViewMatrix, glm::vec3(0.0f, 0.0f, -3.0f));
    mProjectionMatrix = glm::perspective(glm::radians(45.0f), (float)w / (float)h, 0.1f, 100.0f);
    glEnable(GL_DEPTH_TEST);
}

void Cone::paintGL()
{
    mModelMatrix = glm::rotate(mModelMatrix, 0.01f, glm::vec3(1.0f, 0.0f, 0.0f));
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    mCircleProgram.bind();
    glBindVertexArray(mCircleVAO);
    glUniformMatrix4fv(mCircleProjectionLoc, 1, GL_FALSE, glm::value_ptr(mProjectionMatrix));
    glUniformMatrix4fv(mCircleViewLoc, 1, GL_FALSE, glm::value_ptr(mViewMatrix));
    glUniformMatrix4fv(mCircleModelLoc, 1, GL_FALSE, glm::value_ptr(mModelMatrix));
    glDrawArrays(GL_TRIANGLE_FAN, 0, POINT_COUNT);

    mConeProgram.bind();
    glBindVertexArray(mConeVAO);
    glUniformMatrix4fv(mConeProjectionLoc, 1, GL_FALSE, glm::value_ptr(mProjectionMatrix));
    glUniformMatrix4fv(mConeViewLoc, 1, GL_FALSE, glm::value_ptr(mViewMatrix));
    glUniformMatrix4fv(mConeModelLoc, 1, GL_FALSE, glm::value_ptr(mModelMatrix));
    glDrawArrays(GL_TRIANGLE_FAN, 0, POINT_COUNT);
}

Para facilitar la comprensión, se preparan un conjunto de VAO, VBO y Programa respectivamente.

Supongo que te gusta

Origin blog.csdn.net/jake9602/article/details/126050860
Recomendado
Clasificación