圆环的绘制和贴图
绘制 贴图 圆环
2023-09-11 14:21:26 时间
1.数据绑定
glGenVertexArrays(1,vao);
glBindVertexArray(vao[0]);
glGenBuffers(4,vbo);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ARRAY_BUFFER,vbo[0]);
glBufferData(GL_ARRAY_BUFFER,pvalues.size()*4,&pvalues[0],GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,vbo[1]);
glBufferData(GL_ARRAY_BUFFER,tvalues.size()*4,&tvalues[0],GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,vbo[2]);
glBufferData(GL_ARRAY_BUFFER,nvalues.size()*4,&nvalues[0],GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,ebo);
glBufferData(GL_ARRAY_BUFFER,ind.size()*4,&ind[0],GL_STATIC_DRAW);
glBindVertexArray(0);
2.纹理贴图
int width,height,nrChannels;
glGenTextures(1, &texture);
unsigned char *data1=stbi_load("brick1.jpg",&width,&height,&nrChannels,0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data1);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(data1);
3.绘制模型
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glDrawElements(GL_TRIANGLES, myTorus.getNumIndices(), GL_UNSIGNED_INT, 0);
4.圆环的创建代码
定义一个圆环
#ifndef TORUS_H
#define TORUS_H
#include <gl\gl.h> // OpenGL32库的头文件
#include <gl\glext.h>
#include <GL\glm\glm.hpp> //GLM 是OpenGL推荐的数学库
#include <GL\glm\gtc\type_ptr.hpp>
#include <vector>
class Torus
{
public:
Torus();
Torus(float innerRadius, float outerRadius, int prec);
virtual ~Torus();
int getNumVertices();
int getNumIndices();
std::vector<int> getIndices();
std::vector<glm::vec3> getVertices();
std::vector<glm::vec2> getTexCoords();
std::vector<glm::vec3> getNormals();
std::vector<glm::vec3> getStangents();
std::vector<glm::vec3> getTtangents();
float locx,locy,locz,rotateangle;
protected:
private:
int numVertices;
int numIndices;
int prec;
float inner;
float outer;
std::vector<int> indices;
std::vector<glm::vec3> vertices;
std::vector<glm::vec2> texCoords;
std::vector<glm::vec3> normals;
std::vector<glm::vec3> sTangents;
std::vector<glm::vec3> tTangents;
void init();
float toRadians(float degrees);
};
#endif // TORUS_H
#include "Torus.h"
Torus::Torus()
{
prec=48;
inner=0.5f;
outer=0.2f;
init();
}
Torus::Torus(float innerRadius, float outerRadius, int precIn)
{
prec=precIn;
inner=innerRadius;
outer=outerRadius;
init();
}
Torus::~Torus()
{
//dtor
}
float Torus::toRadians(float degrees)
{
return (degrees*2.0f*3.1415926f)/360.0f;
}
void Torus::init()
{
numVertices=(prec+1)*(prec+1);
numIndices=prec*prec*6;
for(int i=0;i<numVertices;i++){vertices.push_back(glm::vec3());}
for(int i=0;i<numVertices;i++){texCoords.push_back(glm::vec2());}
for(int i=0;i<numVertices;i++){normals.push_back(glm::vec3());}
for(int i=0;i<numVertices;i++){sTangents.push_back(glm::vec3());}
for(int i=0;i<numVertices;i++){tTangents.push_back(glm::vec3());}
for(int i=0;i<numIndices;i++){indices.push_back(0);}
//First Torus
for(int i=0;i<prec+1;i++)
{
float amt=toRadians(i*360.0f/prec);
//单位矩阵,旋转amt角度,绕z轴逆时针
glm::mat4 rMat=glm::rotate(glm::mat4(1.0f),amt,glm::vec3(0.0f,0.0f,1.0f));
//旋转后的点乘以圆的半径
glm::vec3 initPos(rMat*glm::vec4(outer,0.0f,0.0f,1.0f));
//得到圆环第一个圆上的第i个点
vertices[i]=glm::vec3(initPos+glm::vec3(inner,0.0f,0.0f));
texCoords[i]=glm::vec2(0.0f,((float)i/(float)prec));
rMat=glm::rotate(glm::mat4(1.0f),amt,glm::vec3(0.0f,0.0f,1.0f));
tTangents[i]=glm::vec3(rMat*glm::vec4(0.0f,-1.0f,0.0f,1.0f));
sTangents[i]=glm::vec3(glm::vec3(0.0f,0.0f,-1.0f));
normals[i]=glm::cross(tTangents[i],sTangents[i]);
}
//Next Torus
for(int ring=1;ring<prec+1;ring++)
{
for(int i=0;i<prec+1;i++)
{
float amt=(float)(toRadians(ring*360.0f/prec));
glm::mat4 rMat=glm::rotate(glm::mat4(1.0f),amt,glm::vec3(0.0f,1.0f,0.0f));
vertices[ring*(prec+1)+i]=glm::vec3(rMat*glm::vec4(vertices[i],1.0f));
texCoords[ring*(prec+1)+i]=glm::vec2((float)ring*2.0f/(float)prec,texCoords[i].t);
if(texCoords[ring*(prec+1)+i].s>1.0)
{
texCoords[ring*(prec+1)+i].s-=1.0f;
}
rMat=glm::rotate(glm::mat4(1.0f),amt,glm::vec3(0.0f,1.0f,0.0f));
sTangents[ring*(prec+1)+i]=glm::vec3(rMat*glm::vec4(sTangents[i],1.0f));
rMat=glm::rotate(glm::mat4(1.0f),amt,glm::vec3(0.0f,1.0f,0.0f));
tTangents[ring*(prec+1)+i]=glm::vec3(rMat*glm::vec4(tTangents[i],1.0f));
rMat=glm::rotate(glm::mat4(1.0f),amt,glm::vec3(0.0f,1.0f,0.0f));
normals[ring*(prec+1)+i]=glm::vec3(rMat*glm::vec4(normals[i],1.0f));
}
}
//Triangle index
for(int ring=0;ring<prec;ring++)
{
for(int vert=0;vert<prec;vert++)
{
indices[((ring*prec+vert)*2)*3+0]=ring*(prec+1)+vert;
indices[((ring*prec+vert)*2)*3+1]=ring*(prec+1)+vert+1;
indices[((ring*prec+vert)*2)*3+2]=(ring+1)*(prec+1)+vert;
indices[((ring*prec+vert)*2+1)*3+0]=ring*(prec+1)+vert+1;
indices[((ring*prec+vert)*2+1)*3+1]=(ring+1)*(prec+1)+vert;
indices[((ring*prec+vert)*2+1)*3+2]=(ring+1)*(prec+1)+vert+1;
}
}
}
int Torus::getNumVertices(){ return numVertices;}
int Torus::getNumIndices(){return numIndices;}
std::vector<int> Torus::getIndices(){return indices;}
std::vector<glm::vec3> Torus::getVertices(){return vertices;}
std::vector<glm::vec2> Torus::getTexCoords(){return texCoords;}
std::vector<glm::vec3> Torus::getNormals(){return normals;}
std::vector<glm::vec3> Torus::getStangents(){return sTangents;}
std::vector<glm::vec3> Torus::getTtangents(){return tTangents;}
引用一个圆环
实例化:
Torus mytorus(0.8f,0.2f,48);
初始化时:
mytorus.locx=0.0f;mytorus.locy=0.0f;mytorus.locz=0.0f;
加载时:
std::vector<int> ind=mytorus.getIndices();
std::vector<glm::vec3> vert =mytorus.getVertices();
std::vector<glm::vec2> tex=mytorus.getTexCoords();
std::vector<glm::vec3> norm=mytorus.getNormals();
std::vector<float> pvalues;
std::vector<float> tvalues;
std::vector<float> nvalues;
int numVertices=mytorus.getNumVertices();
for(int i=0;i<numVertices;i++)
{
pvalues.push_back(vert[i].x);
pvalues.push_back(vert[i].y);
pvalues.push_back(vert[i].z);
tvalues.push_back(tex[i].s);
tvalues.push_back(tex[i].t);
nvalues.push_back(norm[i].x);
nvalues.push_back(norm[i].y);
nvalues.push_back(norm[i].z);
}
glGenVertexArrays(1,vao);
glBindVertexArray(vao[0]);
glGenBuffers(4,vbo);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ARRAY_BUFFER,vbo[0]);
glBufferData(GL_ARRAY_BUFFER,pvalues.size()*4,&pvalues[0],GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,vbo[1]);
glBufferData(GL_ARRAY_BUFFER,tvalues.size()*4,&tvalues[0],GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,vbo[2]);
glBufferData(GL_ARRAY_BUFFER,nvalues.size()*4,&nvalues[0],GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,ebo);
glBufferData(GL_ARRAY_BUFFER,ind.size()*4,&ind[0],GL_STATIC_DRAW);
glBindVertexArray(0);
绘图时:
mytorus.rotateangle += 0.01f;
最后是效果贴图:
最后贴张图,看下文件结构。给大家参考。
相关文章
- 带着canvas去流浪系列之三 绘制饼图
- 绘制文字
- Python 使用turtle模块绘制统计柱状图
- 【STM32F429】第13章 ThreadX GUIX窗口任意位置绘制2D图形
- CRM WebUI的错误消息是如何从后台服务器取出并绘制到前台的
- atitit..代码生成流程图 流程图绘制解决方案 java c#.net php v2
- 一个详尽的面向 SAP UI5 初学者的教程 - 如何在 SAP UI5 中绘制图表 Chart
- Skia深入分析3——skia图片绘制的实现(2)
- MATLAB | 如何绘制高斯混合分布分类区域及边界
- 小学生蓝桥杯Python闯关 | 绘制半圆+三角形
- 166:vue+openlayers 绘制椭圆形
- cesium: 绘制矩形(010)
- 手机指北针 + Python绘制徒步路线图
- OpenGL之三角形绘制(十三)