質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.36%

VAO VBOは複数あってもいいのかどうか?

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 723
退会済みユーザー

退会済みユーザー

DrawGprah関数部のコメント部のコードですが毎フレームvao vbo を生成して消す処理と
Spriteクラスのインスタンスごとにvao vbo を生成する処理は正しいのでしょうか?

提示コードは画像を表示させるクラスです。

#include "../Header/Sprite.hpp"
#include "../Header/Shader.hpp"
#include "../Header/Game.hpp"
#include "../Header/Texture.hpp"
#include "../Header/VertexData.hpp"

// 数学ライブラリ
#include "glm/ext.hpp"
#include "glm/glm.hpp"

// OpenCV 
#include <opencv2/core.hpp>

class Game;
/*################################################################################################################
* 画像 描画クラス
################################################################################################################*/

//コンストラクタ
/*
* Game クラス
* テクスチャ パス
* 描画する画像の寸法
*/

Sprite::Sprite(class Game* g, const char* FileName) : Transform_2D(g)
{
    shader = new Shader(g,"Shader/2D/Sprite.vert", "Shader/2D/Sprite.frag");
    Owner = g;//Gameクラス

    Transform_2D::setTransfrom(glm::vec2(1,1),0,glm::vec2(0,0));    //トランスフォームを初期化

    //テクスチャを設定     
    glGenTextures(1, &TextureID);
    glBindTexture(GL_TEXTURE_2D, TextureID);

    int width = 0, height = 0;    //画像の寸法
    int channels = 0;            //画像のチャンネル数

    std::shared_ptr<byte[]> data = LoadTexture(FileName, width, height, channels);    //テクスチャを取得


    mPicSize.x = width;
    mPicSize.y = height;

    //printf("widht: %f\n", width);
    //printf("height: %f\n", height);

    if (data.get() != NULL) 
    {
        if (channels == 3)
        {
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)width, (GLsizei)height, 0, GL_RGB, GL_UNSIGNED_BYTE, data.get());
        }
        else if (channels == 4)
        {
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.get());
        }
    }
    else {
        std::cerr << "Unable to load texture: " << FileName << std::endl;
    }



//    mSize = end - start;    //画像のサイズを取得

//    printf("width: %.2f\n", mSize.x);
//    printf("height: %.2f\n",mSize.y);

    /*
    vertex[0] = VertexAttribute_2D{ -width / 2.0f,height / 2.0f,    0,0 };
    vertex[1] = VertexAttribute_2D{ -width / 2.0f,-height / 2.0f,    0,1 };
    vertex[2] = VertexAttribute_2D{ width / 2.0f,-height / 2.0f,    1,1 };

    vertex[3] = VertexAttribute_2D{ -width / 2.0f,height / 2.0f,    0,0 };
    vertex[4] = VertexAttribute_2D{ width / 2.0f,-height / 2.0f,    1,1 };
    vertex[5] = VertexAttribute_2D{ width / 2.0f,height / 2.0f,    1,0 };
    */


    /*
    * 
    // 頂点情報を設定
    vertex[0] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f,    start.x * uvWidth,start.y * uvHeight };
    vertex[1] = VertexAttribute_2D{ -mSize.x / 2.0f,-mSize.y / 2.0f,    start.x * uvWidth,end.y * uvHeight };
    vertex[2] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f,    end.x * uvWidth,end.y * uvHeight };

    vertex[3] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f,    start.x * uvWidth,start.y * uvHeight };
    vertex[4] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f,    end.x * uvWidth,end.y * uvHeight };
    vertex[5] = VertexAttribute_2D{ mSize.x / 2.0f,mSize.y / 2.0f,        end.x * uvWidth,start.y * uvHeight };

    */


    //VAO
//    glGenVertexArrays(1, &VAO);
//    glBindVertexArray(VAO);

    //VBO
//    glGenBuffers(1, &VBO);
//    glBindBuffer(GL_ARRAY_BUFFER, VBO);
//    glBufferData(GL_ARRAY_BUFFER, (sizeof(vertex) / sizeof(vertex[0])) * sizeof(VertexAttribute_2D), vertex, GL_STATIC_DRAW);

    //頂点座標
//    glEnableVertexAttribArray(0);
//    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexAttribute_2D), NULL);

    //UV座標
//    glEnableVertexAttribArray(1);
//    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexAttribute_2D), (void*)(sizeof(float) * 2));

    //ミニマップを設定
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glGenerateMipmap(GL_TEXTURE_2D);

    //異方性フィルタリングを設定
    GLfloat largest;
    glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest);


    glDeleteBuffers(1, &VAO);
    glDeleteVertexArrays(1, &VAO);

    glBindVertexArray(0);
    glBindTexture(GL_TEXTURE_2D, 0);


//    delete data;
//    data = nullptr;

}

//描画
void Sprite::DrawGraph(glm::vec2 pos, glm::vec2 start, glm::vec2 end)
{


    Transform_2D::UpdateTransform();        //トランスフォームを更新
    Transform_2D::setTransform_Move(pos);    //移動

    shader->Enable();    //シェーダーを有効にする
    shader->SetFloatUniform_3m("uViewMatrix", getViewMatrix());
    shader->SetFloatUniform_3m("uWorldMatrix", getWorldMatrix());


    glm::vec2 mSize;    
    mSize = end - start;    //画像のサイズを取得
//    printf("mSize.x  %f\n", mSize.x);
//`    printf("start.x. x%f\n", end.x);




    // 頂点情報を設定
    vertex[0] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f,        start.x / mPicSize.x   ,start.y / mPicSize.y };

//    printf("%f\n", start.y / mSize.y);

    vertex[1] = VertexAttribute_2D{ -mSize.x / 2.0f,-mSize.y / 2.0f,    start.x / mPicSize.x   ,end.y / mPicSize.y };
    vertex[2] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f,        end.x / mPicSize.x     ,end.y / mPicSize.y };

    vertex[3] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f,        start.x / mPicSize.x  ,start.y / mPicSize.y };
    vertex[4] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f,        end.x / mPicSize.x    ,end.y / mPicSize.y };
    vertex[5] = VertexAttribute_2D{ mSize.x / 2.0f,mSize.y / 2.0f,        end.x / mPicSize.x    ,start.y / mPicSize.y };

////////////////////////////////////////////////////////////////////////////////////////////

    //VAO
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    //VBO
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(vertex) / sizeof(vertex[0])) * sizeof(VertexAttribute_2D), vertex, GL_STATIC_DRAW);
///////////////////////////////////////////////////////////////////////////////////////////
    //頂点座標
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexAttribute_2D), NULL);

    //UV座標
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexAttribute_2D), (void*)(sizeof(float) * 2));


    glBindVertexArray(VAO);
    glBindTexture(GL_TEXTURE_2D, TextureID);
    glDrawArrays(GL_TRIANGLES, 0, (GLsizei)std::size(vertex));    

    // バッファを解放
    glDeleteBuffers(1,&VAO);
    glDeleteVertexArrays(1,&VAO);

    //glBindVertexArray(0);
//    glBindTexture(GL_TEXTURE_2D, 0);

}



// 画像サイズを取得
glm::vec2 Sprite::getSize()
{
    return mPicSize;
}



// デストラクタ
Sprite::Sprite(const Sprite & sp) : Transform_2D(sp.Owner)
{
    shader = new Shader(sp.Owner, "Shader/2D/Sprite.vert", "Shader/2D/Sprite.frag");
    Owner = sp.Owner;//Gameクラス
    mPicSize.x = sp.mPicSize.x;
    mPicSize.y = sp.mPicSize.y;


}


// デストラクタ
Sprite::~Sprite()
{
//    printf("Sprite delete\n");



    delete shader;
    shader = nullptr;
    glDeleteTextures(1,&TextureID);

}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • y_waiwai

    2021/01/29 10:04

    なにをするコードなんでしょうか

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2021/01/29 10:06

    スプライト描画クラスです。

    キャンセル

  • fana

    2021/01/29 11:26

    > スプライト描画クラスです。

    とだけ言われても,何をするのかわからんのですが…
    画像の任意の部分矩形領域を表示する手段 みたいなものなのでしょうか?
    そうであれば,DrawGraph()の引数の意味は,
    ・pos : 矩形を表示する場所を指定(矩形の中心の位置か)
    ・start, end : 画像のどこらへんを矩形に張り付けるのか,という領域を指定(大元の画像のpixel座標で指定する)
    という話で合ってますか?

    キャンセル

  • 退会済みユーザー

    2021/01/29 11:27

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 1

checkベストアンサー

0

どんな形がベストなのかわかりませんが,
Sprite::DrawGraph()を実施するたびに【VAOやVBOを作って→使って→すぐ捨てる】というのは効率が悪そうに思います.

Sprite::DrawGraph()の引数によって
頂点座標とテクスチャ座標がちょっと変わるだけなのであれば,例えば
その変換のための uniform変数を用意して,そいつだけを更新する形にすれば良いのではないかと.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/01/29 11:38

    あと,Spriteのコンストラクタに

    glDeleteBuffers(1, &VAO);
    glDeleteVertexArrays(1, &VAO);

    とかありますが,必要な処理なんでしょうか?(やっても問題ないのか?)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る