我开始在 Android 上学习 OpenGL,现在我正在尝试摆弄一个简单的三角形。
我想要做的是让它原地旋转(旋转轴是形状的中心),尽管我只是设法让它绕着一个轴旋转(我的意思是它在指定的轴上做圆周运动)。
这是我的代码:
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -10, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
long time = SystemClock.uptimeMillis() % 4000L;
float angle = 0.090f * ((int) time);
Matrix.setIdentityM(mModelMatrix, 0); // initialize to identity matrix
Matrix.rotateM(mModelMatrix, 0, angle, 0, 1.0f, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
mPlayerCharacter.draw(mMVPMatrix);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
mPlayerCharacter = new PlayerCharacter();
}
----- PlayerCharacter.draw() -----
public void draw(float[] mvpMatrix) {
// Add program to OpenGL ES environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
// Pass the projection and view transformation to the shader
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
三角形坐标为顶部 (0, 0.622, 0)、左下 (-0.5, -0.311, 0) 和右下 (0.5, -0.311, 0)。
我尝试寻找类似的问题或相关指南,但我找到的答案都不适合我。
如果是这样,实现我正在寻找的结果的正确方法是什么?
最佳答案
假设您有对象转换矩阵:
protected final float[] mTransformMatrix = new float[16];
当您创建对象时,您只需使用 Matrix.setIdentityM(mTransformMatrix, 0);
旋转你需要:
Matrix.rotateM(mTransformMatrix, 0, angle, 0, 0, 1.0f);
下面是一些对象定位、大小和旋转的方法:
public Sprite setSize(float sizeX, float sizeY) {
setCenterSizeRotation(this.mPositionX, this.mPositionY, sizeX, sizeY,
this.mAngle);
this.mSpriteWidth = sizeX;
this.mSpriteHeight = sizeY;
return this;
}
public Sprite setCenter(float posX, float posY) {
setCenterSizeRotation(posX, posY, this.mSpriteWidth,
this.mSpriteHeight, this.mAngle);
this.mPositionX = posX;
this.mPositionY = posY;
return this;
}
public Sprite setRotation(float angle) {
setCenterSizeRotation(this.mPositionX, this.mPositionY,
this.mSpriteWidth, this.mSpriteHeight, angle);
this.mAngle = angle;
return this;
}
public Sprite setCenterSizeRotation(float posX, float posY, float sizeX,
float sizeY, float angle) {
reset();
float oX = UtilsGL.getStepX() * posX - 1.0f;
float oY = UtilsGL.getStepY() * posY - 1.0f;
float scaleX = sizeX / (UtilsGL.getSurfaceWidth());
float scaleY = sizeY / (UtilsGL.getSurfaceHeight());
translate(oX, oY);
scale(scaleX, scaleY);
rotate(angle);
this.mSpriteWidth = sizeX;
this.mSpriteHeight = sizeY;
this.mPositionX = posX;
this.mPositionY = posY;
this.mAngle = angle;
return this;
}
public Sprite translate(float x, float y) {
Matrix.translateM(mTransformMatrix, 0, x, y, 0);
return this;
}
public Sprite scale(float x, float y) {
Matrix.scaleM(mTransformMatrix, 0, x, y, 1.0f);
return this;
}
public Sprite rotate(float d) {
Matrix.rotateM(mTransformMatrix, 0, d, 0, 0, 1.0f);
return this;
}
public Sprite reset() {
Matrix.setIdentityM(mTransformMatrix, 0);
return this;
}
不要害怕返回,这只是我的 Sprite 类中的一些代码
UtilsGL部分:
private static int mSurfaceWidth;
private static int mSurfaceHeight;
private static float mStepX;
private static float mStepY;
public static void setSurfaceWH(int width, int height) {
mSurfaceWidth = width;
mSurfaceHeight = height;
mStepX = 2.0f / (float) mSurfaceWidth;
mStepY = 2.0f / (float) mSurfaceHeight;
}
public static int getSurfaceWidth() {
return mSurfaceWidth;
}
public static int getSurfaceHeight() {
return mSurfaceHeight;
}
public static float getStepX() {
return mStepX;
}
public static float getStepY() {
return mStepY;
}
下面有很多代码,但都很有用。为什么是静态的?我不是 OOP 极客)我选择让它简单但实用
关于java - 在 Android 上使用 OpenGL ES 使对象/形状原地旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21687044/