[英]Making an object/shape rotate in place with OpenGL ES on Android
I started learning OpenGL on android, and now I'm trying to mess around with a simple triangle. 我开始在android上学习OpenGL,现在我想弄个简单的三角形。
What I'm trying to do is make it rotate in place (the rotation pivot being the shape's center), although I only managed to make it rotate around an axis (By that I mean it makes a circular motion in the axis specified). 我想做的是使它就位旋转(旋转枢轴是形状的中心),尽管我只设法使其绕轴旋转(因为我是说它在指定的轴上作圆周运动)。
Here's my code: 这是我的代码:
@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);
}
The triangles coordinates are top (0, 0.622, 0), bottom left ( -0.5, -0.311, 0), and bottom right (0.5, -0.311, 0). 三角形的坐标为上(0,0.622,0),左下(-0.5,-0.311、0)和右下(0.5,-0.311、0)。
I tried looking for similar questions or related guides, but none of the answers I found worked for me. 我曾尝试寻找类似的问题或相关指南,但没有找到对我有用的答案。
If so, what is the right way to achieve the result I'm looking for? 如果是这样,什么是达到我想要的结果的正确方法?
Assume you have your object transformation matrix: 假设您有对象转换矩阵:
protected final float[] mTransformMatrix = new float[16];
When you create object you just use Matrix.setIdentityM(mTransformMatrix, 0);
创建对象时,只需使用
Matrix.setIdentityM(mTransformMatrix, 0);
To rotate you need: 要旋转,您需要:
Matrix.rotateM(mTransformMatrix, 0, angle, 0, 0, 1.0f);
Here are some methods for object positioning, sizeing and rotating: 以下是一些用于对象定位,调整大小和旋转的方法:
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;
}
Don't be afraid of returns, that's just a bit of code from my Sprite class 不要害怕返回,这只是我的Sprite类中的一些代码
UtilsGL part: 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;
}
A lot of code down here but it's all useful. 这里有很多代码,但它们都很有用。 Why static?
为什么是静态的? I'm not a OOP geek) I chose to make it simple but functional
我不是OOP怪胎)我选择使其简单但实用
Problem solved! 问题解决了! I can't believe it was something so small!
我简直不敢相信它是如此之小!
The problem was this line: 问题是这一行:
gl_Position = vPosition * uMVPMatrix;
I can't quite explain why (so if someone could - that'd be great!) but when I changed it to: 我无法完全解释原因(如果有人可以,那就太好了!),但是当我将其更改为:
gl_Position = uMVPMatrix * vPosition;
it worked as expected! 它按预期工作!
If someone can further explain why this works instead of the first option, that'd be awesome! 如果有人可以进一步解释为什么它能代替第一个选择起作用,那就太好了! I will of course mark the answer as accepted.
我当然会将答案标记为已接受。
Thanks. 谢谢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.