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

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

新規登録して質問してみよう
ただいま回答率
85.35%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1475閲覧

頂点情報のUV座標を更新する方法 glBuffersubData();関数の使い方が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/05/21 08:45

編集2021/05/23 08:51

提示コードのコメント部の 頂点属性のUVデータを更新のコード部ですが毎フレーム頂点情報のUV座標を更新して反映させたいのですがglBufferSubData();関数の使い方が知りたいです。

確認したこと
「 UV座標の指定を確認するためコンストラクタ部にUV指定のコードを入れましたが座標は適切でした。 」
「glBuffersubData();関数でエラーコード0x502 が発生しているためこの関数が原因です。"現在のステートで無効な操作をしている場合、もしくは廃止された関数を呼び出した場合(*1)"」

利用ライブラリ
glew
glfw
freetype
opengl
glmライブラリ

Github: https://github.com/Shigurechan/OpenGL_FrameWork/tree/6c59a4560a5cb4c042f557264d9ab3f9e034d7dc

提示画像の右上のキャラクター
イメージ説明
参考サイト: https://www.it-swarm-ja.com/ja/opengl/opengl%E9%A0%82%E7%82%B9%E3%83%90%E3%83%83%E3%83%95%E3%82%A1%E3%83%BC%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B%E9%81%A9%E5%88%87%E3%81%AA%E6%96%B9%E6%B3%95%E3%81%AF%E4%BD%95%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F/1072569757/

参考サイト: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferSubData.xhtml
参考サイト: https://qiita.com/uechoco@github/items/08e401761bddd17b4c3f

cpp

1#include "Sprite.hpp" 2 3#include <iostream> 4#include <fstream> 5 6#include <glm/glm.hpp> 7#include <glm/gtc/matrix_Transform.hpp> 8#include <glm/gtx/Transform.hpp> 9 10#include "Texture.hpp" 11#include "Shader.hpp" 12#include "Window.hpp" 13#include <stb/stb_image.h> 14 15 16//コンストラクタ 17FrameWork::Sprite::Sprite(std::shared_ptr<Window> w,const char* vert,const char* frag) : Transform_2D(),Shader() 18{ 19 windowContext = w; //ウインドウコンテキスト 20 21 22 //シェーダー読み込み 23 24 if (vert == NULL && frag == NULL) 25 { 26 vert = "Shader/2D/BasicTexture_2D.vert"; 27 frag = "Shader/2D/BasicTexture_2D.frag"; 28 LoadShader(vert, frag); //シェーダーロード 29 30 isDefaultShader = true; 31 } 32 else 33 { 34 LoadShader(vert, frag); 35 36 isDefaultShader = false; 37 38 } 39 40 41 42 43 44 //テクスチャ関係 45 textureID = std::vector<TextureData>(0); //テクスチャーデータ 46 textureUnitCount = 0; //テクスチャユニット数をカウント 47 48 49 //vao 50 glGenVertexArrays(1, &vao); 51 glBindVertexArray(vao); 52 53 //vbo 54 glGenBuffers(1, &vbo); 55 glBindBuffer(GL_ARRAY_BUFFER, vbo); 56 57 //頂点 58 GLint attrib = getAttribLocation("vertexPosition"); 59 glEnableVertexAttribArray(attrib); 60 glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(VertexUV), rectangleVertex, GL_STATIC_DRAW); 61 glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0); 62 setBindAttribVertex("vertexPosition"); 63 64 //UV 65 attrib = getAttribLocation("vertexUV"); 66 glEnableVertexAttribArray(attrib); 67 glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(VertexUV), rectangleVertex, GL_STATIC_DRAW); 68 glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(sizeof(GLfloat) * 2)); 69 setBindAttribVertex("vertexUV"); 70 71 72 //アルファブレンド有効 73 glEnable(GL_BLEND); 74 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 75} 76 77 78// ######################################## メンバ関数 ######################################## 79 80//テクスチャ設定 81void FrameWork::Sprite::setTexture(TextureData tex) 82{ 83 84 textureID.push_back(tex); //テクスチャーIDに追加 85 86 87 glGenTextures(1, &textureID.back().ID); //テクスチャIDの生成 88 89 //バインド 90 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 91 glBindTexture(GL_TEXTURE_2D, textureID.back().ID); 92 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureID.back().size.x, textureID.back().size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureID.back().fileData); 93 94 // テクスチャの補間設定 95 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 96 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 97 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 100 101 textureID.back().textureUnitNumber = GL_TEXTURE0 + (unsigned short int)textureUnitCount; 102 assert(textureID.back().textureUnitNumber < GL_TEXTURE31);//エラー表示 103 104 textureUnitCount++; //テクスチャーユニットカウントに加算 105} 106 107//描画するアクティブなテクスチャに指定 108void FrameWork::Sprite::setDrawTextureID(unsigned char id) 109{ 110 //assert(id < textureID.size()); 111 glActiveTexture(textureID.at(id).textureUnitNumber); 112} 113 114//描画 115void FrameWork::Sprite::DrawGraph(glm::vec2 pos, unsigned char texNum,float r,glm::vec2 s,glm::vec2 startSize,glm::vec2 endSize) 116{ 117 if (isDefaultShader == true) 118 { 119 setEnable(); 120 } 121 122 glBindVertexArray(vao); 123 124 125 setDrawTextureID((unsigned char)texNum); //テクチャーユニットを設定 126 127 // ####################### 頂点属性のUVデータを更新 ####################### 128 129 130 //UVサイズからピクセルサイズを算出 131 const float sizeX = 1.0f / (float)textureID.at(texNum).size.x; 132 const float sizeY = 1.0f / (float)textureID.at(texNum).size.y; 133 134 //std::cout << textureID.at(texNum).size.x << std::endl; 135 //std::cout << textureID.at(texNum).size.y << std::endl; 136 137 138 //std::cout<< sizeX << std::endl; 139 //左上 140 rectangleVertex[0].uv[0] = sizeX * startSize.x; 141 rectangleVertex[0].uv[1] = 1.0f - (sizeY * startSize.y); 142 143 //左下 144 rectangleVertex[1].uv[0] = sizeX * startSize.x; 145 rectangleVertex[1].uv[1] = 1.0f - (sizeY * ((endSize.y - startSize.y) + startSize.y)); 146 rectangleVertex[4].uv[0] = sizeX * startSize.x; 147 rectangleVertex[4].uv[1] = 1.0f - (sizeY * ((endSize.y - startSize.y) + startSize.y)); 148 149 //右上 150 rectangleVertex[2].uv[0] = (sizeX * endSize.x); 151 rectangleVertex[2].uv[1] = 1.0f - (sizeY * startSize.y); 152 rectangleVertex[3].uv[0] = (sizeX * endSize.x); 153 rectangleVertex[3].uv[1] = 1.0f - (sizeY * startSize.y); 154 155 //右下 156 rectangleVertex[5].uv[0] = sizeX * endSize.x; 157 rectangleVertex[5].uv[1] = 1.0f - (sizeY * ((endSize.y - startSize.y) + startSize.y)); 158 159 160 //glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VertexUV) * 6, rectangleVertex); 161 162 163 // ################################################### 164 165 166 167 //std::cout << windowContext->getSize().x << std::endl; 168 169 //Transform 170 setSizeScale(glm::vec2(std::abs((endSize.x - startSize.x)), (std::abs(endSize.y - startSize.y)))); //サイズ 171 setScale(s); //スケール 172 setRotate(r); //回転 173 setTranslate(glm::vec3(pos.x + (getSizeScale().x / 2.0f), pos.y + (getSizeScale().y / 2.0f), 0.0f)); //平行移動 174 175 176 177 //uniform 178 setUniformMatrix4fv("uTranslate", translate); 179 setUniformMatrix4fv("uRotate", rotate); 180 setUniformMatrix4fv("uScale", scale); 181 setUniformMatrix4fv("uViewProjection", glm::ortho(0.0f, windowContext->getSize().x, windowContext->getSize().y, 0.0f, -1.0f, 1.0f)); 182 183 184 185 //バインド&描画 186 glBindTexture(GL_TEXTURE_2D, textureID.at(texNum).ID); 187 glDrawArrays(GL_TRIANGLES, 0, 6); 188 189 190 191 //バインドを解除 192 glBindVertexArray(0); 193 glBindTexture(GL_TEXTURE_2D, 0); 194 if (isDefaultShader == true) 195 { 196 setDisable(); 197 } 198 199 200} 201 202 203//デストラクタ 204FrameWork::Sprite::~Sprite() 205{ 206 207 //std::cout << "デストラクタ" << std::endl; 208 209 //テクスチャーIDを開放 210 for (int i = 0; i < textureID.size(); i++) 211 { 212 glDeleteTextures(1,&textureID.at(i).ID); 213 214 stbi_image_free(textureID.at(i).fileData); 215 textureID.at(i).fileData = NULL; 216 217 218 219 } 220 221 glDeleteVertexArrays(1, &vao); 222 glDeleteBuffers(1, &vbo); 223 224} 225 226

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/05/21 09:17

startSize, endSize, sizeX, sizeYにはどのような数値が入っていて、 uvには現状、何が設定されているのでしょうか。
退会済みユーザー

退会済みユーザー

2021/05/21 09:19

CELL 48 でsizeXは96 sizeY 48です。表示して確認しましたが値が正常に入っています。
退会済みユーザー

退会済みユーザー

2021/05/21 09:31

繰り返しになりますが、uvに現状、何が設定されているのでしょうか。
退会済みユーザー

退会済みユーザー

2021/05/21 09:40 編集

勘違いでした、削除いたします。
退会済みユーザー

退会済みユーザー

2021/05/22 08:02 編集

最小のコードで、UV座標を指定して画像を表示するコードは書けますか? 追記 テキストやコインを削除して動かしても同様の結果でしょうか。
退会済みユーザー

退会済みユーザー

2021/05/23 03:52

テキストやコインを消しても同じ結果でした。
退会済みユーザー

退会済みユーザー

2021/05/23 04:05

//UVサイズからピクセルサイズを算出 const float sizeX = 1.0f / (float)96; const float sizeY = 1.0f / (float)48; glm::vec2 startSize = glm::vec2(48, 0); glm::vec2 endSize = glm::vec2(48 * 2, 48); //std::cout<< sizeX << std::endl; //左上 rectangleVertex[0].uv[0] = sizeX * startSize.x; rectangleVertex[0].uv[1] = 1.0f - (sizeY * startSize.y); //左下 rectangleVertex[1].uv[0] = sizeX * startSize.x; rectangleVertex[1].uv[1] = 1.0f - (sizeY * ((endSize.y - startSize.y) + startSize.y)); rectangleVertex[4].uv[0] = sizeX * startSize.x; rectangleVertex[4].uv[1] = 1.0f - (sizeY * ((endSize.y - startSize.y) + startSize.y)); //右上 rectangleVertex[2].uv[0] = (sizeX * endSize.x); rectangleVertex[2].uv[1] = 1.0f - (sizeY * startSize.y); rectangleVertex[3].uv[0] = (sizeX * endSize.x); rectangleVertex[3].uv[1] = 1.0f - (sizeY * startSize.y); //右下 rectangleVertex[5].uv[0] = sizeX * endSize.x; rectangleVertex[5].uv[1] = 1.0f - (sizeY * ((endSize.y - startSize.y) + startSize.y)); コンストラクタ部でこのようにコードを書いて実行しましたが画像が片方だけ表示されました。 つまりglbufferSubDataが悪いということなのですが使い方が知りたいです。
退会済みユーザー

退会済みユーザー

2021/05/23 05:27 編集

画像だけだとテキストとコインしか対象以外がわからなかったので、あのように書きましたが、 「glBufferData」や「glBufferSubData」を使っているものを上記画像1枚にした場合でも再現しますか? できれば、再現可能な最小のコードを用意してもらいたいですが。
退会済みユーザー

退会済みユーザー

2021/05/23 05:30

提示コードを修正しました。コンストラクタ部でUV座標を設定したら正しく表示されたのでUV座標は問題ありません。またglGetError関数にて0x502のエラーが表示されているためやはりglBufferSubData関数の使い方が間違えているものの思います。
退会済みユーザー

退会済みユーザー

2021/05/23 05:51

再現可能な最小のコードを用意してもらいたいですが。 間違えている箇所の予想はできますが、あなたの提示するコードは余計な箇所が多すぎるため、 予想の検証や問題の指摘は難しいです。
退会済みユーザー

退会済みユーザー

2021/05/23 05:57

githubを載せましたので確認お願い出来ますでしょうか? 依存関係はglew glfw opengl freetypeです。
退会済みユーザー

退会済みユーザー

2021/05/23 06:22

あなたの作った「OpenGL_Framework」では、余計なコードが多いですし、 問題を再現するコードも含まれてませんよね。 だから、再現可能な最小のコードを用意してください。 > githubを載せましたので確認お願い出来ますでしょうか? せめて導入手順ぐらい記載しませんか? > #include <glew/include/GL/glew.h> このような一般的ではない指定になっているので、 それらライブラリの一般的な導入手順では動かないです。 代理デバッグするつもりはないので、「OpenGL_Framework」自体を動かそうなんて思いませんが。
退会済みユーザー

退会済みユーザー

2021/05/24 09:03

> テキストやコインを消しても同じ結果でした。 消せばちゃんと動きましたよ。
guest

回答1

0

ベストアンサー

「glBufferSubData()」はバインドされているバッファに対して更新を行います。

投稿2021/05/24 09:02

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/05/26 01:59

なるほど。glBindBuffer(GL_ARRAY_BUFFER, vbo);を描画部に追加してglBufferData(GL_ARRAY_BUFFER, 6 * sizeof(VertexUV), rectangleVertex, GL_DYNAMIC_DRAW); としたのですが0X501というエラーが発生しますこれはなぜでしょうか? [ 呼んだ関数の引数の値が無効な値もしくは範囲外の場合 ]
退会済みユーザー

退会済みユーザー

2021/05/26 04:32

どの関数で発生したエラーですか
退会済みユーザー

退会済みユーザー

2021/05/26 05:09

治りました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問