2015-12-15 7 views
8

おはよう!Android - OpenGL ES 2.0:エミュレータ(動作) - デバイス(しない)

Android用OpenGL ES 2.0で簡単なテストを行っています。私は、エミュレータでうまく動作するモデルローダーを使用しています。しかし、ASUS ZenFone 2E(Android 5.0.1)(プリペイド・フォン)で使用しようとすると、回転するモデルのない背景のクリアカラーが表示されます。 OpenGL ES 2.0とAndroidの両方で豊富な経験を積んだ人が私を助けてくれることを願っています。申し訳ありませんが、冗長ではありませんが、なぜ電話機で動作していないのかわかりません。ここではソースが(私は極度の初心者です)です:

GameView.java:

package wise.child.dials; 

import android.content.Context; 
import android.opengl.GLES20; 
import android.opengl.GLSurfaceView; 
import android.opengl.Matrix; 
import android.os.SystemClock; 

import java.io.IOException; 
import java.nio.FloatBuffer; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import model.Model; 
import render.Program; 
import render.Shader; 
import util.OBJLoader; 

public class GameView extends GLSurfaceView implements GLSurfaceView.Renderer { 

    // App Context 
    private Context mContext; 

    // Handles 
    private int mPositionHandle; 
    private int mColorHandle; 
    private int mMVPMatrixHandle; 

    // Program & Shaders 
    private Program testProgram; 
    private Shader testVertexShader; 
    private Shader testFragmentShader; 

    // Model 
    private Model model; 
    private FloatBuffer vertexFloatBuffer; 
    private int vertexCount; 

    // Matrices 
    private final float[] mMVPMatrix = new float[16]; 
    private final float[] mProjectionMatrix = new float[16]; 
    private final float[] mViewMatrix = new float[16]; 
    private float[] mRotationMatrix = new float[16]; 

    // Constructor 
    public GameView(Context context) { 
     super(context); 

     // App Context 
     mContext = context; 

     // OpenGL ES 2.0 Context 
     setEGLContextClientVersion(2); 

     // Renderer 
     setRenderer(this); 
    } 

    /*-------------------*/ 
    /* Rendering Methods */ 
    /*-------------------*/ 

    // One Time Initialization 
    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     GLES20.glClearColor(0.95f, 0.95f, 0.95f, 1f); 

     // Initialize Shaders 
     testVertexShader = new Shader(GLES20.GL_VERTEX_SHADER, mContext, R.raw.test_vertex_shader); 
     testFragmentShader = new Shader(GLES20.GL_FRAGMENT_SHADER, mContext, R.raw.test_fragment_shader); 

     // Create Program 
     testProgram = new Program(testVertexShader, testFragmentShader); 
     testProgram.use(); 

     // Get Handles - Uniforms & Attributes 
     mPositionHandle = testProgram.getAttribute("vPosition"); 
     mColorHandle = testProgram.getUniform("vColor"); 
     mMVPMatrixHandle = testProgram.getUniform("uMVPMatrix"); 

     // Model 
     try { 
      model = OBJLoader.loadOBJ(mContext, R.raw.spider); 
      vertexFloatBuffer = model.getVerticesFromIndices(); 
      vertexCount = model.getVertexCount(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    // Drawing Call 
    @Override 
    public void onDrawFrame(GL10 gl) { 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 

     // Time and Rotation Animation 
     float[] scratch = new float[16]; 
     long time = SystemClock.uptimeMillis() % 4000L; 
     float angle = 0.090f * ((int) time); 
     Matrix.setRotateM(mRotationMatrix, 0, angle, angle, angle, angle); 

     // Set and Bind Data 
     GLES20.glEnableVertexAttribArray(mPositionHandle); 
     GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexFloatBuffer); 

     // Set Color 
     float[] color = {.75f, 0f, 0f, 1f}; 
     GLES20.glUniform4fv(mColorHandle, 1, color, 0); 

     // Camera Position - View Matrix 
     Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -15, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 

     // Projection x View 
     Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0); 

     // Rotation x MVP 
     Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0); 

     // Final Matrix 
     GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, scratch, 0); 

     // Draw 
     GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); 

     // Disable 
     GLES20.glDisableVertexAttribArray(mPositionHandle); 

    } 

    // GLSurface Changed 
    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 

     // GL Viewport & Aspect Ratio 
     GLES20.glViewport(0, 0, width, height); 
     float aspectRatio = (float) width/height; 

     // Calculate Projection 
     Matrix.frustumM(mProjectionMatrix, 0, -aspectRatio, aspectRatio, -1, 1, 3, 50); 
    } 

} 

Shader.java

package render; 

import android.content.Context; 
import android.opengl.GLES20; 
import android.util.Log; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 

public class Shader { 

    // Shader Source Code 
    public String shaderSource; 

    // Shader Handle 
    public int shaderHandle; 

    public int programHandle; 

    public Shader(int type, Context context, int resID) { 

     try { 
      shaderSource = loadShader(context, resID); 
      Log.d("Shader Load", "Success!"); 
      System.out.println(shaderSource); 
     } catch (IOException e) { 
      Log.d("Shader Load", "Failed."); 
      e.printStackTrace(); 
     } 

     shaderHandle = GLES20.glCreateShader(type); 
     GLES20.glShaderSource(shaderHandle, shaderSource); 
     GLES20.glCompileShader(shaderHandle); 

    } 

    // Get From Raw Folder 
    private String loadShader(Context context, int resID) throws IOException { 

     BufferedReader reader = new BufferedReader(
       new InputStreamReader(context.getResources().openRawResource(resID)) 
     ); 

     String line, shader; 
     StringBuilder builder = new StringBuilder(); 

     while ((line = reader.readLine()) != null) { 
      builder.append(line).append('\n'); 
     } 

     reader.close(); 

     shader = builder.toString(); 

     return shader; 
    } 

    // Associated Program 
    public void setProgram(int handle) { 
     programHandle = handle; 
    } 


} 

Program.java

package render; 

import android.opengl.GLES20; 

import java.util.ArrayList; 
import java.util.List; 

public class Program { 

    public int handle; 

    private Shader vertexShader; 
    private Shader fragmentShader; 

    private List<String> attributes = new ArrayList<String>(); 
    private List<String> uniforms = new ArrayList<String>(); 

    public Program(Shader vertexShader, Shader fragmentShader) { 
     this.vertexShader = vertexShader; 
     this.fragmentShader = fragmentShader; 

     this.vertexShader.setProgram(handle); 
     this.fragmentShader.setProgram(handle); 

     handle = GLES20.glCreateProgram(); 
     GLES20.glAttachShader(handle, vertexShader.shaderHandle); 
     GLES20.glAttachShader(handle, fragmentShader.shaderHandle); 
     GLES20.glLinkProgram(handle); 


    } 

    public void use() { 
     GLES20.glUseProgram(handle); 
    } 

    public int getAttribute(String name) { 
     return GLES20.glGetAttribLocation(handle, name); 
    } 

    public void setAttribute(String name) { 

    } 

    public int getUniform(String name) { 
     return GLES20.glGetUniformLocation(handle, name); 
    } 
} 

Model.java

package model; 

import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 
import java.util.ArrayList; 
import java.util.List; 

public class Model { 

    private static final int NUM_OF_COORDS = 3; 

    public List<Vertex> vertices = new ArrayList<Vertex>(); 
    public List<Vertex> normals = new ArrayList<Vertex>(); 
    public List<Face> faces = new ArrayList<Face>(); 

    public Model() {} 

    public int getVertexCount() { 
     return faces.size() * NUM_OF_COORDS; 
    } 

    public FloatBuffer getVerticesFromIndices() { 

     int numOfVertices = 3; 
     int bytesPerFloat = 4; 

     ByteBuffer bb = ByteBuffer.allocateDirect(faces.size() * numOfVertices * NUM_OF_COORDS * bytesPerFloat); 
     bb.order(ByteOrder.nativeOrder()); 
     FloatBuffer vertexFloatBuffer = bb.asFloatBuffer(); 

     // Use indices to find proper vertex 
     for (Face face : faces) { 

      // VERTEX 1 
      vertexFloatBuffer.put(vertices.get((int) (face.vertex.x - 1)).x); 
      vertexFloatBuffer.put(vertices.get((int) (face.vertex.x - 1)).y); 
      vertexFloatBuffer.put(vertices.get((int)(face.vertex.x - 1)).z); 

      // VERTEX 2 
      vertexFloatBuffer.put(vertices.get((int)(face.vertex.y - 1)).x); 
      vertexFloatBuffer.put(vertices.get((int)(face.vertex.y - 1)).y); 
      vertexFloatBuffer.put(vertices.get((int)(face.vertex.y - 1)).z); 

      // VERTEX 3 
      vertexFloatBuffer.put(vertices.get((int)(face.vertex.z - 1)).x); 
      vertexFloatBuffer.put(vertices.get((int)(face.vertex.z - 1)).y); 
      vertexFloatBuffer.put(vertices.get((int)(face.vertex.z - 1)).z); 
     } 

     vertexFloatBuffer.position(0); 

     return vertexFloatBuffer; 
    } 

    public FloatBuffer getNormalsFromIndices() { 

     int numOfVertices = 3; 
     int bytesPerFloat = 4; 

     ByteBuffer bb = ByteBuffer.allocateDirect(faces.size() * numOfVertices * NUM_OF_COORDS * bytesPerFloat); 
     bb.order(ByteOrder.nativeOrder()); 
     FloatBuffer normalFloatBuffer = bb.asFloatBuffer(); 

     // Use indices to find proper normal 
     for (Face face : faces) { 

      // VERTEX 1 
      normalFloatBuffer.put(normals.get((int) (face.normal.x - 1)).x); 
      normalFloatBuffer.put(normals.get((int) (face.normal.x - 1)).y); 
      normalFloatBuffer.put(normals.get((int)(face.normal.x - 1)).z); 

      // VERTEX 2 
      normalFloatBuffer.put(normals.get((int)(face.normal.y - 1)).x); 
      normalFloatBuffer.put(normals.get((int)(face.normal.y - 1)).y); 
      normalFloatBuffer.put(normals.get((int)(face.normal.y - 1)).z); 

      // VERTEX 3 
      normalFloatBuffer.put(normals.get((int)(face.normal.z - 1)).x); 
      normalFloatBuffer.put(normals.get((int)(face.normal.z - 1)).y); 
      normalFloatBuffer.put(normals.get((int)(face.normal.z - 1)).z); 
     } 

     normalFloatBuffer.position(0); 

     return normalFloatBuffer; 
    } 


} 

OBJLoader.java

package util; 

import android.content.Context; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 

import model.Face; 
import model.Model; 
import model.Vertex; 

public class OBJLoader { 

    /* loads .obj data from file in res/raw folder */ 
    public static Model loadOBJ(Context context, int resID) throws IOException { 

     Model model = new Model(); 

     BufferedReader reader = new BufferedReader(
       new InputStreamReader(context.getResources().openRawResource(resID)) 
     ); 

     String line; 

     while ((line = reader.readLine()) != null) { 
      if (line.startsWith("v ")) { 
       // Vertex 
       float x = Float.valueOf(line.split(" ")[1]); 
       float y = Float.valueOf(line.split(" ")[2]); 
       float z = Float.valueOf(line.split(" ")[3]); 
       model.vertices.add(new Vertex(x, y, z)); 

      } else if (line.startsWith("vn ")) { 
       // Normal 
       float x = Float.valueOf(line.split(" ")[1]); 
       float y = Float.valueOf(line.split(" ")[2]); 
       float z = Float.valueOf(line.split(" ")[3]); 
       model.normals.add(new Vertex(x, y, z)); 

      } else if (line.startsWith("f ")) { 
       // Face 
       Vertex vertexIndices = new Vertex(
         Float.valueOf(line.split(" ")[1].split("/")[0]), 
         Float.valueOf(line.split(" ")[2].split("/")[0]), 
         Float.valueOf(line.split(" ")[3].split("/")[0]) 
       ); 

       Vertex normalIndices = new Vertex(
         Float.valueOf(line.split(" ")[1].split("/")[2]), 
         Float.valueOf(line.split(" ")[2].split("/")[2]), 
         Float.valueOf(line.split(" ")[3].split("/")[2]) 
       ); 

       model.faces.add(new Face(vertexIndices, normalIndices)); 
      } 
     } 

     reader.close(); 

     return model; 
    } 
} 

MainActivity.java

package wise.child.dials; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.Window; 
import android.view.WindowManager; 

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Fullscreen & No Title Bar 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     // Set OpenGL ES Drawing Surface (Game View) 
     setContentView(new GameView(this)); 
    } 
} 

AndroidManifest.xmlを

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="wise.child.dials"> 

    <uses-feature 
     android:glEsVersion="0x00020000" 
     android:required="true" /> 

    <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" /> 
    <supports-gl-texture android:name="GL_OES_compressed_paletted_texture" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity 
      android:name=".MenuActivity" 
      android:screenOrientation="landscape" 
      android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"> 
     </activity> 

     <activity 
      android:name=".MainActivity" 
      android:screenOrientation="landscape" 
      android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <activity android:name=".SplashScreen" /> 
    </application> 

</manifest> 

バーテックスシェーダ

attribute vec4 vPosition; 

uniform mat4 uMVPMatrix; 

void main() { 
    gl_Position = uMVPMatrix * vPosition; 
} 

フラグメントシェーダ

uniform vec4 vColor; 

void main() { 
    gl_FragColor = vColor; 
} 

enter image description here

答えて

1

この特定の問題へのソリューション:

だから、私は私のフラグメントシェーダに次の行を追加:

precision mediump float;

が私たちを与えるために:

フラグメントシェーダ

precision mediump float; 

uniform vec4 vColor; 

void main() { 
    gl_FragColor = vColor; 
} 

を、これは働いていたなぜ、私が」私は知らないと言って恥ずかしい。誰かがさらに詳しく説明したいと思うなら、私は興味がありますか?私はまだOpenGL ES 2.0を学んでいます。 OpenGL ES 2.0プログラミングガイド(Good Book)を読んで、私はその行に出会いました。また、「OpenGL ES 2.0では、有効な頂点シェーダとフラグメントシェーダがロードされていない限り、描画することはできません。Androidのチュートリアルにもこの行が含まれていますので、重要です。

+0

Androidのシェーダとライティングについての詳細は、この本もお試しください:https://pragprog.com/book/kbogla/opengl-es-2 -for-android - 私は現在それを勉強していて、(ダウンロード可能なzip形式の)サンプルはとても素晴らしいもので、うまく動作します。 –

関連する問題