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

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

ただいまの
回答率

90.51%

  • Java

    15836questions

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

  • Android Studio

    4300questions

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

  • OpenGL ES

    34questions

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

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

解決済

回答 2

投稿

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

退会済みユーザー

前提・実現したいこと

該当のソースコードに記載している場所(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つ目

public class Deformation extends GLSurfaceView{

    MyRenderer myRenderer;
    Calculation calc = new Calculation();
    GL10 gl10;
    GL11 gl11;//ここでGL11 gl11 = (GL11) gl10;としても意味なし
             //GL11 gl11 = new GL11();とすると赤線が出てメソッドの実装が言われる


    public DeformationGLView(Context context) {
        super(context);
        myRenderer = new MyRenderer();
        setRenderer(myRenderer);
    }

    final float TOUCH_SCALE_FACTOR = 0.2f;
    final float MULTI_TOUCH_SCALE_FACTOR = 0.01f;
    private float mPreviousX0;
    private float mPreviousY0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int Action = event.getAction();
        int Count = event.getPointerCount();
        float X0 = event.getX(0);
        float Y0 = event.getY(0);
        final int x = (int) event.getX();
        final int y = (int) event.getY();



        switch (Action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:

                calc.PickUpPoint(gl11,4.0f,x,y);//ここでエラー発生
                         //ここの引数gl11でnullが入ってしまう

                if(calc.PickUpPoint(gl11,4.0f, x, y)==true) {
                    Toast.makeText(getContext(), "true", Toast.LENGTH_SHORT).show();
                }

                else{
                    Toast.makeText(getContext(),"false",Toast.LENGTH_SHORT).show();
                }


2つ目

public boolean PickUpPoint(GL11 gl11,float r,int x, int y){
        int i, j, k;

        float dis,maxdis,mindis;
        maxdis = r*r;
        mindis= r*r;

        boolean flag = false;

        for(i=0; i<ncpt[0]; i++){
            for(j=0;j<ncpt[1];j++){
                for(k=0;k<ncpt[2];k++){
                    float CPX = CP[i][j][k][0];
                    float CPY = CP[i][j][k][1];
                    float CPZ = CP[i][j][k][2];

                   //glGetFloatv,glGetIntegervでエラー発生
                    gl11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX,modelview,model_offset);
                    gl11.glGetFloatv(GL11.GL_PROJECTION_MATRIX,projection,projection_offset);
                    gl11.glGetIntegerv(GL11.GL_VIEWPORT,viewport,viewport_offset);

                    GLU.gluProject(
                            CPX, CPY, CPZ,
                            model_f,modelOffset,
                            project_f,projectOffset,
                            view,viewOffset,
                            win[0],winOffset
                );

            if ((dis = (x-win[0][0])*(x-win[0][0])+(y-win[0][1])*(y-win[0][1])) < maxdis) {

                flag = true;
                if (dis < mindis) {
                    mindis = dis;
                    }
                }else {

                }
            }
        }
    }
        return flag;
}


3つ目

public void onDrawFrame(GL10 gl) {

        long start = System.currentTimeMillis();

        gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(0.0f, 0.0f, TrancelateZ - 10.0f);

        gl.glRotatef(RotateX, 0, 1, 0);//Y軸中心の回転
        gl.glRotatef(RotateY, 1, 0, 0);//X軸中心の回転

        GL11 gl11 = (GL11) gl;
    //ここでキャストして定義しているからGL11に値が入るようになると考えている
        if (Draw == true) {
            calc.Draw(gl,gl11);//デバッグするとここのgl11には値が入っている
        }

補足情報(言語/FW/ツール等のバージョンなど)

Java
OpenGL ES 1.0
OpenGL ES 1.1
Android Studio

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • narita_takashi

    2016/12/11 01:12

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

    キャンセル

回答 2

checkベストアンサー

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/12 02:30

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

    ご回答いただきありがとうございました。

    キャンセル

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/12 02:32

    ご回答いただきありがとうございました。

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

    キャンセル

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

  • Java

    15836questions

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

  • Android Studio

    4300questions

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

  • OpenGL ES

    34questions

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