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

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

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

携帯電話のような組込み機器のためにデザインされたOpenGLのサブセットです。

Q&A

解決済

2回答

5354閲覧

OpenGL ESで長方形を描画すると「GL_INVALID_OPERATION: Operation illegal in current state」が発生します

fumiasi

総合スコア12

OpenGL ES

携帯電話のような組込み機器のためにデザインされたOpenGLのサブセットです。

0グッド

0クリップ

投稿2017/05/13 15:59

###前提・実現したいこと
Unityで外部プラグインを作成してOpenGL ESで長方形(FillRect)を描画しようとしたところ、
「GL_INVALID_OPERATION: Operation illegal in current state」が発生し、
何も描画されない状態になってしまいます。

どこか根本的に間違っている部分や設定漏れがあるのではと考えておりますが、
数日間、原因を調査しても解決しなかったので、皆様のお力をお借りできればと思います。
お手数ですが、何卒宜しくお願い致します。

###ソースコード

c++

1// 頂点シェーダー 2#define VERTEX_C_SRC(ver, attr, varying) \ 3 ver \ 4 attr " highp vec4 a_vertex;\n" \ 5 attr " lowp vec4 a_color;\n" \ 6 "\n" \ 7 "uniform highp mat4 u_ModelViewProj;\n" \ 8 "\n" \ 9 varying " lowp vec4 v_color;\n" \ 10 "\n" \ 11 "void main()\n" \ 12 "{\n" \ 13 " gl_Position = u_ModelViewProj * a_vertex;\n" \ 14 " v_color = a_color;\n" \ 15 "}\n" \ 16 17static const char* c_VProgTextGLES2 = VERTEX_C_SRC("\n", "attribute", "varying"); 18static const char* c_VProgTextGLES3 = VERTEX_C_SRC("#version 300 es\n", "in", "out"); 19static const char* c_VProgTextGLCore = VERTEX_C_SRC("#version 150\n", "in", "out"); 20 21 22 23// フラグメントシェーダー 24#define FRAGMENT_C_SRC(ver, varying, outDecl, outVar) \ 25 ver \ 26 outDecl \ 27 varying " lowp vec4 v_color;\n" \ 28 "\n" \ 29 "void main()\n" \ 30 "{\n" \ 31 " " outVar " = v_color;\n" \ 32 "}\n" \ 33 34static const char* c_FShaderTextGLES2 = FRAGMENT_C_SRC("\n", "varying", "\n", "gl_FragColor"); 35static const char* c_FShaderTextGLES3 = FRAGMENT_C_SRC("#version 300 es\n", "in", "out lowp vec4 fragColor;\n", "fragColor"); 36static const char* c_FShaderTextGLCore = FRAGMENT_C_SRC("#version 150\n", "in", "out lowp vec4 fragColor;\n", "fragColor");

C++

1class Shader 2{ 3public: 4 GLuint m_Program; 5 GLuint m_VertShader; 6 GLuint m_FragShader; 7 GLint* m_piGLAttrib; 8 GLint m_iGLAttribNum; 9 GLint* m_piGLUniform; 10 GLint m_iGLUniformNum; 11 UnityGfxRenderer m_APIType; 12 13 Shader( const char* vert, const char* frag, const int* attribIndex, const char** attribName, int attribNum, const int* uniformIndex, const char** uniformName, int uniformNum, UnityGfxRenderer APIType) 14 { 15 m_Program = 0; 16 m_VertShader = 0; 17 m_FragShader = 0; 18 m_iGLAttribNum = 0; 19 m_piGLAttrib = NULL; 20 m_iGLAttribNum = 0; 21 m_piGLUniform = NULL; 22 m_APIType = APIType; 23 24 createShader( vert, frag, attribIndex, attribName, attribNum, uniformIndex, uniformName, uniformNum); 25 } 26 27 boolean createShader( const char* vert, const char* frag, const int* attribIndex, const char** attribName, int attribNum, const int* uniformIndex, const char** uniformName, int uniformNum) 28 { 29 // プログラムオブジェクトの作成 30 m_Program = glCreateProgram(); 31 if( m_Program == 0 ){ 32 goto _ERROR; 33 } 34 35 if( FALSE == compileShader( &m_VertShader, GL_VERTEX_SHADER, vert) ){ 36 goto _ERROR; 37 } 38 if( FALSE == compileShader( &m_FragShader, GL_FRAGMENT_SHADER, frag) ){ 39 goto _ERROR; 40 } 41 42 // シェーダオブジェクトのシェーダプログラムへの登録 43 glAttachShader( m_Program, m_VertShader ); 44 glAttachShader( m_Program, m_FragShader ); 45 46 #if SUPPORT_OPENGL_CORE 47 if (m_APIType == kUnityGfxRendererOpenGLCore) 48 glBindFragDataLocation(m_Program, 0, "fragColor"); 49 #endif // if SUPPORT_OPENGL_CORE 50 51 // シェーダプログラムのリンク 52 glLinkProgram( m_Program ); 53 54 // プログラムの検証 55 glValidateProgram( m_Program ); 56 57 // リンクフェーズで決定されたuniform locationをすべて取得 58 if( FALSE == getAttribLocations( attribIndex, attribName, attribNum ) ){ 59 goto _ERROR; 60 } 61 // リンクフェーズで決定されたattrib locationをすべて取得 62 if( FALSE == getUniformLocations( uniformIndex, uniformName, uniformNum ) ){ 63 goto _ERROR; 64 } 65 66 // シェーダオブジェクトの削除 67 releaseShader(); 68 69 return TRUE; 70 71 _ERROR: 72 release(); 73 return FALSE; 74 } 75 76 77 boolean compileShader(GLuint* shader, GLenum type, const char* source) 78 { 79 GLint iGLStatus; 80 81 if( source == NULL ){ 82 return FALSE; 83 } 84 85 *shader = glCreateShader( type ); 86 if( *shader == 0 ){ 87 goto _ERROR; 88 } 89 90 // シェーダのソースプログラムのシェーダオブジェクトへの読み込み 91 glShaderSource(*shader, 1, (const GLchar**)&source, NULL); 92 93 // シェーダのソースプログラムのコンパイル 94 glCompileShader( *shader ); 95 96 glGetShaderiv( *shader, GL_COMPILE_STATUS, &iGLStatus ); 97 if( iGLStatus == 0 ){ 98 goto _ERROR; 99 } 100 101 return TRUE; 102 103 _ERROR: 104 if( *shader ){ 105 glDeleteShader( *shader ); 106 *shader = 0; 107 } 108 return FALSE; 109 } 110 111 void releaseShader() 112 { 113 if( m_VertShader ) 114 { 115 glDeleteShader( m_VertShader ); 116 m_VertShader = 0; 117 } 118 if( m_FragShader ) 119 { 120 glDeleteShader( m_FragShader ); 121 m_FragShader = 0; 122 } 123 } 124 125 void useShader() 126 { 127 glUseProgram( m_Program ); 128 } 129 130 boolean getAttribLocations( const int* index, const GLchar** name, int32 num ) 131 { 132 glGetProgramiv( m_Program, GL_ACTIVE_ATTRIBUTES, &m_iGLAttribNum ); 133 134 m_piGLAttrib = new GLint[ num ]; 135 for( int i = 0 ; i < num ; i++ ) 136 { 137 if( m_piGLAttrib == NULL ) continue; 138 m_piGLAttrib[ index[ i ] ] = glGetAttribLocation( m_Program, name[ i ] ); 139 } 140 141 return TRUE; 142 } 143 144 boolean getUniformLocations( const int* index, const GLchar** name, int32 num ) 145 { 146 glGetProgramiv( m_Program, GL_ACTIVE_UNIFORMS, &m_iGLUniformNum ); 147 148 m_piGLUniform = new GLint[ num ]; 149 for( int i = 0 ; i < num ; i++ ) 150 { 151 if( m_piGLUniform == NULL ) continue; 152 m_piGLUniform[ index[ i ] ] = glGetUniformLocation( m_Program, name[ i ] ); 153 } 154 155 return TRUE; 156 } 157}

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

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

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

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

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

guest

回答2

0

ベストアンサー

glVertexAttribPointerにクライアント側のメモリアドレスを渡しているようですが(DrawPolyの引数vertex)、OpenGLのバージョンによっては認められない方法かと思います。
頂点情報をOpenGLサーバ側にVBOの形で送り込み、それをバインドした上でglVertexAttribPointerを使って頂点属性を指定してみてはどうでしょうか。

投稿2017/05/14 02:01

編集2017/05/14 02:02
Bongo

総合スコア10811

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

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

fumiasi

2017/05/14 07:18

情報ありがとうございます。 頂いた内容を基に glGenBuffers(1, &m_VertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertex, &pVerCoord[ 0 ], GL_STREAM_DRAW); をFillRect内で行って Render_DrawPoly()内で glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer); glEnableClientState(GL_VERTEX_ARRAY); を行ってから glVertexAttribPointer(pShader->m_piGLAttrib[COMMON_ATTRIB_VERTEX], 3, GL_FLOAT, GL_FALSE, 0, 0); を行うようにしたところ、無事に表示されるようになりました。 数日間、悩んでいた内容だったので非常に助かりました。 ありがとうございました。
guest

0

すみません
上記に収まらなかったので問題部分のソースをこちら側に追加させて頂きます。

C++

1float m_Proj[ 16 ]; 2float m_View[ 16 ]; 3OGLShader *m_ShaderTbl; 4 5// m_APITypeにはUnity側で実行されているOpenGLの環境が格納されています。 6// kUnityGfxRendererOpenGLES20 / kUnityGfxRendererOpenGLES30 / kUnityGfxRendererOpenGLCore 7// の何れかの値になります。 8UnityGfxRenderer m_APIType; 9 10// Unity側からdllの初期化/解放時に呼ばれる 11void ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces* interfaces) 12{ 13 // 初期化 14 if (type == kUnityGfxDeviceEventInitialize) 15 { 16 CreateResources(); 17 } 18 // 解放 19 else if (type == kUnityGfxDeviceEventShutdown) 20 { 21 //@TODO: release resources 22 } 23} 24 25const GLchar* commonAttribName[] = 26{ 27 "a_vertex", 28 "a_normal", 29 "a_color", 30}; 31 32enum 33{ 34 COMMON_ATTRIB_VERTEX, 35 COMMON_ATTRIB_NORMAL, 36 COMMON_ATTRIB_COLOR, 37 COMMON_ATTRIB_MAX, 38}; 39 40const int commonAttribIndex[] = 41{ 42 COMMON_ATTRIB_VERTEX, 43 COMMON_ATTRIB_NORMAL, 44 COMMON_ATTRIB_COLOR, 45}; 46 47const GLchar* commonUniformName[] = 48{ 49 "u_ModelViewProj", 50 "u_work0", 51 "u_work1", 52 "u_work2", 53}; 54 55enum 56{ 57 COMMON_UNIFORM_MODELVIEWPROJ, 58 COMMON_UNIFORM_WORK0, 59 COMMON_UNIFORM_WORK1, 60 COMMON_UNIFORM_WORK2, 61 62 COMMON_UNIFORM_MAX 63}; 64 65const int commonUniformIndex[] = 66{ 67 COMMON_UNIFORM_MODELVIEWPROJ, 68 COMMON_UNIFORM_WORK0, 69 COMMON_UNIFORM_WORK1, 70 COMMON_UNIFORM_WORK2, 71}; 72 73void CreateResources() 74{ 75 m_Proj[0] = 1.0f; m_Proj[4] = 0.0f; m_Proj[8] = 0.0f; m_Proj[12] = 0.0f; 76 m_Proj[1] = 0.0f; m_Proj[5] = 1.0f; m_Proj[9] = 0.0f; m_Proj[13] = 0.0f; 77 m_Proj[2] = 0.0f; m_Proj[6] = 0.0f; m_Proj[10] = 1.0f; m_Proj[14] = 0.0f; 78 m_Proj[3] = 0.0f; m_Proj[7] = 0.0f; m_Proj[11] = 0.0f; m_Proj[15] = 1.0f; 79 80 m_View[0] = 1.0f; m_View[4] = 0.0f; m_View[8] = 0.0f; m_View[12] = 0.0f; 81 m_View[1] = 0.0f; m_View[5] = 1.0f; m_View[9] = 0.0f; m_View[13] = 0.0f; 82 m_View[2] = 0.0f; m_View[6] = 0.0f; m_View[10] = 1.0f; m_View[14] = 0.0f; 83 m_View[3] = 0.0f; m_View[7] = 0.0f; m_View[11] = 0.0f; m_View[15] = 1.0f; 84 85 if (m_APIType == kUnityGfxRendererOpenGLCore) 86 { 87 glewExperimental = GL_TRUE; 88 glewInit(); 89 glGetError(); // glewInitで生成されたエラーを初期化する 90 } 91 92 // シェーダー生成 93 if (m_APIType == kUnityGfxRendererOpenGLES20) 94 { 95 m_ShaderTbl = new Shader(c_VProgTextGLES2, c_FShaderTextGLES2, commonAttribIndex, commonAttribName, COMMON_ATTRIB_MAX, commonUniformIndex, commonUniformName, COMMON_UNIFORM_MAX, m_APIType); 96 } 97 else if (m_APIType == kUnityGfxRendererOpenGLES30) 98 { 99 m_ShaderTbl = new Shader(c_VProgTextGLES3, c_FShaderTextGLES3, commonAttribIndex, commonAttribName, COMMON_ATTRIB_MAX, commonUniformIndex, commonUniformName, COMMON_UNIFORM_MAX, m_APIType); 100 } 101#if SUPPORT_OPENGL_CORE 102 else if (m_APIType == kUnityGfxRendererOpenGLCore) 103 { 104 m_ShaderTbl = new Shader(c_VProgTextGLCore, c_FShaderTextGLCore, commonAttribIndex, commonAttribName, COMMON_ATTRIB_MAX, commonUniformIndex, commonUniformName, COMMON_UNIFORM_MAX, m_APIType); 105 } 106#endif // if SUPPORT_OPENGL_CORE 107} 108 109void FillRect(int x, int y, int width, int height) 110{ 111 float pVerCoord[12]; 112 113 // 頂点の設定 114 pVerCoord[0] = pVerCoord[3] = (float)x; 115 pVerCoord[1] = pVerCoord[7] = (float)y; 116 pVerCoord[4] = pVerCoord[10] = (float)(y + height); 117 pVerCoord[6] = pVerCoord[9] = (float)(x + width); 118 pVerCoord[2] = pVerCoord[5] = pVerCoord[8] = pVerCoord[11] = m_Prio; 119 m_Prio += 0.0001f; // DEPTH_ADD 120 121 int alpha = ( (m_Color >> 24) & 0xFF ) 122 if (alpha < 0xFF) 123 { 124 // 半透明 125 glBlendEquation(GL_FUNC_ADD_OES); 126 glEnable(GL_BLEND); 127 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 128 } 129 130 DrawPoly(pVerCoord, m_Color, GL_TRIANGLE_STRIP, 4); 131} 132 133void DrawPoly(float *vertex, int color, GLenum type, int count) 134{ 135 // シェーダーの取得 136 OGLShader *pShader = m_ShaderTbl; 137 if (pShader == NULL) return; 138 139 // modelViewProj = m_View * m_Proj 140 float modelViewProj[ 16 ]; 141 modelViewProj[0] = m_View[0] * m_Proj[0] + m_View[1] * m_Proj[4] + m_View[2] * m_Proj[8] + m_View[3] * m_Proj[12]; 142 modelViewProj[1] = m_View[0] * m_Proj[1] + m_View[1] * m_Proj[5] + m_View[2] * m_Proj[9] + m_View[3] * m_Proj[13]; 143 modelViewProj[2] = m_View[0] * m_Proj[2] + m_View[1] * m_Proj[6] + m_View[2] * m_Proj[10] + m_View[3] * m_Proj[14]; 144 modelViewProj[3] = m_View[0] * m_Proj[3] + m_View[1] * m_Proj[7] + m_View[2] * m_Proj[11] + m_View[3] * m_Proj[15]; 145 modelViewProj[4] = m_View[4] * m_Proj[0] + m_View[5] * m_Proj[4] + m_View[6] * m_Proj[8] + m_View[7] * m_Proj[12]; 146 modelViewProj[5] = m_View[4] * m_Proj[1] + m_View[5] * m_Proj[5] + m_View[6] * m_Proj[9] + m_View[7] * m_Proj[13]; 147 modelViewProj[6] = m_View[4] * m_Proj[2] + m_View[5] * m_Proj[6] + m_View[6] * m_Proj[10] + m_View[7] * m_Proj[14]; 148 modelViewProj[7] = m_View[4] * m_Proj[3] + m_View[5] * m_Proj[7] + m_View[6] * m_Proj[11] + m_View[7] * m_Proj[15]; 149 modelViewProj[8] = m_View[8] * m_Proj[0] + m_View[9] * m_Proj[4] + m_View[10] * m_Proj[8] + m_View[11] * m_Proj[12]; 150 modelViewProj[9] = m_View[8] * m_Proj[1] + m_View[9] * m_Proj[5] + m_View[10] * m_Proj[9] + m_View[11] * m_Proj[13]; 151 modelViewProj[10] = m_View[8] * m_Proj[2] + m_View[9] * m_Proj[6] + m_View[10] * m_Proj[10] + m_View[11] * m_Proj[14]; 152 modelViewProj[11] = m_View[8] * m_Proj[3] + m_View[9] * m_Proj[7] + m_View[10] * m_Proj[11] + m_View[11] * m_Proj[15]; 153 modelViewProj[12] = m_View[12] * m_Proj[0] + m_View[13] * m_Proj[4] + m_View[14] * m_Proj[8] + m_View[15] * m_Proj[12]; 154 modelViewProj[13] = m_View[12] * m_Proj[1] + m_View[13] * m_Proj[5] + m_View[14] * m_Proj[9] + m_View[15] * m_Proj[13]; 155 modelViewProj[14] = m_View[12] * m_Proj[2] + m_View[13] * m_Proj[6] + m_View[14] * m_Proj[10] + m_View[15] * m_Proj[14]; 156 modelViewProj[15] = m_View[12] * m_Proj[3] + m_View[13] * m_Proj[7] + m_View[14] * m_Proj[11] + m_View[15] * m_Proj[15]; 157 158 // 有効化 159 pShader->useShader(); 160 161 // マトリックスの設定 162 glUniformMatrix4fv( pShader->m_piGLUniform[COMMON_UNIFORM_MODELVIEWPROJ], 1, GL_FALSE, modelViewProj.m ); 163 164 // Core profile needs VAOs, setup one 165#if SUPPORT_OPENGL_CORE 166 GLuint m_VertexArray; 167 if (m_APIType == kUnityGfxRendererOpenGLCore) 168 { 169 glGenVertexArrays(1, &m_VertexArray); 170 glBindVertexArray(m_VertexArray); 171 } 172#endif // if SUPPORT_OPENGL_CORE 173 174 // 頂点の設定 175 glEnableVertexAttribArray( pShader->m_piGLAttrib[COMMON_ATTRIB_VERTEX] ); 176 glVertexAttribPointer( pShader->m_piGLAttrib[COMMON_ATTRIB_VERTEX], 3, GL_FLOAT, GL_FALSE, 0, vertex ); 177 178 // 頂点カラー設定 179 glDisableVertexAttribArray( pShader->m_piGLAttrib[COMMON_ATTRIB_COLOR] ); 180 glVertexAttrib4f( pShader->m_piGLAttrib[COMMON_ATTRIB_COLOR], ( ( (color >> 16) & 0xFF ) * 0.0039f ), ( ( (color >> 8) & 0xFF ) * 0.0039f ), ( ( (color >> 0) & 0xFF ) * 0.0039f ), ( ( (color >> 24) & 0xFF ) * 0.0039f ) ); 181 182 // Cleanup VAO 183#if SUPPORT_OPENGL_CORE 184 if (m_APIType == kUnityGfxRendererOpenGLCore) 185 { 186 glBindVertexArray(m_VertexArray); 187 } 188#endif 189 // 描画 190 glDrawArrays( type, 0, count ); 191}

###問題点
上記の処理で

FillRect(0, 0, 1920, 1080);

を呼び出した際に、DrawPoly()関数の

// 頂点の設定 glEnableVertexAttribArray( pShader->m_piGLAttrib[COMMON_ATTRIB_VERTEX] ); glVertexAttribPointer( pShader->m_piGLAttrib[COMMON_ATTRIB_VERTEX], 3, GL_FLOAT, GL_FALSE, 0, vertex );

下側のglVertexAttribPointer()を呼び出したタイミングで
「GL_INVALID_OPERATION: Operation illegal in current state」が発生します。

投稿2017/05/13 16:01

編集2017/05/13 16:03
fumiasi

総合スコア12

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問