エブリカ!!!
私はほとんど自殺していた!Canvas を離れて OpenGL メソッドを学習し、ゲーム エンジンを実装してから 3 日後。
Web にはごみだらけの OpenGL チュートリアルがあふれており、その多くは未完成であり、その多くは 2D OpenGL ゲーム エンジンの実装方法の間違った方法につながっています。大きな間違いは、G11Ext をゲームの作成に使用することです。回転しないので : D
その後、YouTube ゲームのサンプル ビデオ リンクから見つけた他のチュートリアルからこのチュートリアルを見つけました笑:
ここで視聴者を混乱させないために
第1章: http://obviam.net/index.php/opengl-es-with-android-switching-from-canvas-to-opengl/
第2章: http://obviam.net/index.php/opengl-es-android-displaying-graphical-elements-primitives/
第3章: http://obviam.net/index.php/texture-mapping-opengl-android-displaying-images-using-opengl-and-squares/
ちょうど 15 分前に、スプライトを使用して図形を回転、移動、およびサイズ変更できる方法を発見しました。! ! ハハハ
この素晴らしいチュートリアルを読んだ後、多くの読者がスプライトの移動、サイズ変更、回転の方法を尋ねています。だから私は、この混乱した例とチュートリアルからいくつかのコードを作成しました:
このクラスは、いくつかの頂点操作に使用されます
public class Vertex
{
public FloatBuffer buffer; // buffer holding the vertices
public float vertex[];
public Vertex (float[] vertex)
{
this.vertex = vertex;
this.prepare ();
}
private void prepare ()
{
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer factory = ByteBuffer.allocateDirect (vertex.length * 4);
factory.order (ByteOrder.nativeOrder ());
// allocates the memory from the byte buffer
buffer = factory.asFloatBuffer ();
// fill the vertexBuffer with the vertices
buffer.put (vertex);
// set the cursor position to the beginning of the buffer
buffer.position (0);
}
}
このクラスは、回転と位置を移動できるテクスチャで形状を描画するために使用されます
public class Square
{
Vertex shape,texture;
int corner=0;
float x=0;
public Square()
{
shape = new Vertex (new float[]
{
1f,1f,0f,
0f,1f,0f,
1f,0f,0f,
0f,0f,0f,
});
texture = new Vertex (new float[]
{
1.0f, 0.0f,
0.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
});
}
/** The draw method for the square with the GL context */
public void draw (GL10 gl, int image, float x, float y, float width, float height, float corner)
{
if (corner>=0)
{
corner += 1;
}
if (corner>360)
{
corner = -1;
}
gl.glPushMatrix();
x += 1f;
if (x>800)
{
x = 0;
}
position (gl, 0, 0, width, height, corner);
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, image);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// set the colour for the square
gl.glColor4f (0.0f, 1.0f, 0.0f, 0.5f);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer (3, GL10.GL_FLOAT, 0, shape.buffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texture.buffer);
// Draw the vertices as triangle strip
gl.glDrawArrays (GL10.GL_TRIANGLE_STRIP, 0, shape.vertex.length / 3);
// Disable the client state before leaving
gl.glDisableClientState (GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glPopMatrix();
}
public void position (GL10 gl, float x, float y, float width, float height, float corner)
{
gl.glTranslatef (x, y, 0f); //MOVE !!! 1f is size of figure if called after scaling, 1f is pixel if called before scaling
if (corner>0)
{
gl.glTranslatef (width/2, height/2, 0f);
gl.glRotatef (corner, 0f, 0f, 1f); // ROTATE !!!
gl.glTranslatef (-width/2, -height/2, 0f);
}
gl.glScalef (width, height, 0f); // ADJUST SIZE !!!
}
}
主なことは、1つのopengl単位== 1ピクセルになるようにカメラを設定する方法と、テクスチャをロードする方法です
public class Scene implements Renderer
{
public Context context;
public Resources resources;
public SparseIntArray images = new SparseIntArray ();
public float width;
public float height;
public Scene (Context context)
{
this.context = context;
this.resources = context.getResources ();
}
@Override
public void onDrawFrame (GL10 gl)
{
// // clear Screen and Depth Buffer
gl.glClear (GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
// // Reset the Modelview Matrix
gl.glLoadIdentity ();
draw (gl);
}
@Override
public void onSurfaceChanged (GL10 gl, int width, int height)
{
this.width = width;
this.height = height;
gl.glViewport (0, 0, width, height); // Reset The Current Viewport
gl.glMatrixMode (GL10.GL_PROJECTION); // Select The Projection Matrix
gl.glLoadIdentity (); // Reset The Projection Matrix
gl.glOrthof (0, width, 0, height, -1f, 1f);
//gl.glTranslatef (0f, -height/2, 0.0f); // move the camera !!
gl.glMatrixMode (GL10.GL_MODELVIEW); // Select The Modelview Matrix
gl.glLoadIdentity (); // Reset The Modelview Matrix
load (gl);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping ( NEW )
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_BLEND);
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
init (gl);
}
public void init (GL10 gl)
{
}
public void load (GL10 gl)
{
}
public void draw (GL10 gl)
{
}
private static int next (GL10 gl)
{
int[] temp = new int[1];
gl.glGenTextures (1, temp, 0);
return temp[0];
}
public int image (GL10 gl, int resource)
{
int id = next (gl);
images.put (resource, id);
gl.glBindTexture (GL10.GL_TEXTURE_2D, id);
gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
gl.glTexEnvf (GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
BitmapFactory.Options options = new BitmapFactory.Options ();
options.inScaled = false;
InputStream input = resources.openRawResource (resource);
Bitmap bitmap;
try
{
bitmap = BitmapFactory.decodeStream (input, null, options);
}
finally
{
try
{
input.close ();
}
catch (IOException e)
{
// Ignore.
}
}
// Matrix flip = new Matrix ();
// flip.postScale (1f, -1f);
// bitmap = Bitmap.createBitmap (bitmap, 0, 0, bitmap.getWidth (), bitmap.getHeight (), flip, true);
GLUtils.texImage2D (GL10.GL_TEXTURE_2D, 0, bitmap, 0);
return id;
}
}
そしていくつかの使用法
public class Scene2 extends Scene
{
Square square1, square2;
public Scene2(Context context)
{
super (context);
// TODO Auto-generated constructor stub
}
public void init (GL10 gl)
{
square1 = new Square ();
square2 = new Square ();
}
public void load (GL10 gl)
{
image (gl, R.drawable.s1_clouds);
image (gl, R.drawable.s1_ground);
}
public void draw (GL10 gl)
{
square1.draw (gl, images.get(R.drawable.s1_clouds), 0, 0, width, height, 0);
square1.draw (gl, images.get(R.drawable.s1_ground), 0, 0, width, height, 0);
}
}
ここで実装して実装したかった主なことは、X 軸と Y 軸がキャンバスに似ていることです。
(0,0)
--------------------------------- X axis
|
|
|
|
|
|
|
|
Y axis
この後にいくつかの完全なチュートリアルを書きます。達成したいすべての目標を達成したことを発表したいと思います。つまり、X 軸を上に、Y 軸を左に、opengl 単位 = ピクセル、オブジェクトのサイズをピクセルで設定、オブジェクトを回転、移動します。すべてをピクセル単位でオブジェクト化します。今、私はスプライトのアニメーションを処理し、それらをより細かいクラスにします。それが新しい 2D OpenGL ゲーム フレームワークの基礎です...
この関数を発見すると、チュートリアルが役立ちましたhttp://www.morrowland.com/apron/tutorials/gl/gl_matrix.php
唯一の本当の方法を教えてくれたこのブログにとても感謝しています...
+1 android 最も単純な 2D OpenGL ゲーム エンジンを 1 週間で...
幸せな心が吹いています...
:P
編集: 1 年後、ここで説明されている概念を使用した素晴らしいフレームワークhttps://github.com/hazardland/game.androidと、考えられるフレームワークの使用例を含むサンプル ゲームがhttps://github.com/hazardland/ferry.android (市場で画面を見るhttps://play.google.com/store/apps/details?id=hazardland.borani )