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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

OpenGL ES

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

2回答

1892閲覧

gl11に値が入っていないことによるNullPointerExceptionの解決

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

OpenGL ES

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

1クリップ

投稿2016/12/10 06:18

###前提・実現したいこと
該当のソースコードに記載している場所(2か所)でNullPointerExceptionが出てしまいました。

そこでデバッグしてどこが問題なのかというのを探ってみると
1つ目のソースコードに記載している
「calc.PickUpPoint(gl11,4.0f,x,y)」
の引数であるgl11にnullが入ってしまっていることがわかりました。

そこでここのnullを解決できればいいと思うのですが
どうやってgl11という引数に値を入れられるようにすればいいのかがわかりません。

というのも3つ目のソースコードにあるonDrawFrameメソッドでは
同じようにgl11を引数とする呼び出しをしているのですが
デバッグをしてみるときちんとnullではない値が入っていました。

なぜなのかということを考えた時にonDrawFrameメソッドの引数にglが使われており
それをキャストすることで定義しているからではないかと考えました。

それで1つ目のソースコードを見てみるとgl11に何か値を入れるような書き方はしていません。

しかし同じようにキャストしても意味がなかったうえに
インスタンスの生成のようなことをすると赤線が出て
解決の提案として「Implement method」と表示されしまいます。

そこでどうすればgl11に値が入るようになるのかご教授いただきたく今回質問させていただきました。

###発生している問題・エラーメッセージ

NullPointerExceptionが出た場所を記載します。

1つ目のソースコード:calc.PickUpPoint(gl11,4.0f,x,y)
2つ目のソースコード:glGetFloatv(GL11.GL_MODELVIEW_MATRIX,modelview,model_offset)

modelview,model_offsetは該当のソースコードには記載していませんが
2つめのソースコードが記載されているクラスで定義しています。

###該当のソースコード
1つ目

java

1public class Deformation extends GLSurfaceView{ 2 3 MyRenderer myRenderer; 4 Calculation calc = new Calculation(); 5 GL10 gl10; 6 GL11 gl11;//ここでGL11 gl11 = (GL11) gl10;としても意味なし 7 //GL11 gl11 = new GL11();とすると赤線が出てメソッドの実装が言われる 8 9 10 public DeformationGLView(Context context) { 11 super(context); 12 myRenderer = new MyRenderer(); 13 setRenderer(myRenderer); 14 } 15 16 final float TOUCH_SCALE_FACTOR = 0.2f; 17 final float MULTI_TOUCH_SCALE_FACTOR = 0.01f; 18 private float mPreviousX0; 19 private float mPreviousY0; 20 21 @Override 22 public boolean onTouchEvent(MotionEvent event) { 23 int Action = event.getAction(); 24 int Count = event.getPointerCount(); 25 float X0 = event.getX(0); 26 float Y0 = event.getY(0); 27 final int x = (int) event.getX(); 28 final int y = (int) event.getY(); 29 30 31 32 switch (Action & MotionEvent.ACTION_MASK) { 33 case MotionEvent.ACTION_DOWN: 34 35 calc.PickUpPoint(gl11,4.0f,x,y);//ここでエラー発生 36 //ここの引数gl11でnullが入ってしまう 37 38 if(calc.PickUpPoint(gl11,4.0f, x, y)==true) { 39 Toast.makeText(getContext(), "true", Toast.LENGTH_SHORT).show(); 40 } 41 42 else{ 43 Toast.makeText(getContext(),"false",Toast.LENGTH_SHORT).show(); 44 } 45

2つ目

java

1 public boolean PickUpPoint(GL11 gl11,float r,int x, int y){ 2 int i, j, k; 3 4 float dis,maxdis,mindis; 5 maxdis = r*r; 6 mindis= r*r; 7 8 boolean flag = false; 9 10 for(i=0; i<ncpt[0]; i++){ 11 for(j=0;j<ncpt[1];j++){ 12 for(k=0;k<ncpt[2];k++){ 13 float CPX = CP[i][j][k][0]; 14 float CPY = CP[i][j][k][1]; 15 float CPZ = CP[i][j][k][2]; 16 17 //glGetFloatv,glGetIntegervでエラー発生 18 gl11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX,modelview,model_offset); 19 gl11.glGetFloatv(GL11.GL_PROJECTION_MATRIX,projection,projection_offset); 20 gl11.glGetIntegerv(GL11.GL_VIEWPORT,viewport,viewport_offset); 21 22 GLU.gluProject( 23 CPX, CPY, CPZ, 24 model_f,modelOffset, 25 project_f,projectOffset, 26 view,viewOffset, 27 win[0],winOffset 28 ); 29 30 if ((dis = (x-win[0][0])*(x-win[0][0])+(y-win[0][1])*(y-win[0][1])) < maxdis) { 31 32 flag = true; 33 if (dis < mindis) { 34 mindis = dis; 35 } 36 }else { 37 38 } 39 } 40 } 41 } 42 return flag; 43}

3つ目

java

1public void onDrawFrame(GL10 gl) { 2 3 long start = System.currentTimeMillis(); 4 5 gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 6 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 7 8 gl.glMatrixMode(GL10.GL_MODELVIEW); 9 gl.glLoadIdentity(); 10 gl.glTranslatef(0.0f, 0.0f, TrancelateZ - 10.0f); 11 12 gl.glRotatef(RotateX, 0, 1, 0);//Y軸中心の回転 13 gl.glRotatef(RotateY, 1, 0, 0);//X軸中心の回転 14 15 GL11 gl11 = (GL11) gl; 16 //ここでキャストして定義しているからGL11に値が入るようになると考えている 17 if (Draw == true) { 18 calc.Draw(gl,gl11);//デバッグするとここのgl11には値が入っている 19 } 20 21

###補足情報(言語/FW/ツール等のバージョンなど)
Java
OpenGL ES 1.0
OpenGL ES 1.1
Android Studio

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

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

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

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

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

narita_takashi

2016/12/10 16:12

こちらの該当ソースはどこから持ってこられたものですか?たぶん作成された方に確認された方が解決は早い気がするのですが。。。
guest

回答2

0

ベストアンサー

GL10,GL11というのはonDrawFrameのようなOpenGLのハンドラーに引数として渡されるもので「OpenGLのAPIを呼び出すためのオブジェクト」のようです。よって自分でnewしてもNGでOpenGLのランタイムがハンドラーに渡してくれたオブジェクトを利用するという使い方が普通のようです。

以下は推測です。

単なるAPI呼び出しに用いるオブジェクトに思えるので実際はアプリケーション動作中にOpenGLのランタイムのどこかにGL11のインスタンスが記憶されている(シングルトンとして)という気がします。うまくいくかどうかはわかりませんが、試しに次のようにしてみたらどうでしょうか。

  1. Deformation クラスのgl11フィールドをstaticにする。
  2. OpenGLのハンドラー(onDrawFrameのようなもの)で引数のGL10のインスタンスをGL11へキャストし、1.に定義したstaticフィールドへ設定する(覚えさせる)してしまう。

ちなみにGL11はGL10の派生クラスでありGL10のメソッドはGL11にもあるはずなので、DeformationクラスにGL10,GL11の両方を持つ必要はなくGL11のみあれば充分だと思えます。

ただし、上記のやりかたは非常にインチキな方法に感じるのでOpenGLのハンドラー以外でもGL11のインスタンスを使ってよいならば本来どこかのクラスにGL10のインスタンスを取ってくるstaticなメソッドが定義されている気がします。もしそういうものがないならOpenGLのハンドラー以外からOpenGLのAPIを呼ぶことは禁止なのかも知れません。

投稿2016/12/11 03:38

KSwordOfHaste

総合スコア18394

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

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

退会済みユーザー

退会済みユーザー

2016/12/11 17:30

KSwordOfHaste様の仰ったやり方でやってみたところ 無事にNPEが消え値もきちんと入るようになりました。 ご回答いただきありがとうございました。
guest

0

背景を理解しないまま回答してみます。おそらく「とりあえず動いた」というレベルまで持っていけると思いますが、正しい方法でない可能性が高いです。

案1: 1つめのJavaにおいて、gl10 をどこかで代入しているでしょうから、そこで gl11 = (GL11)gl10; のように受け取ってしまえば、とりあえず gl11 は null ではなくなるでしょう。
gl10を代入している箇所が見つからないなら、DIしている可能性があります。setGl10(gl10) のようなセッターメソッドを作れば、DIを騙せるかもしれない。

案2: gl11変数に値を格納することはあきらめ、呼び出し時に calc.PickUpPoint((GL11)gl10,4.0f,x,y); のように帳尻を合わせてしまえば、とりあえずは NPEは回避できるのではないでしょうか。

繰り返しますが、あくまで「とりあえず動いた」レベルまで持っていっているだけです。

https://developer.android.com/guide/topics/graphics/opengl.html
を見たところ、古いAndroid機の互換性を強く意識しているのでなければ、2.xや3.xのほうがいいのではないかとも思います。

投稿2016/12/11 02:35

matobaa

総合スコア2493

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

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

退会済みユーザー

退会済みユーザー

2016/12/11 17:32

ご回答いただきありがとうございました。 バージョン2.x以降でやったほうがいいのかなと思うこともあるのですが 余りにもシェーダーの仕様が違っているため1.xのままやっている次第です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問