螺旋管的做法和上一节的圆柱非常类似,就是在大圆径每转过一定角度时,将y值加上一定值。另个其纹理坐标生成的方法也和上一节一致。我做出的效果如下

其渲染器实现如下

#ifndef LUOXUANGUANRENDER_H
#define LUOXUANGUANRENDER_H#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QOpenGLExtraFunctions>
#define PI 3.14159265f
class LuoxuanGuanRender
{
public:LuoxuanGuanRender() = default;void initsize(float rBig,float rSmall,float h,float nCirclef,int nCol,int nRow,QImage &img);void initsize(float rBig,float rSmall,float h,float nCirclef,int nCol,int nRow);void render(QOpenGLExtraFunctions *f,QMatrix4x4 &pMatrix,QMatrix4x4 &vMatrix,QMatrix4x4 &mMatrix);private:QOpenGLShaderProgram program_;QOpenGLBuffer vbo_;QVector<GLfloat> vertPoints_,textPoints_;QOpenGLTexture *texture_{nullptr};bool userTexture_ = false;
};#endif // LUOXUANGUANRENDER_H
#include "luoxuanguanrender.h"void LuoxuanGuanRender::initsize(float rBig, float rSmall, float h, float nCirclef, int nCol, int nRow, QImage &img)
{userTexture_ = true;program_.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex,"vsrc.vert");program_.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment,"fsrc.frag");program_.link();float angdegTotal=nCirclef*360.0f;//大圆周总度数float angdegColSpan=360.0f/nCol;//小圆周每份的角度跨度float angdegRowSpan=angdegTotal/nRow;//大圆周每份的角度跨度float A=(rBig-rSmall)/2;//用于旋转的小圆半径float D=rSmall+A;//旋转轨迹形成的大圆周半径QVector<GLfloat> originVertPoints,originTextPoints;for(float angdegCol=0;::ceil(angdegCol)<360+angdegColSpan;angdegCol+=angdegColSpan){double a=angdegCol * PI / 180;//当前小圆弧度float t=angdegCol/360;//当前角度对应的t坐标for(float angdegRow=0;::ceil(angdegRow)<angdegTotal+angdegRowSpan;angdegRow+=angdegRowSpan)//重复了一列顶点,方便了索引的计算{float yVec=(angdegRow/angdegTotal)*h;//根据旋转角度增加y的值double u=angdegRow * PI /180;//当前大圆周弧度float y=A*::cos(a);float x=(D+A*::sin(a))*::sin(u);float z=(D+A*::sin(a))*::cos(u);//将计算出来的XYZ坐标加入存放顶点坐标的ArrayListoriginVertPoints << x << y + yVec << z;float s=angdegRow/360;//当前角度对应的s坐标originTextPoints << s << t;}}for(int i=0;i<nCol-1;i++){//按照卷绕成三角形的需要for(int j=0;j<nRow;j++){//生成顶点编号列表int index=i*(nRow+1)+j;//当前四边形第一顶点编号vertPoints_ << originVertPoints.at((index+1)*3 + 0); //第一个三角形三个顶点的编号入列表vertPoints_ << originVertPoints.at((index+1)*3 + 1);vertPoints_ << originVertPoints.at((index+1)*3 + 2);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 0);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 1);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 2);vertPoints_ << originVertPoints.at((index+nRow+2)*3 + 0);vertPoints_ << originVertPoints.at((index+nRow+2)*3 + 1);vertPoints_ << originVertPoints.at((index+nRow+2)*3 + 2);textPoints_ << originTextPoints.at((index +1)*2 + 0); //第一个三角形颜色textPoints_ << originTextPoints.at((index +1)*2 + 1);textPoints_ << originTextPoints.at((index +1)*2 + 2);textPoints_ << originTextPoints.at((index +1)*2 + 3);textPoints_ << originTextPoints.at((index+nRow+1)*2 + 0);textPoints_ << originTextPoints.at((index+nRow+1)*2 + 1);textPoints_ << originTextPoints.at((index+nRow+1)*2 + 2);textPoints_ << originTextPoints.at((index+nRow+1)*2 + 3);textPoints_ << originTextPoints.at((index+nRow+2)*2 + 0);textPoints_ << originTextPoints.at((index+nRow+2)*2 + 1);textPoints_ << originTextPoints.at((index+nRow+2)*2 + 2);textPoints_ << originTextPoints.at((index+nRow+2)*2 + 3);vertPoints_ << originVertPoints.at((index+1)*3 + 0); //第二个三角形三个顶点的编号入列表vertPoints_ << originVertPoints.at((index+1)*3 + 1);vertPoints_ << originVertPoints.at((index+1)*3 + 2);vertPoints_ << originVertPoints.at(index*3 + 0);vertPoints_ << originVertPoints.at(index*3 + 1);vertPoints_ << originVertPoints.at(index*3 + 2);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 0);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 1);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 2);textPoints_ << originTextPoints.at((index+1)*2 + 0); //第二个三角形纹理坐标textPoints_ << originTextPoints.at((index+1)*2 + 1);textPoints_ << originTextPoints.at((index+1)*2 + 2);textPoints_ << originTextPoints.at((index+1)*2 + 3);textPoints_ << originTextPoints.at(index*2 + 0);textPoints_ << originTextPoints.at(index*2 + 1);textPoints_ << originTextPoints.at(index*2 + 2);textPoints_ << originTextPoints.at(index*2 + 3);textPoints_ << originTextPoints.at((index+nRow+1)*2 + 0);textPoints_ << originTextPoints.at((index+nRow+1)*2 + 1);textPoints_ << originTextPoints.at((index+nRow+1)*2 + 2);textPoints_ << originTextPoints.at((index+nRow+1)*2 + 3);}}QVector<GLfloat> vboVec;vboVec << vertPoints_ << textPoints_;vbo_.create();vbo_.bind();vbo_.allocate(vboVec.data(),vboVec.count() * sizeof(GLfloat));texture_ = new QOpenGLTexture(img);texture_->setWrapMode(QOpenGLTexture::ClampToEdge);texture_->setMinMagFilters(QOpenGLTexture::NearestMipMapNearest,QOpenGLTexture::LinearMipMapNearest);
}void LuoxuanGuanRender::initsize(float rBig, float rSmall, float h, float nCirclef, int nCol, int nRow)
{userTexture_ = false;program_.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex,"lvsrc.vert");program_.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment,"lfsrc.frag");program_.link();float angdegTotal=nCirclef*360.0f;//总度数float angdegColSpan=360.0f/nCol;float angdegRowSpan=angdegTotal/nRow;float A=(rBig-rSmall)/2;//用于旋转的小圆半径float D=rSmall+A;//旋转轨迹形成的大圆周半径QVector<GLfloat> originVertPoints,originColorPoints;for(float angdegCol=0;::ceil(angdegCol)<360+angdegColSpan;angdegCol+=angdegColSpan){double a=angdegCol * PI / 180;//当前小圆弧度for(float angdegRow=0;::ceil(angdegRow)<angdegTotal+angdegRowSpan;angdegRow+=angdegRowSpan)//重复了一列顶点,方便了索引的计算{float yVec=(angdegRow/angdegTotal)*h;//根据旋转角度增加y的值double u=angdegRow * PI /180;//当前大圆周弧度float y=A*::cos(a);float x=(D+A*::sin(a))*::sin(u);float z=(D+A*::sin(a))*::cos(u);//将计算出来的XYZ坐标加入存放顶点坐标的ArrayListoriginVertPoints << x << y + yVec << z;originColorPoints << 1.0 << 1.0 << 1.0 << 1.0;}}for(int i=0;i<nCol;i++){//按照卷绕成三角形的需要for(int j=0;j<nRow;j++){//生成顶点编号列表int index=i*(nRow+1)+j;//当前四边形第一顶点编号vertPoints_ << originVertPoints.at((index+1)*3 + 0); //第一个三角形三个顶点的编号入列表vertPoints_ << originVertPoints.at((index+1)*3 + 1);vertPoints_ << originVertPoints.at((index+1)*3 + 2);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 0);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 1);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 2);vertPoints_ << originVertPoints.at((index+nRow+2)*3 + 0);vertPoints_ << originVertPoints.at((index+nRow+2)*3 + 1);vertPoints_ << originVertPoints.at((index+nRow+2)*3 + 2);textPoints_ << originColorPoints.at((index +1)*2 + 0); //第一个三角形颜色textPoints_ << originColorPoints.at((index +1)*2 + 1);textPoints_ << originColorPoints.at((index +1)*2 + 2);textPoints_ << originColorPoints.at((index +1)*2 + 3);textPoints_ << originColorPoints.at((index+nRow+1)*2 + 0);textPoints_ << originColorPoints.at((index+nRow+1)*2 + 1);textPoints_ << originColorPoints.at((index+nRow+1)*2 + 2);textPoints_ << originColorPoints.at((index+nRow+1)*2 + 3);textPoints_ << originColorPoints.at((index+nRow+2)*2 + 0);textPoints_ << originColorPoints.at((index+nRow+2)*2 + 1);textPoints_ << originColorPoints.at((index+nRow+2)*2 + 2);textPoints_ << originColorPoints.at((index+nRow+2)*2 + 3);vertPoints_ << originVertPoints.at((index+1)*3 + 0); //第二个三角形三个顶点的编号入列表vertPoints_ << originVertPoints.at((index+1)*3 + 1);vertPoints_ << originVertPoints.at((index+1)*3 + 2);vertPoints_ << originVertPoints.at(index*3 + 0);vertPoints_ << originVertPoints.at(index*3 + 1);vertPoints_ << originVertPoints.at(index*3 + 2);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 0);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 1);vertPoints_ << originVertPoints.at((index+nRow+1)*3 + 2);textPoints_ << originColorPoints.at((index+1)*2 + 0); //第二个三角形纹理坐标textPoints_ << originColorPoints.at((index+1)*2 + 1);textPoints_ << originColorPoints.at((index+1)*2 + 2);textPoints_ << originColorPoints.at((index+1)*2 + 3);textPoints_ << originColorPoints.at(index*2 + 0);textPoints_ << originColorPoints.at(index*2 + 1);textPoints_ << originColorPoints.at(index*2 + 2);textPoints_ << originColorPoints.at(index*2 + 3);textPoints_ << originColorPoints.at((index+nRow+1)*2 + 0);textPoints_ << originColorPoints.at((index+nRow+1)*2 + 1);textPoints_ << originColorPoints.at((index+nRow+1)*2 + 2);textPoints_ << originColorPoints.at((index+nRow+1)*2 + 3);}}QVector<GLfloat> vboVec;vboVec << vertPoints_ << textPoints_;vbo_.create();vbo_.bind();vbo_.allocate(vboVec.data(),vboVec.count() * sizeof(GLfloat));
}void LuoxuanGuanRender::render(QOpenGLExtraFunctions *f, QMatrix4x4 &pMatrix, QMatrix4x4 &vMatrix, QMatrix4x4 &mMatrix)
{f->glEnable(GL_DEPTH_TEST);f->glEnable(GL_CULL_FACE);program_.bind();vbo_.bind();if(userTexture_){f->glActiveTexture(GL_TEXTURE0);program_.setUniformValue("uPMatrix",pMatrix);program_.setUniformValue("uVMatrix",vMatrix);program_.setUniformValue("uMMatrix",mMatrix);program_.setUniformValue("sTexture",0);program_.enableAttributeArray(0);program_.enableAttributeArray(1);program_.setAttributeBuffer(0,GL_FLOAT,0,3,3*sizeof(GLfloat));program_.setAttributeBuffer(1,GL_FLOAT,vertPoints_.count() * sizeof(GLfloat),2,2*sizeof(GLfloat));texture_->bind();f->glDrawArrays(GL_TRIANGLES,0,vertPoints_.count() / 3);program_.disableAttributeArray(0);program_.disableAttributeArray(1);texture_->release();}else{program_.setUniformValue("uPMatrix",pMatrix);program_.setUniformValue("uVMatrix",vMatrix);program_.setUniformValue("uMMatrix",mMatrix);program_.enableAttributeArray(0);program_.enableAttributeArray(1);program_.setAttributeBuffer(0,GL_FLOAT,0,3,3*sizeof(GLfloat));program_.setAttributeBuffer(1,GL_FLOAT,vertPoints_.count() * sizeof(GLfloat),4,4*sizeof(GLfloat));f->glDrawArrays(GL_LINES,0,vertPoints_.count() / 3);program_.disableAttributeArray(0);program_.disableAttributeArray(1);}vbo_.release();program_.release();f->glDisable(GL_CULL_FACE);f->glDisable(GL_DEPTH_TEST);
}

其shader实现如下,带图片纹理

#version 330
uniform mat4 uPMatrix,uVMatrix,uMMatrix;
layout (location = 0)in vec3 aPosition;
layout (location = 1)in vec2 aTexture;
smooth out vec2 vTexture;void main(void)
{gl_Position = uPMatrix * uVMatrix * uMMatrix * vec4(aPosition,1);vTexture = aTexture;
}
#version 330
uniform sampler2D sTexture;
in vec2 vTexture;
out vec4 fragColor;void main(void)
{fragColor = texture2D(sTexture,vTexture);
}

不带纹理

#version 330
uniform mat4 uPMatrix,uVMatrix,uMMatrix;
layout (location = 0)in vec3 aPosition;
layout (location = 1)in vec4 aColor;
smooth out vec4 vColor;void main(void)
{gl_Position = uPMatrix * uVMatrix * uMMatrix * vec4(aPosition,1);vColor = aColor;
}
#version 330
in vec4 vColor;
out vec4 fragColor;void main(void)
{fragColor = vColor;
}

其使用方法和上一节一样,只是参数传递有一些不一样而已

#ifndef WIDGET_H
#define WIDGET_H#include <QOpenGLWidget>
#include <QTimer>
#include "luoxuanguanrender.h"
class Widget : public QOpenGLWidget
{Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();protected:void initializeGL() override;void resizeGL(int w, int h) override;void paintGL() override;private:QTimer tm_;LuoxuanGuanRender render_;QMatrix4x4 pMatrix_;QVector3D camera_;qreal angleX_ = 0,angleY_ = 0,angleZ_ = 0;private slots:void slotTimeout();
};#endif // WIDGET_H
#include "widget.h"Widget::Widget(QWidget *parent): QOpenGLWidget(parent)
{connect(&tm_,SIGNAL(timeout()),this,SLOT(slotTimeout()));tm_.start(60);
}Widget::~Widget()
{}void Widget::initializeGL()
{
//    render_.initsize(1.8,1.0,7,3.3,10,80,QImage("texture.png"));render_.initsize(1.8,1.0,7,3.3,10,80);camera_.setX(0);camera_.setY(0);camera_.setZ(10);
}void Widget::resizeGL(int w, int h)
{pMatrix_.setToIdentity();pMatrix_.perspective(45,float(w)/h,0.01f,100.0f);
}void Widget::paintGL()
{QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();f->glClearColor(0.0f,0.0f,0.0f,0.0f);f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);QMatrix4x4 vMatrix;vMatrix.lookAt(camera_,QVector3D(0.0,0.0,0.0),QVector3D(0.0,1.0,0.0));QMatrix4x4 mMatrix;
//    mMatrix.rotate(angleX_,1,0,0);mMatrix.translate(0,-3.2,0);mMatrix.rotate(angleY_,0,1,0);
//    mMatrix.rotate(angleZ_,0,0,1);render_.render(f,pMatrix_,vMatrix,mMatrix);
}void Widget::slotTimeout()
{angleX_ += 5;angleY_ += 5;angleZ_ += 5;update();
}

到此结束

qt opengl 3d基本形状-螺旋管相关推荐

  1. qt opengl 3d基本形状-圆柱

    圆柱的顶面和底面都是一个圆形,其顶点坐标为(R*cos(弧度),y,R*sin(弧度))其中R分别为圆柱高的峰值,比如正放于中心时y就是h/2或者-h/2,h/2表示顶面,-h/2表示底面.其纹理坐标 ...

  2. qt opengl 3d基本形状圆锥

    圆锥与上一节的圆柱很相似,其侧面的顶点坐标同样拆分成很多个小三角形,顶点位于一点,底面顶点和圆柱计算底面顶点的方法一样,都是(r*cos(弧度),-h/2,r*sin(弧度));底面顶点纹理坐标的计算 ...

  3. Qt+OpenGL——3D坐标转2D坐标

    原理介绍:https://learnopengl-cn.github.io/01%20Getting%20started/08%20Coordinate%20Systems/ 代码实现 为了获取模型中 ...

  4. QT实现绘制3D基本形状

    QT实现绘制3D基本形状 一项目简介 二项目技术 三项目展示 主要源码片段解析 获取完整项目源码传送门 一项目简介 显示Qt 3D提供的四个基本形状,并为每个形状设置一个网格. 基本形状显示了Qt 3 ...

  5. 【Qt OpenGL】Qt Creator中的3D绘图及动画教程

    Qt Creator中的3D绘图及动画教程(参照NeHe) 刚刚学习了Qt Creator,发现Qt提供了QtOpenGL模块,对OpenGL做了不错的封装,这使得我们可以很轻松地在Qt程序中使用Op ...

  6. OpenGL(十八)——Qt OpenGL绘制一个3D世界

    OpenGL(十八)--Qt OpenGL绘制一个3D世界 一.说明 本篇介绍构建一个3D的世界. 二.简介 加载3D世界,并在其中漫游: 在这一课中,你将学会如何加载3D世界,并在3D世界中漫游. ...

  7. Qt实现3D纹理渲染自由旋转空间立方体

    昨天七夕,关于七夕美好的爱情传说源自于浩瀚银河星空,又碰巧最近在学习QtOpenGL实现三维纹理防体重建,突发奇想用Qt实现一个立方体星空模型,并且能随着鼠标操作实现空间自由旋转 核心思想是用到Qt ...

  8. OpenGL(十四)——Qt OpenGL纹理

    OpenGL(十四)--Qt OpenGL纹理 一.纹理 终于写到纹理的部分了: 纹理(Texture)的本质是一个2D图片(1D和3D),或者叫图形数据.只是在OpenGL中专业术语中称其为纹理. ...

  9. 【QT项目:视频播放器——Qt opengl编程】通过shader完成显示yuv

    通过Qt opengl不是为了3D绘制,而是为了将视频绘制起来 使用opengl 可以极大降低yuv转rgb的转换开销 使用Opengl需要考虑三大问题: 1.QOpenGLWidget(与界面如何交 ...

最新文章

  1. 如何将代码优雅的放在WORD文档中?
  2. linux服务器间文件夹拷贝
  3. [CCO 2019] Sirtet(差分约束+最短路)
  4. SaltStack匹配target-第六篇
  5. 二次优化问题dfp_MATLAB优化问题应用实例讲解
  6. 源文件与模块文件生成时的文件不同,仍要调试器使用它吗
  7. 中国双面泡棉胶带市场趋势报告、技术动态创新及市场预测
  8. 使用frida获取微信EnMicroMsg.db 数据库密码
  9. java语言介绍及特点分析(萌新入门须知内容)
  10. php判断是否是浏览器请求,php 判断请求是否来自“手机浏览器”
  11. 如何用计算机测量图片景深,用手机也能测景深 DOF Master景深测量软件
  12. VisualBasic程序设计第二章的学习与自测
  13. java图形用户界面基础
  14. 二维码制作方法有哪些?教你简单的二维码制作方法
  15. FUSE引起的SIGBUS问题分析报告
  16. C#实现物体尺寸测量(利用坐标转换)
  17. linux系统中加密文件传输助手,Linux 下的安卓文件传输助手!
  18. 电子凸轮核心-曲线规划
  19. windows 8 英库输入法
  20. 图像标注平台搭建之cvat

热门文章

  1. 双引擎强悍!QQ电脑管家4.6 Beta1实测
  2. 妻子,情人,红颜知己
  3. Windows程序意外挂掉,但显存依然被占用
  4. 关于亚健康(KK记)
  5. 1.产品/数据产品设计
  6. IRP结构体之Flag成员
  7. 电脑怎样文字转语音?给文字配音的方法其实有很多种
  8. 基于JavaSpringBoot+Vue+uniapp实现微信小程序新闻资讯平台
  9. shell 中匹配正则 字符串处理【整理版】
  10. ubuntu16.04,解决桌面右键菜单失效问题!