pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

使用默認構造函數調用的網格類不起作用 OpenGL

Mesh class called with default constructor not working OpenGL C++(使用默認構造函數調用的網格類不起作用 OpenGL C++)
本文介紹了使用默認構造函數調用的網格類不起作用 OpenGL C++的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我為 OpenGL 3.3 創建了一個 Mesh 類,當我使用非默認構造函數創建類時,當我創建對象時創建頂點時,它可以正常工作.
但是,我現在想要通過將它們放入向量中來動態創建多個對象,因此我必須添加一個默認構造函數,我使用與其他構造函數相同的函數來設置緩沖區數據......但是它不起作用.據我所知,不是因為它在向量中,而是與構造函數有關,或者與稍后創建緩沖區數據的事實有關.我真的不太確定.

I created a Mesh class for OpenGL 3.3, it works fine when I create the class with a non-default constructor, when I create the vertices when I create the object.
However, I now want to have multiple objects that I can create dynamically by putting them in a vector, so I had to add in a default constructor I use the same functions for setting up the buffer data as with the other constructor... but it doesn't work. It's as far as I can tell not because of the fact it's in the vector but it's something to do with the constructor or something with the fact the buffer data is created later. I'm really not quite sure.

這是我的課程.(當我創建一個有效的網格時,我調用帶參數的構造函數,當它不起作用時,我構建一個沒有參數的網格并調用changeMes??h"函數)

Here are my classes. ( When I create a mesh that works I call the constructor with parameters and when it doesn't work I construct a mesh with no parameters and call the "changeMesh" function)

mesh.h

#ifndef MESH_H
#define MESH_H

#include <iostream>
#include <vector>
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

class mesh
{
    public:
        mesh();
        mesh(std::vector<GLfloat> vertices, std::vector<GLuint> triangles, GLuint shaderProgram);
        ~mesh();
        void changeMesh(std::vector<GLfloat> vertices, std::vector<GLuint> triangles, GLuint shaderProgram);
        void render();
        void Translate(glm::vec3 addVector);
        void Rotate(glm::vec3 rotVector, GLfloat angle);
    protected:
    private:
        GLuint vertexArrayObject, vertexBuffer, elementBuffer, shaderProgram;
        std::vector<GLfloat> vertices;
        std::vector<GLuint> indices;
        glm::mat4 transform;
        void setUpMesh();
        void bindVertices();
};

#endif // MESH_H

mesh.cpp

    #include "../include/mesh.h"

mesh::mesh(std::vector<GLfloat> vertices, std::vector<GLuint> indices, GLuint shaderProgram)
{
    this->shaderProgram = shaderProgram;
    this->vertices = vertices;
    this->indices = indices;
    setUpMesh();
}

mesh::mesh(){
    glGenVertexArrays(1, &vertexArrayObject);
    glBindVertexArray(vertexArrayObject);

    glGenBuffers(1, &vertexBuffer);
    glGenBuffers(1, &elementBuffer);
}

mesh::~mesh()
{
    glDeleteBuffers(1, &elementBuffer);
    glDeleteBuffers(1, &vertexBuffer);

    glDeleteVertexArrays(1, &vertexArrayObject);
}

void mesh::changeMesh(std::vector<GLfloat> vertices, std::vector<GLuint> triangles, GLuint shaderProgram){
    this->shaderProgram = shaderProgram;
    this->vertices = vertices;
    this->indices = indices;
    bindVertices();

}

void mesh::setUpMesh(){
    glGenVertexArrays(1, &vertexArrayObject);
    glBindVertexArray(vertexArrayObject);

    glGenBuffers(1, &vertexBuffer);
    glGenBuffers(1, &elementBuffer);

    bindVertices();
    glBindVertexArray(0);

}

void mesh::bindVertices(){
    glBindVertexArray(vertexArrayObject);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(GLfloat), this->vertices.data(), GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), this->indices.data(), GL_STATIC_DRAW);


    GLint amountDataPerVert = 5;

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, amountDataPerVert*sizeof(GLfloat), 0);

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, amountDataPerVert*sizeof(GLfloat), (void*)(3*sizeof(GLfloat)));


    glBindVertexArray(0);

}
void mesh::render(){
    glBindVertexArray(vertexArrayObject);
    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "transform"), 1, GL_FALSE, glm::value_ptr(transform));

    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

void mesh::Translate(glm::vec3 addVector){
    transform = glm::translate(transform, addVector);
}

void mesh::Rotate(glm::vec3 rotVector, GLfloat angle){
    transform = glm::rotate(transform, glm::radians(angle), rotVector);
}

推薦答案

雖然您認為問題與將對象存儲在向量中無關,但我有一種強烈的感覺,它可能會發生.您在 C++ 包裝器中封裝 OpenGL 對象的方式是一種痛苦的方法,您可能會像之前的許多人一樣發現.

While you believe that the problem has nothing to do with storing the objects in a vector, I have a strong feeling that it probably does. The way you are encapsulating OpenGL objects in C++ wrappers is a recipe for pain, and you're probably finding out like many did before you.

典型的問題是由復制和銷毀對象時發生的組合引起的.C++包裝器擁有的OpenGL對象在析構函數中被刪除:

The typical problems are caused by the combination of what happens when objects are copied and destructed. The OpenGL objects owned by the C++ wrapper are deleted in the destructor:

mesh::~mesh()
{
    glDeleteBuffers(1, &elementBuffer);
    glDeleteBuffers(1, &vertexBuffer);

    glDeleteVertexArrays(1, &vertexArrayObject);
}

為了說明這個問題,讓我們看一個典型的序列.假設您有一個網格對象向量,以及一種向該向量添加新網格的方法(注釋點以供以后參考):

To illustrate the problem with this, let's look at a typical sequence. Let's say you have a vector of mesh objects, and a method to add a new mesh to this vector (points annotated for later reference):

std::vector<mesh> m_meshes;

void createMesh(...) {
    mesh newMesh;  // point 1
    newMesh.changeMesh(...);
    m_meshes.push_back(newMesh);  // point 2
}  // point 3

看起來無害?根本不是.這里發生了不好的事情:

Looks harmless? It's not at all. Bad things happened here:

  • 第 1 點:創建了新對象.構造函數創建 OpenGL 對象,并將它們的名稱存儲在成員變量中.
  • 第 2 點:將網格對象的副本添加到向量中,其中使用默認復制構造函數創建副本.這意味著將復制包含 OpenGL 對象名稱的成員變量.
  • 第 3 點:網格對象超出范圍.調用析構函數,刪除 OpenGL 對象.
  • Point 1: New object is created. The constructor creates the OpenGL objects, and stores their names in member variables.
  • Point 2: A copy of the mesh object is added to the vector, where the copy is created with the default copy constructor. This means that the member variables, which contain the OpenGL object names, are copied.
  • Point 3: The mesh object goes out of scope. The destructor is invoked, which deletes the OpenGL objects.

畢竟你擁有的是一個存儲在向量中的網格對象,OpenGL 對象名稱存儲在其成員變量中,而實際的 OpenGL 對象已被刪除.這意味著存儲在此網格對象中的對象名稱現在無效.

What you have after all of this is a mesh object stored in the vector, with OpenGL object names stored in its member variables, while the actual OpenGL objects have been deleted. This means that the object names stored in this mesh object are now invalid.

根本問題是您的類沒有正確的復制構造函數和賦值運算符.不幸的是,在成員變量中存儲 OpenGL 對象名稱,以及在構造函數/析構函數中生成/刪除對象名稱時,實現它們并不容易.

The root problem is that your class does not have proper copy constructors and assignment operators. And unfortunately, it is not easily possible to implement them when storing OpenGL object names in member variables, and generating/deleting the object names in constructor/destructor.

有很多方法可以解決這個問題.它們都不是完美的:

There are a number of ways to handle this. None of them are perfectly pretty:

  1. 不要在構造函數/析構函數中生成/刪除 OpenGL 對象.相反,使用您顯式調用的某種形式的 init()/cleanup() 方法.缺點是您必須小心正確地調用這些方法.例如,如果您有一個對象向量,并且想要刪除該向量,則必須手動對向量的所有成員調用 cleanup().

  1. Do not generate/delete the OpenGL objects in constructor/destructor. Instead, use some form of init()/cleanup() methods that you invoke explicitly. The downside is that you have to be careful to invoke these methods correctly. For example, if you have a vector of objects, and want to delete the vector, you have to invoke cleanup() on all members of the vector manually.

總是用指針來引用對象.使用網格對象指針向量代替網格對象向量.這樣,對象就不會被復制.您還必須小心正確地管理對象的生命周期,而不是泄漏它們.如果您使用某種形式的智能指針而不是裸指針,這是最簡單的.

Always reference the objects with pointers. Instead of having a vector of mesh objects, use a vector of mesh object pointers. This way, the objects are not copied. You also have to be careful to manage the lifetime of the objects correctly, and not leak them. This is easiest if you use some form of smart pointer instead of naked pointers.

使用某種形式的混合,您仍然使用實際的 C++ 對象,但它們將底層 OpenGL 對象的名稱存儲在引用計數的嵌套對象中.這樣,他們就可以實現正確的復制/分配語義.

Use some form of hybrid, where you still use actual C++ objects, but they store the names of the underlying OpenGL objects in a nested object that is reference counted. This way, they can implement proper copy/assign semantics.

我認為最簡單、最干凈的方法是使用智能指針的選項 2.較新版本的 C++ 在標準庫中具有智能指針,因此您無需實現任何內容.例如,在 C++11 中,您可以使用類型 std::shared_ptr 來引用您的網格對象.上面的代碼片段將如下所示:

I think the easiest and cleanest approach is option 2 with using smart pointers. Newer versions of C++ have smart pointers in the standard library, so there isn't anything you need to implement. For example in C++11, you can use the type std::shared_ptr<mesh> to reference your mesh objects. The code fragment above would then look like this:

std::vector<std::shared_ptr<mesh> > m_meshes;

void createMesh(...) {
    std::shared_ptr<mesh> newMesh = std::make_shared<mesh>();
    newMesh->changeMesh(...);
    m_meshes.push_back(newMesh);
}

為了確保無論如何都不會意外復制對象,為類聲明未實現的(私有)復制構造函數和賦值運算符也是一個好主意.本主題解釋了如何在 C++11 中做到最好:在 C++11 中使用顯式刪除的成員函數,是否仍然值得從不可復制的基類繼承?.

To be sure that you don't accidentally copy the objects anyway, it's also a good idea to declare unimplemented (private) copy constructors and assignment operators for the class. This topic explains how to do that best in C++11: With explicitly deleted member functions in C++11, is it still worthwhile to inherit from a noncopyable base class?.

這篇關于使用默認構造函數調用的網格類不起作用 OpenGL C++的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

How can I read and manipulate CSV file data in C++?(如何在 C++ 中讀取和操作 CSV 文件數據?)
In C++ why can#39;t I write a for() loop like this: for( int i = 1, double i2 = 0; (在 C++ 中,為什么我不能像這樣編寫 for() 循環: for( int i = 1, double i2 = 0;)
How does OpenMP handle nested loops?(OpenMP 如何處理嵌套循環?)
Reusing thread in loop c++(在循環 C++ 中重用線程)
Precise thread sleep needed. Max 1ms error(需要精確的線程睡眠.最大 1ms 誤差)
Is there ever a need for a quot;do {...} while ( )quot; loop?(是否需要“do {...} while ()?環形?)
主站蜘蛛池模板: 岛津二手液相色谱仪,岛津10A液相,安捷伦二手液相,安捷伦1100液相-杭州森尼欧科学仪器有限公司 | 飞歌臭氧发生器厂家_水处理臭氧发生器_十大臭氧消毒机品牌 | EDLC超级法拉电容器_LIC锂离子超级电容_超级电容模组_软包单体电容电池_轴向薄膜电力电容器_深圳佳名兴电容有限公司_JMX专注中高端品牌电容生产厂家 | 政府回应:200块在义乌小巷能买到爱情吗?——揭秘打工族省钱约会的生存智慧 | GAST/BRIWATEC/CINCINNATI/KARL-KLEIN/ZIEHL-ABEGG风机|亚喜科技 | NBA直播_NBA直播免费观看直播在线_NBA直播免费高清无插件在线观看-24直播网 | ETFE膜结构_PTFE膜结构_空间钢结构_膜结构_张拉膜_浙江萬豪空间结构集团有限公司 | 主题班会网 - 安全教育主题班会,各类主题班会PPT模板 | 苹果售后维修点查询,苹果iPhone授权售后维修服务中心 – 修果网 拼装地板,悬浮地板厂家,悬浮式拼装运动地板-石家庄博超地板科技有限公司 | jrs高清nba(无插件)直播-jrs直播低调看直播-jrs直播nba-jrs直播 上海地磅秤|电子地上衡|防爆地磅_上海地磅秤厂家–越衡称重 | 交变/复合盐雾试验箱-高低温冲击试验箱_安奈设备产品供应杭州/江苏南京/安徽马鞍山合肥等全国各地 | 氢氧化钙设备, 氢氧化钙生产线-淄博惠琛工贸有限公司 | DWS物流设备_扫码称重量方一体机_快递包裹分拣机_广东高臻智能装备有限公司 | 对辊式破碎机-对辊制砂机-双辊-双齿辊破碎机-巩义市裕顺机械制造有限公司 | 不锈钢散热器,冷却翅片管散热器厂家-无锡市烨晟化工装备科技有限公司 | 档案密集柜_手动密集柜_智能密集柜_内蒙古档案密集柜-盛隆柜业内蒙古密集柜直销中心 | 对照品_中药对照品_标准品_对照药材_「格利普」高纯中药标准品厂家-成都格利普生物科技有限公司 澳门精准正版免费大全,2025新澳门全年免费,新澳天天开奖免费资料大全最新,新澳2025今晚开奖资料,新澳马今天最快最新图库 | 长信科技产业园官网_西安厂房_陕西标准工业厂房 | Trimos测长机_测高仪_TESA_mahr,WYLER水平仪,PWB对刀仪-德瑞华测量技术(苏州)有限公司 | 大通天成企业资质代办_承装修试电力设施许可证_增值电信业务经营许可证_无人机运营合格证_广播电视节目制作许可证 | 水质监测站_水质在线分析仪_水质自动监测系统_多参数水质在线监测仪_水质传感器-山东万象环境科技有限公司 | 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | 哈尔滨治「失眠/抑郁/焦虑症/精神心理」专科医院排行榜-京科脑康免费咨询 一对一诊疗 | 河南mpp电力管_mpp电力管生产厂家_mpp电力电缆保护管价格 - 河南晨翀实业 | 电杆荷载挠度测试仪-电杆荷载位移-管桩测试仪-北京绿野创能机电设备有限公司 | 超高频感应加热设备_高频感应电源厂家_CCD视觉检测设备_振动盘视觉检测设备_深圳雨滴科技-深圳市雨滴科技有限公司 | 湖南长沙商标注册专利申请,长沙公司注册代理记账首选美创! | 液压升降平台_剪叉式液压/导轨式升降机_传菜机定做「宁波日腾升降机厂家」 | 高温热泵烘干机,高温烘干热泵,热水设备机组_正旭热泵 | 氢氧化钾厂家直销批发-济南金昊化工有限公司 | 艾默生变频器,艾默生ct,变频器,ct驱动器,广州艾默生变频器,供水专用变频器,风机变频器,电梯变频器,艾默生变频器代理-广州市盟雄贸易有限公司官方网站-艾默生变频器应用解决方案服务商 | 伺服电机维修、驱动器维修「安川|三菱|松下」伺服维修公司-深圳华创益 | 广东机电安装工程_中央空调工程_东莞装饰装修-广东粤标建设有限公司 | 洗地机_全自动洗地机_手推式洗地机【上海滢皓环保】 | 锂电叉车,电动叉车_厂家-山东博峻智能科技有限公司 | 等离子表面处理机-等离子表面活化机-真空等离子清洗机-深圳市东信高科自动化设备有限公司 | 玉米深加工机械,玉米加工设备,玉米加工机械等玉米深加工设备制造商-河南成立粮油机械有限公司 | 压力喷雾干燥机,喷雾干燥设备,柱塞隔膜泵-无锡市闻华干燥设备有限公司 | 合肥废气治理设备_安徽除尘设备_工业废气处理设备厂家-盈凯环保 合肥防火门窗/隔断_合肥防火卷帘门厂家_安徽耐火窗_良万消防设备有限公司 | BOE画框屏-触摸一体机-触控查询一体机-触摸屏一体机价格-厂家直销-触发电子 | 抓斗式清污机|螺杆式|卷扬式启闭机|底轴驱动钢坝|污水处理闸门-方源水利机械 |