我开始在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)。
我尝试寻找类似的问题或相关指南,但我找到的答案都没有为我工作。
如果是这样,实现我正在寻找的结果的正确方法是什么?
答案 0 :(得分:1)
假设您有对象转换矩阵:
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极客)我选择让它变得简单但功能齐全
答案 1 :(得分:1)
问题解决了! 我简直不敢相信这么小!
问题在于这一行:
gl_Position = vPosition * uMVPMatrix;
我无法解释为什么(所以如果有人可以 - 那就太好了!)但是当我把它改为:
gl_Position = uMVPMatrix * vPosition;
它按预期工作了!
如果有人能够进一步解释为什么这样做而不是第一个选项,那就太棒了!我当然会将答案标记为已接受。
感谢。