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

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

ただいまの
回答率

87.78%

OpenGL ES2.0の書籍とC言語→Javaへの変換について

解決済

回答 2

投稿

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

退会済みユーザー

前提・質問内容

Androidのプログラミングに興味を持って趣味でJavaを触り
手探りでまだまだ知識は浅く日々勉強しながら、調べながらも
簡単なアプリは作ってみたりもしました。

そんな時にOpenGL ESというものがあることを知って
興味を持ったので早速やってみたいと思って以下の2つの書籍を購入しました。

「マルチプラットフォームのためのOpenGL ES入門 基礎編」
「マルチプラットフォームのためのOpenGL ES入門 応用編」

上記の本はサンプルファイル(Eclipseで作られている)が付録についており
それを基にして学んでいくスタイルです。

そのサンプルプログラムを見て思ったのですが
上記の本のプログラミングはすべてC言語で記載されている上に
補助関数として筆者が作成した関数まであるそうです。

私はAndroid Studioを用いているのでEclipseを取り込んでビルドすると
エラーの無間地獄にはまってしまいエラー解決は断念しました。

となると一から作る必要があると思うのですが
私は趣味でプログラミングをしている身で
JavaしかやっていないためC言語はほとんどわかりません。

そのため「基礎編」の一番しょっぱなのサンプルである
スケルトンプログラム(初期化しただけの真っ暗な画面)からお手上げ状態です。

そこで質問としてお聞きしたいのはC言語で記載されているものを
どうやったらJavaで動かすことができるかです。

まずはスケルトンプログラムが動かないことには進まないと思うので
どうやったらC言語で書かれているものを基に
一からJavaで作ることができるのか教えていただけたらと思います。

該当のソースコード

以下が書籍の基礎編のスケルトンプログラムに必要な
ヘッダファイルとC言語のファイルです。

「マルチプラットフォームのためのOpenGL ES入門 基礎編」より引用しました。

support.h↓

#ifndef OpenGL_ES_20_support_h
#define OpenGL_ES_20_support_h

#include    <stdio.h>
#include    <stdlib.h>
#include    <stdbool.h>
#include    <assert.h>
#include    <string.h>
#include    <math.h>

#ifdef __APPLE__
#ifdef __OBJC__
#define CSTR2NSSTRING(c_str)       [[NSString alloc] initWithUTF8String:c_str]

// Objective-C source
#define     __log(message)        NSLog(@message)
#define     __logf(fmt, ...)      NSLog(@fmt, __VA_ARGS__)
#else
// C Source
#define     __log(message)        printf("%s\n", message)
#define     __logf(fmt, ...)      printf(fmt "\n", __VA_ARGS__)

#endif

#else // ANDROID
#include    <android/log.h>
#define __LOG_TAG   "GLES20"
#define __log(msg)       __android_log_print(ANDROID_LOG_DEBUG, __LOG_TAG, "%s", msg)
#define __logf(...)      __android_log_print(ANDROID_LOG_DEBUG, __LOG_TAG, __VA_ARGS__)

#endif

/**
 * アプリを強制停止させる(対応してないextension解説等)
 */
#define GLAPP_FLAG_ABORT (0x1 << 2)

struct GLApplication;

/**
 * アプリの初期化を行う
 */
typedef void (*GLApplication_initialize)(struct GLApplication *app);

/**
 * アプリの非同期処理を行う
 */
typedef void (*GLApplication_async)(struct GLApplication *app);

/**
 * レンダリングエリアが変更された
 */
typedef void (*GLApplication_surface_changed)(struct GLApplication *app);

/**
 * アプリのレンダリングを行う
 * 毎秒60回前後呼び出される。
 */
typedef void (*GLApplication_rendering)(struct GLApplication *app);

/**
 * アプリのデータ削除を行う
 */
typedef void (*GLApplication_destroy)(struct GLApplication *app);

/**
 * アプリに与えられるデータ
 * プラットフォームごとに適当な拡張を行なっている。
 */
typedef struct GLApplication {
    /**
     * View(レンダリングターゲット)の幅
     */
    int surface_width;

    /**
     * View(レンダリングターゲット)の高さ
     */
    int surface_height;

    /**
     * アプリ実行フラグ
     */
    int flags;

    /**
     * プラットフォーム固有データを格納する。
     * サンプルアプリから扱う必要はない。
     */
    void* platform;

    /**
     * 初期化関数
     */
    GLApplication_initialize initialize;

    /**
     * 非同期処理
     */
    GLApplication_async async;

    /**
     * サーフェイスサイズ変更関数
     */
    GLApplication_surface_changed resized;

    /**
     * レンダリング関数
     */
    GLApplication_rendering rendering;

    /**
     * 解放関数
     */
    GLApplication_destroy destroy;

    /**
     * サンプルごとの拡張データ保持用変数。
     * 自由に構造体等をallocして利用する。
     * XXX_destroy時に必ずfreeを行うこと。
     */
    void* extension;
} GLApplication;

/**
 * ファイルのフルパス -> ファイル名に変換する('/'区切り専用)
 */
extern char* util_getFileName(char* __file__);

/**
 * ダイアログを出して実行を停止する
 */
extern void GLApplication_abortWithMessage(GLApplication *app, const char* message);

/**
 * アプリ実行を停止している場合はapp_TRUE
 */
extern bool GLApplication_isAbort(GLApplication *app);

/**
 * ファイル系サポート関数
 */
#include    "support_RawData.h"

/**
 * GL系サポート関数宣言
 */
#include    "support_gl.h"

#endif

sample_skelton.c↓

#include "support.h"

/**
 * アプリの初期化を行う
 */
void sample_Skelton_initialize(GLApplication *app) {
    __log("initialize");
}

/**
 * レンダリングエリアが変更された
 */
void sample_Skelton_resized(GLApplication *app) {
    __logf("resized(%d x %d)", app->surface_width, app->surface_height);
}

/**
 * アプリのレンダリングを行う
 * 毎秒60回前後呼び出される。
 */
void sample_Skelton_rendering(GLApplication *app) {
//    __log("rendering");
}

/**
 * アプリのデータ削除を行う
 */
void sample_Skelton_destroy(GLApplication *app) {
    __log("destroy");
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

AndroidではOpenGL ESのAPIが提供されてます。Javaで書けます(シェーダコード除く)。
リファレンスはこちら
私は数年前にOpenGL ES2.0での実装経験しかありませんが、こんな感じで書きます。
手元のソースから抜粋:

// ActivityとView
 :
import android.opengl.GLSurfaceView;
 :

public class GameActivity extends Activity {
  // GLビュー
  private GLView glView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
     :
    // GLビュー
    glView = new GLView(stageData, screenMode, animation);
     :
  }

  private class GLView extends GLSurfaceView {
    // メインのレンダラ
    private GameRenderer gr;

    public GLView(ClusterStageData stageData, 
        int screenMode, boolean animation) {
      super(GameActivity.this);
      gr = new GameRenderer(GameActivity.this, stageData, 
          screenMode, animation, new GLColor(0.0076f, 0.0076f, 0.2025f, 1.0f));
      setEGLContextClientVersion(2);
      setRenderer(gr);
    }
  }
}
// レンダラ
 :
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.opengl.Matrix;
 :

final class GameRenderer implements Renderer {

  /**
   * 頂点シェーダ。変換行列*座標データの形式
   */
  private static final String VERTEX_SHADER_CODE = 
      "attribute vec4 vPos;" +
      "uniform mat4 vModelviewM;" +
      "attribute vec4 uvPos;" +
      "uniform mat4 uvTranslateM;" +  
      "varying vec2 uvFPos;" +
      "void main() {" + 
          "gl_Position = vModelviewM * vPos;" +
          "uvFPos = vec2(uvTranslateM * uvPos);" +
      "}";
    :
  @Override
  public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    GLES20.glClearColor(bgColor.getRed(), bgColor.getGreen(), bgColor.getBlue(), bgColor.getAlpha());
    // シェーダを作成し、プログラム開始
    int vertexShader = Utility.loadShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER_CODE);
    int fragmentShader = Utility.loadShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER_CODE);
     :
  }
   :
  @Override
  public void onDrawFrame(GL10 gl) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glUseProgram(program);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frameTexture);
    :
  }
   :
}


流れとしてはandroid.opengl.GLSurfaceViewに描画時に呼ばれるonDrawFrameなどを提供するandroid.opengl.GLSurfaceView.Rendererの実装を渡す感じです。
そしてレンダラの中でOpenGL ESのAPIを色々使います。ここまでの流れはGoogleなどで検索すればたくさん出てくると思います。
以降は、私もやりたいことのCのソースやOpenGL ESのリファレンスとにらめっこしてJavaで実装していったという感じです。基本的にはCと同じ名前のAPIがあるので、それを使えば大丈夫です。

最近はAndroidのAPIはOpenGL ES3.2まで対応しているようなので違う部分があるかもしれませんし、実装方法も変わってるかもしれませんが、私も趣味でいじった程度なのであまり詳しくありません…。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/08 21:24

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

    キャンセル

0

そこで質問としてお聞きしたいのはC言語で記載されているものを 
どうやったらJavaで動かすことができるかです。

質問はCからJavaへの移植についてだと思いますが(Android でC言語で書かれたものを動かすという意味という事も考えられちょっと心配しております)、個人的には、移植するより条件にあった書籍を購入し、勉強されたほうが良いと思います。

AndroidでOpenGLESをとなると

  • Android NDKを利用し、ネイティブから呼び出す
  • Android NDKを利用せず、AndroidライブラリのOpenGLをラップしたクラスを使って呼び出す

という方法があり

購入された書籍は、Android NDKを利用しネイティブから呼び出す実装になっていると思われます。
表題にマルチプラットフォームとありますから当然そうなると思います。

syusuketyoさんとしては、AndroidのJavaでOpenGL ES2.0を勉強したいというふうに読めますので、
もう一方のAndroid NDKを使わないで、AndroidライブラリのOpenGLをラップしたクラスを使って呼び出す方法で書かれている書籍を購入されて勉強されたほうが良いと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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