RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1228869
Accepted
Юрій Писанка
Юрій Писанка
Asked:2022-01-09 06:15:31 +0000 UTC2022-01-09 06:15:31 +0000 UTC 2022-01-09 06:15:31 +0000 UTC

OpenGL 3.3 C++ 帮助优化Plane类

  • 772

编写了一个类,让您无需大量代码即可快速绘制飞机。但是几十架飞机,一切都在几秒钟内冻结了一秒钟。我究竟做错了什么。

请注意,该类仅用于显示正方形,每个正方形都有自己的纹理,不适用于模型。

我将添加一点问题,如何正确绘制每个帧都是唯一的网格,因为它在 OpenGL 2.0 中仅在标准中。OpenGL 3.0

class Plane3_3
{
public:
    //Шейдер программа
    GLuint shaderProgramPlane;

    //Структура одного полигона
    struct Mesh
    {
        GLuint Texture;
        GLuint VAOparam,VBOpoints;
        int Size;
        float R,G,B,A;
    };

    //Временный масив для компиляции в VAO
    vector<GLfloat>Vertex2D;

    //Набор меша 
    std::vector<Mesh>ArrMesh;
    //Екземпляр набора для сброса в масив
    Mesh Temp;


    //Задать цвет
    void Color4f(float R,float G,float B,float A)
    {
        Temp.R = R;
        Temp.G = G;
        Temp.B = B;
        Temp.A = A;
    }

    //Задать цвет в диапазоне  - 255
    void Color4uf(float R,float G,float B,float A)
    {
        Temp.R = R/255;
        Temp.G = G/255;
        Temp.B = B/255;
        Temp.A = A/255;
    }

    //Очистить временные переменные задать текстуру изза нее и цвета не могу месш вклеить в один vao
    void Begin(GLuint Texture)
    {
        Vertex2D.clear();
        Temp.VAOparam = 0;
        Temp.VBOpoints = 0;
        Temp.Texture = Texture;
    }


    //Отрендорить (Скомпилировать) и сбросить в масив
    void End()
    {
    //Создать VAO буфер
    glGenVertexArrays(1,&Temp.VAOparam);
    //Создать VBO буфер
    glGenBuffers(1,&Temp.VBOpoints);

    //Активировать VAO Буфер
    glBindVertexArray(Temp.VBOpoints);
        //Активировать VBO Буфер и связать переменную с буфером
        glBindBuffer(GL_ARRAY_BUFFER,Temp.VBOpoints);
            //Скопировать (координаты) в VBO  ==  GL_ARRAY_BUFFER
            glBufferData(GL_ARRAY_BUFFER,sizeof(float)*Vertex2D.size(),&Vertex2D[0],GL_STREAM_DRAW); //GL_STATIC_DRAW GL_DYNAMIC_DRAW GL_STREAM_DRAW
            //Как шейдер должен распознать точку Текстурные координаты
            glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,4*sizeof(GL_FLOAT),(GLvoid*)0);
            //Активировать индекс layout
            glEnableVertexAttribArray(0);


            //Как шейдер должен распознать точку координаты
            glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,4*sizeof(GL_FLOAT),(GLvoid*)(2 * sizeof(GL_FLOAT)));
            //Активировать индекс layout
            glEnableVertexAttribArray(1);


        //деактивирую наверное VBO Буфер
        glBindBuffer(GL_ARRAY_BUFFER,0);
    //деактивирую наверное VAO буфер
    glBindVertexArray(0);

    Temp.Size = Vertex2D.size()/4;

    //Сброс в масив
    ArrMesh.push_back(Temp);
    }

    //Создать шейдер
    void CreateShader()
    {//--------------------------------
    GLuint vertexShader;
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    const GLchar* vertexShaderSourse = "#version 330 core\n"
        "layout(location=0) in vec2 TextCord;\n"
        "layout(location=1) in vec2 position;\n"
        "out vec2 TexCoords;\n"
        "void main()\n"
        "{\n"
        "TexCoords = TextCord;\n"
        "gl_Position = vec4(position.x,position.y,0,1);\n"
        "}\0";
    glShaderSource(vertexShader,1,&vertexShaderSourse,NULL);
    glCompileShader(vertexShader);

    {
        GLint success;
        GLchar infoLog[512];
        glGetShaderiv(vertexShader,GL_COMPILE_STATUS,&success);
        if(!success)
        {
            glGetShaderInfoLog(vertexShader,512,NULL,infoLog);
            std::cout<<"error vertex shader"<<std::endl<<infoLog<<std::endl;
        }
    }
    













    GLuint fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    const GLchar* fragmentShaderSourse = "#version 330 core\n"
        "out vec4 color;\n"
        "in vec2 TexCoords;\n"
        "uniform sampler2D ourTexture;\n"
        "uniform vec4 colorUS;\n"
        "void main()\n"
        "{\n"
        "color = texture(ourTexture, TexCoords)*colorUS;\n"
        "}\n"
        "\0";
    glShaderSource(fragmentShader,1,&fragmentShaderSourse,NULL);
    glCompileShader(fragmentShader);

    {
        GLint success;
        GLchar infoLog[512];
        glGetShaderiv(fragmentShader,GL_COMPILE_STATUS,&success);
        if(!success)
        {
            glGetShaderInfoLog(fragmentShader,512,NULL,infoLog);
            std::cout<<"Fragment Error"<<std::endl<<infoLog<<std::endl;
        }
    }
    


    shaderProgramPlane = glCreateProgram();
    glAttachShader(shaderProgramPlane,vertexShader);
    glAttachShader(shaderProgramPlane,fragmentShader);

    glLinkProgram(shaderProgramPlane);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    {
    GLint success;
    GLchar infoLog[512];
    glGetProgramiv(shaderProgramPlane,GL_LINK_STATUS,&success);
        if(!success)
        {
            glGetProgramInfoLog(shaderProgramPlane,512,NULL,infoLog);
            std::cout<<"error shader"<<std::endl<<infoLog<<std::endl;
        }

    }
    }//--------------------------------













    


    //Добавить точку
    void AddPoint(float tx, float ty,float x,float y)
    {
        Vertex2D.push_back(tx);
        Vertex2D.push_back(ty);

        Vertex2D.push_back(x);
        Vertex2D.push_back(y);
    }



    //Рисовать все
    void Draw()
    {
                
        //Активировать шейдер
        glUseProgram(shaderProgramPlane);

        for(int i = 0; i<ArrMesh.size();i++)
        {

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, ArrMesh[i].Texture);
        glUniform1i(glGetUniformLocation(shaderProgramPlane, "ourTexture"), 0);


        glUniform4f(glGetUniformLocation(shaderProgramPlane, "colorUS"), ArrMesh[i].R,ArrMesh[i].G,ArrMesh[i].B,ArrMesh[i].A);

        //Активировать vao
        glBindVertexArray(ArrMesh[i].VAOparam);
        //Рисовать масив
        glDrawArrays(GL_TRIANGLES,0,ArrMesh[i].Size);
        //Не понятно вроде деактивирую
        glBindVertexArray(0);

        }

    }


//Очистить все
    void Clear()
    {
        for(int i = 0; i<ArrMesh.size();i++)
        {
        glDeleteVertexArrays(1,&ArrMesh[i].VAOparam);
        glDeleteBuffers(1,&ArrMesh[i].VBOpoints);
        }
        ArrMesh.clear();
    }




    Plane3_3()
    {
        Temp.R = 1;
        Temp.G = 1;
        Temp.B = 1;
        Temp.A = 1;
    }

    ~Plane3_3()
    {
    }
};

/// 决定走另一条路。这些点是静态的,正方形只收集一次,然后使用着色器修改为所需的点。

/*
Керування через шейдер замість меша напряму (рендор мешів лагає)
Предається стандартний меш координати 1 1 
Текстурні координати 1 1
В такому випадку в шейдер ми передаємо координати меша і текстурного квадрата 
Передеємо розміри обох кубів.
*/

class Square
{
    public:
    //Шейдер программа
    GLuint shaderProgramPlane;






    //Создать шейдер
    void CreateShader()
    {//--------------------------------
    GLuint vertexShader;
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    const GLchar* vertexShaderSourse = "#version 330 core\n"
        "layout(location=0) in vec2 TextCord;\n"
        "layout(location=1) in vec2 position;\n"
        "uniform vec2 S;\n"
        "uniform vec2 P;\n"
        "out vec2 TexCoords;\n"
        "void main()\n"
        "{\n"
        "TexCoords = TextCord;\n"
        "gl_Position = vec4(position.x*S.x+P.x,position.y*S.y+P.y,0,1);\n"
        "}\0";
    glShaderSource(vertexShader,1,&vertexShaderSourse,NULL);
    glCompileShader(vertexShader);

    {
        GLint success;
        GLchar infoLog[512];
        glGetShaderiv(vertexShader,GL_COMPILE_STATUS,&success);
        if(!success)
        {
            glGetShaderInfoLog(vertexShader,512,NULL,infoLog);
            std::cout<<"error vertex shader"<<std::endl<<infoLog<<std::endl;
        }
    }
    













    GLuint fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    const GLchar* fragmentShaderSourse = "#version 330 core\n"
        "out vec4 color;\n"
        "in vec2 TexCoords;\n"
        "uniform sampler2D ourTexture;\n"
        "uniform vec4 colorUS;\n"
        "uniform int textureEnable;\n"
        "uniform vec2 Stx;\n" //Розміркуба текстурних кординат
        "uniform vec2 Ptx;\n" //Зміщення текстурних координат, через шейдер
        "void main()\n"
        "{\n"
        "vec2 TC = TexCoords;\n"
        "TC.x = TC.x * Stx.x + Ptx.x;\n"
        "TC.y = TC.y * Stx.y + Ptx.y;\n"
    //  "TexCoords.y = (TexCoords.y*Stx.y)+Ptx.y;\n"

        "if(textureEnable)\n"
        "color = texture(ourTexture, TC)*colorUS;\n"
        "else\n"
        "color = colorUS;\n"
        "}\n"
        "\0";
    glShaderSource(fragmentShader,1,&fragmentShaderSourse,NULL);
    glCompileShader(fragmentShader);

    {
        GLint success;
        GLchar infoLog[512];
        glGetShaderiv(fragmentShader,GL_COMPILE_STATUS,&success);
        if(!success)
        {
            glGetShaderInfoLog(fragmentShader,512,NULL,infoLog);
            std::cout<<"Fragment Error"<<std::endl<<infoLog<<std::endl;
        }
    }
    


    shaderProgramPlane = glCreateProgram();
    glAttachShader(shaderProgramPlane,vertexShader);
    glAttachShader(shaderProgramPlane,fragmentShader);

    glLinkProgram(shaderProgramPlane);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    {
    GLint success;
    GLchar infoLog[512];
    glGetProgramiv(shaderProgramPlane,GL_LINK_STATUS,&success);
        if(!success)
        {
            glGetProgramInfoLog(shaderProgramPlane,512,NULL,infoLog);
            std::cout<<"error shader"<<std::endl<<infoLog<<std::endl;
        }

    }
    }//--------------------------------






    GLuint VAOparam,VBOpoints;

    void Comp()
    {
    //Создать VAO буфер
    glGenVertexArrays(1,&VAOparam);
    //Создать VBO буфер
    glGenBuffers(1,&VBOpoints);

    std::vector<float> Vertex2D;


    //Point A
    //tx
    Vertex2D.push_back(0);
    //ty
    Vertex2D.push_back(0);


    //x
    Vertex2D.push_back(-0.5);
    //y
    Vertex2D.push_back(-0.5);





    //Point B

    //tx
    Vertex2D.push_back(1);
    //ty
    Vertex2D.push_back(0);

    //x
    Vertex2D.push_back(0.5);
    //y
    Vertex2D.push_back(-0.5);




    //Point C
    //tx
    Vertex2D.push_back(1);
    //ty
    Vertex2D.push_back(1);


    //x
    Vertex2D.push_back(0.5);
    //y
    Vertex2D.push_back(0.5);


    //Point C
    //tx
    Vertex2D.push_back(1);
    //ty
    Vertex2D.push_back(1);


    //x
    Vertex2D.push_back(0.5);
    //y
    Vertex2D.push_back(0.5);




        //Point A
    //tx
    Vertex2D.push_back(0);
    //ty
    Vertex2D.push_back(0);


    //x
    Vertex2D.push_back(-0.5);
    //y
    Vertex2D.push_back(-0.5);








    //Point D

    //tx
    Vertex2D.push_back(0);
    //ty
    Vertex2D.push_back(1);

    //x
    Vertex2D.push_back(-0.5);
    //y
    Vertex2D.push_back(0.5);


    //Активировать VAO Буфер
    glBindVertexArray(VBOpoints);
        //Активировать VBO Буфер и связать переменную с буфером
        glBindBuffer(GL_ARRAY_BUFFER,VBOpoints);
            //Скопировать (координаты) в VBO  ==  GL_ARRAY_BUFFER
            glBufferData(GL_ARRAY_BUFFER,sizeof(float)*Vertex2D.size(),&Vertex2D[0],GL_STATIC_DRAW); //GL_STATIC_DRAW GL_DYNAMIC_DRAW GL_STREAM_DRAW
            //Как шейдер должен распознать точку Текстурные координаты
            glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,4*sizeof(GL_FLOAT),(GLvoid*)0);
            //Активировать индекс layout
            glEnableVertexAttribArray(0);


            //Как шейдер должен распознать точку координаты
            glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,4*sizeof(GL_FLOAT),(GLvoid*)(2 * sizeof(GL_FLOAT)));
            //Активировать индекс layout
            glEnableVertexAttribArray(1);


        //деактивирую наверное VBO Буфер
        glBindBuffer(GL_ARRAY_BUFFER,0);
    //деактивирую наверное VAO буфер
    glBindVertexArray(0);
    }
    
    //Розмір і позиція куба
    float SX,SY,X,Y;


    void SetSizeAndPos(float sx,float sy,float x,float y)
    {
        SX = sx;
        SY = sy;
        X = x;
        Y = y;
    }

    bool TextureEnable;
    void SetTextureEnable(bool Enable)
    {
        TextureEnable = Enable;
    }

    //Розмір і позиця текстури
    float txSX,txSY,txX,txY;
    void SetTxSizeAndPos(float sx,float sy,float x,float y)
    {
        txSX = sx;
        txSY = sy;
        txX = x;
        txY = y;
    }


    void Draw(GLuint Texture,float R,float G,float B,float A)
    {
                
        //Активировать шейдер
        glUseProgram(shaderProgramPlane);

        if(TextureEnable)
        {
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, Texture);
            glUniform1i(glGetUniformLocation(shaderProgramPlane, "ourTexture"), 0);
        }

        glUniform1i(glGetUniformLocation(shaderProgramPlane, "textureEnable"), TextureEnable);


        glUniform4f(glGetUniformLocation(shaderProgramPlane, "colorUS"), R/255,G/255,B/255,A/255);


        glUniform2f(glGetUniformLocation(shaderProgramPlane, "S"), SX,SY);
        glUniform2f(glGetUniformLocation(shaderProgramPlane, "P"), X,Y);

        glUniform2f(glGetUniformLocation(shaderProgramPlane, "Stx"), txSX,txSY);
        glUniform2f(glGetUniformLocation(shaderProgramPlane, "Ptx"), txX,txY);
        //glUniform1f(glGetUniformLocation(shaderProgramPlane, "sx"), SX);
        //glUniform1f(glGetUniformLocation(shaderProgramPlane, "sy"), SY);

        //Активировать vao
        glBindVertexArray(VAOparam);
        //Рисовать масив
        glDrawArrays(GL_TRIANGLES,0,6);
        //Не понятно вроде деактивирую
        glBindVertexArray(0);

        
    }


    Square()
    {
    }

    ~Square()
    {
    }
};

//Функція малює квадрат по координатам Ця функція для 2.0 стандарту але користувач може вказати свою
void UserOpenGL3_3_DrawPlane(bool TextureEnable,GLuint TextureID,double x1,double y1,double tx1,double ty1,double x2,double y2,double tx2,double ty2,double x3,double y3,double tx3,double ty3,double x4,double y4,double tx4,double ty4,double R,double G,double B,double A)
{
    Square1.SetSizeAndPos(x2-x1,y4-y1,(x1+x2+x3+x4)/4,(y1+y2+y3+y4)/4);
    Square1.SetTxSizeAndPos(tx2-tx1,ty4-ty1,tx1,ty1);
    Square1.SetTextureEnable(TextureEnable);
    Square1.Draw(TextureID,R,G,B,A);
}
c++
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Никита Самоуков
    2022-01-12T22:52:27Z2022-01-12T22:52:27Z
    glBindVertexArray(VAOparam);  
    glUseProgram(shaderProgramPlane); 
    glUniformXXX
    glGetUniformLocation
    

    这些东西速度不快,也不应该每方都做,否则就挂一百了。

    您需要设置一次参数,然后绘制很多对象。

    每一帧都会改变的网格可以这样绘制:

    struct DDLineData
    {
        vec3 pos;
        vec4 color;
    };
    vector<DDLineData> dd_lines;
    

    每一帧:

    _shader_color.Use();
    _shader_color.projection = proj;
    _shader_color.view = view;
    
    unsigned int VBO, VAO;
    if (!_to_render.GetRBuf().dd_lines.empty())
    {
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
        glBindVertexArray(VAO);
    
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, _to_render.GetRBuf().dd_lines.size() * sizeof(DDLineData), _to_render.GetRBuf().dd_lines.data(), GL_STATIC_DRAW);
    
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(DDLineData), (void*)offsetof(DDLineData, pos));
        glEnableVertexAttribArray(0);
    
        glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(DDLineData), (void*)offsetof(DDLineData, color));
        glEnableVertexAttribArray(1);
    
        glDrawArrays(GL_LINES, 0, _to_render.GetRBuf().dd_lines.size());
        // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
    }
    

    По идее нужен DYNAMIC_DRAW но серавно эта штука у меня только для отладки.

    Для шейдера я использую https://gitlab.com/nikitasamoukov/codegenshaders и обращения к _shader_color, это по факту вызовы glUseProgram и glUniformXXX.

    vec3 из glm.

    • 0

相关问题

  • 编译器和模板处理

  • 指针。找到最小数量

  • C++,关于枚举类对象初始化的问题

  • 函数中的二维数组

  • 无法使用默认构造函数创建类对象

  • C++ 和循环依赖

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5