OpenGL画坐标系2

此项目为“OpenGL画坐标系1”的拓展,1的链接:https://blog.csdn.net/qq_37996632/article/details/103149535

思路:在原有的直线坐标轴上加上一个小的四棱锥,当然圆锥也可以,不过绘制圆锥的难度要大一点。

整体效果如下:

 

项目整体目录如下: 

注意:对比“OpenGL画坐标系1”,修改了Coordinate.h,Coordinate.cpp,Widget.cpp三个文件,并且删除了y轴和z轴的着色器文件,整合到一个着色器文件里。

 

Coordinate.h 

#ifndef COORDINATE_H
#define COORDINATE_H
#include <QOpenGLExtraFunctions>

class Coordinate : protected QOpenGLExtraFunctions
{
public:
    Coordinate();
    ~Coordinate();

    void init();

    void drawCoordAxis(GLuint lineVBO, GLfloat *lineVertices, GLuint pyramidVBO, GLfloat *pyramidVertices);
    void drawX();
    void drawY();
    void drawZ();

private:
    GLuint linesVBO[3];    // VBO of lines
    GLuint pyramidsVBO[3];   // VBO of pyramids
};

#endif // COORDINATE_H

Coordinate.cpp 

#include "coordinate.h"
#define VNAME(value) (#value)
#include <QDebug>

// vertices of lines
GLfloat lineXVertices[6] = {
    0.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f
};

GLfloat lineYVertices[] = {
    0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f
};

GLfloat lineZVertices[] = {
    0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f
};

// vertices of pyramids
GLfloat pyramidXVertices[] =
{
    1.0f, 0.01f, 0.01f,     // x1
    1.0f, 0.01f, -0.01f,    // x2
    1.0f, -0.01f, -0.01f,   // x3

    1.0f, 0.01f, 0.01f,     // x1
    1.0f, -0.01f, -0.01f,   // x3
    1.0f, -0.01f, 0.01f,    // x4

    1.1f, 0.0f, 0.0f,       // 0
    1.0f, 0.01f, 0.01f,     // x1
    1.0f, -0.01f, 0.01f,    // x4

    1.1f, 0.0f, 0.0f,       // 0
    1.0f, 0.01f, 0.01f,     // x1
    1.0f, 0.01f, -0.01f,    // x2

    1.1f, 0.0f, 0.0f,       // 0
    1.0f, 0.01f, -0.01f,    // x2
    1.0f, -0.01f, -0.01f,   // x3

    1.1f, 0.0f, 0.0f,       // 0
    1.0f, -0.01f, -0.01f,   // x3
    1.0f, -0.01f, 0.01f     // x4
};

GLfloat pyramidYVertices[] =
{
    0.01f, 1.0f, -0.01f,    // x1
    -0.01f, 1.0f, -0.01f,   // x2
    -0.01f, 1.0f, 0.01f,    // x3

    0.01f, 1.0f, -0.01f,    // x1
    -0.01f, 1.0f, 0.01f,    // x3
    0.01f, 1.0f, 0.01f,     // x4

    0.0f, 1.1f, 0.0f,       // 0
    0.01f, 1.0f, -0.01f,    // x1
    0.01f, 1.0f, 0.01f,     // x4

    0.0f, 1.1f, 0.0f,       // 0
    0.01f, 1.0f, -0.01f,    // x1
    -0.01f, 1.0f, -0.01f,   // x2

    0.0f, 1.1f, 0.0f,       // 0
    -0.01f, 1.0f, -0.01f,   // x2
    -0.01f, 1.0f, 0.01f,    // x3

    0.0f, 1.1f, 0.0f,       // 0
    -0.01f, 1.0f, 0.01f,    // x3
    0.01f, 1.0f, 0.01f      // x4
};

GLfloat pyramidZVertices[] =
{
    0.01f, 0.01f, 1.0f,     // x1
    -0.01f, 0.01f, 1.0f,    // x2
    -0.01f, -0.01f, 1.0f,   // x3

    0.01f, 0.01f, 1.0f,     // x1
    -0.01f, -0.01f, 1.0f,   // x3
    0.01f, -0.01f, 1.0f,    // x4

    0.0f, 0.0f, 1.1f,       // 0
    0.01f, 0.01f, 1.0f,     // x1
    0.01f, -0.01f, 1.0f,    // x4

    0.0f, 0.0f, 1.1f,       // 0
    0.01f, 0.01f, 1.0f,     // x1
    -0.01f, 0.01f, 1.0f,    // x2

    0.0f, 0.0f, 1.1f,       // 0
    -0.01f, 0.01f, 1.0f,    // x2
    -0.01f, -0.01f, 1.0f,   // x3

    0.0f, 0.0f, 1.1f,       // 0
    -0.01f, -0.01f, 1.0f,   // x3
    0.01f, -0.01f, 1.0f     // x4
};


Coordinate::Coordinate()
{
    this->initializeOpenGLFunctions();
}

Coordinate::~Coordinate()
{
    glDeleteBuffers(3, linesVBO);
    glDeleteBuffers(3, pyramidsVBO);
}

void Coordinate::init()
{
    // generate VBO
    glGenBuffers(3, linesVBO);
    glGenBuffers(3, pyramidsVBO);
}

void Coordinate::drawCoordAxis(GLuint lineVBO, GLfloat *lineVertices, GLuint pyramidVBO, GLfloat *pyramidVertices)
{
    // line
    glBindBuffer(GL_ARRAY_BUFFER, lineVBO);
    // 24为sizeof(lineVertices)的大小,因数组作为参数传递,sizeof()后值为1
    glBufferData(GL_ARRAY_BUFFER, 24, lineVertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glDrawArrays(GL_LINES, 0, 2);

    // pyramid
    glBindBuffer(GL_ARRAY_BUFFER, pyramidVBO);
    glBufferData(GL_ARRAY_BUFFER, 216, pyramidVertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glDrawArrays(GL_TRIANGLES, 0, 18);
}

void Coordinate::drawX()
{
    drawCoordAxis(linesVBO[0], lineXVertices, pyramidsVBO[0], pyramidXVertices);
}

void Coordinate::drawY()
{
    drawCoordAxis(linesVBO[1], lineYVertices, pyramidsVBO[1], pyramidYVertices);
}

void Coordinate::drawZ()
{
    drawCoordAxis(linesVBO[2], lineZVertices, pyramidsVBO[2], pyramidZVertices);
}

 

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLExtraFunctions>
#include <coordinate.h>
#include <shader.h>

class Widget : public QOpenGLWidget, protected QOpenGLExtraFunctions
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;

private:
    Coordinate *coordinate;
    Shader *shader;

    GLuint axisIndex;
};

#endif // WIDGET_H

Widget. cpp

#include "widget.h"

Widget::Widget(QWidget *parent) : QOpenGLWidget(parent)
{
    this->setWindowTitle("Coordinate");
}

Widget::~Widget()
{
    delete shader;
}

void Widget::initializeGL(){
    this->initializeOpenGLFunctions();

    // load shaders
    shader = new Shader(":/shaders/Coordinate.vert",":/shaders/Coordinate.frag");

    coordinate = new Coordinate();
    coordinate->init();

    // set projection and view matrix
    QMatrix4x4 projection, view;
    view.translate(QVector3D(0.0f, -0.5f, -3.0f)); // camera view
    projection.perspective(45.0f, (GLfloat)width() / (GLfloat)height(), 0.1f, 100.0f);

    shader->use();
    shader->setMatrix4f("view", view);
    shader->setMatrix4f("projection", projection);

    glEnable(GL_DEPTH_TEST);
}

void Widget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void Widget::paintGL()
{
    glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    QMatrix4x4 model;
    model.setToIdentity(); // initializing, Set the rectangle to an identity matrix
    model.rotate(-45.0f, 0.0f, 1.0f ,0.0f); // rotate coordinate system to aovid blocking z-axis

    // draw x,y,z coordinate axis
    shader->use();
    shader->setMatrix4f("model", model);

    shader->setBool("axisIndex", 1);
    coordinate->drawX();

    shader->setBool("axisIndex", 2);
    coordinate->drawY();

    shader->setBool("axisIndex", 3);
    coordinate->drawZ();
}

 

Coordinate.vert

#version 330 core
layout (location = 0) in vec3 aPos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main(){
    gl_Position = projection * view * model * vec4(aPos, 1.0f);
}

Coordinate.frag

#version 330 core
out vec4 FragColor;

uniform int axisIndex;

void main()
{
    if(axisIndex == 1)
    {
        FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
    }
    else if(axisIndex == 2)
    {
        FragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
    }
    else if(axisIndex == 3)
    {
        FragColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值