zl程序教程

您现在的位置是:首页 >  其它

当前栏目

圆环的绘制和贴图

绘制 贴图 圆环
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;

最后是效果贴图:

最后贴张图,看下文件结构。给大家参考。