标签:frame ldo 显示 sso 坐标系 south bundle 技术分享 转换
世界坐标系:
当前绘图坐标系:
其中四种坐标经常要在程序中用到:世界坐标,物体坐标,设备坐标和眼坐标。
1、世界坐标是OpenGL中用来描述场景的坐标,Z+轴垂直屏幕向外,X+从左到右,Y+轴从下到上,是右手笛卡尔坐标系统。我们用这个坐标系来描述物体及光源的位置。
将物体放到场景中也就是将物体平移到特定位置、旋转一定角度,这些操作就是坐标变换。OpenGL中提供了glTranslate*/glRotate*/glScale*三条坐标变换命令,利用OpenGL的矩阵运算命令,则可以实现任意复杂的坐标变换。
OpenGL中有一个坐标变换矩阵栈(ModelView),栈顶就是当前坐标变换矩阵,进入OpenGL管道的每个坐标(齐次坐标)都会先乘上这个矩阵,结果才是对应点在场景中的世界坐标。OpenGL中的坐标变换都是通过矩阵运算完成的,与图形学课本的描述完全一致。要注意的是变换中的矩阵乘法是左乘,而矩阵乘法与算术乘法不同,不符合交换律(万一不明白去看矩阵代数书好了)。
glTranslate*(x,y,z):平移,参数为各轴向的移动量。
2、物体坐标是以物体某一点为原点而建立的“世界坐标”,该坐标系仅对该物体适用,用来简化对物体各部分坐标的描述。物体放到场景中时,各部分经历的坐标变换相同,相对位置不变,所以可视为一个整体,与人类的思维习惯一致。
3、眼坐标是以视点为原点,以视线的方向为Z+轴正方向的坐标系中的方向。OpenGL管道会将世界坐标先变换到眼坐标,然后进行裁剪,只有在视线范围(视见体)之内的场景才会进入下一阶段的计算。同样的,有投影变换矩阵栈(Projection),栈顶矩阵就是当前投影变换矩阵,负责将场景各坐标变换到眼坐标,由所得到的结果是裁剪后的场景部分,称为裁剪坐标。前面提到过的视见体设定其实就是在建立该矩阵。
4、设备坐标:OpenGL 的重要功能之一就是将三维的世界坐标经过变换、投影等计算,最终算出它在显示设备上对应的位置,这个位置就称为设备坐标。在屏幕、打印机等设备上的坐标是二维坐标。值得一提的是,OpenGL可以只使用设备的一部分进行绘制,这个部分称为视区或视口(viewport)。投影得到的是视区内的坐标(投影坐标),从投影坐标到设备坐标的计算过程就是设备变换了。
package com.example.hejunlin.openglcoordinate;
import android.opengl.GLSurfaceView;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private GLSurfaceView mSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSurfaceView = new GLSurfaceView(this);
mSurfaceView.setRenderer(new MyGLRenderer());
setContentView(mSurfaceView);
}
@Override
protected void onResume() {
super.onResume();
mSurfaceView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mSurfaceView.onPause();
}
}
Renderer
package com.example.hejunlin.openglcoordinate;
import android.opengl.GLES31;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.Matrix;
import android.util.Log;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by hejunlin on 2017/3/13.
*/
public class MyGLRenderer implements GLSurfaceView.Renderer {
private Coordinate coordinate;
private float mAngle = 45;
public MyGLRenderer() {
coordinate = new Coordinate();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(255.0f, 255.0f, 255.0f, 1.0f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glDisable(GL10.GL_DITHER);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (height == 0) {
height = 1;
}
float aspect = (float) width / height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void onDrawFrame(GL10 gl) {
Log.d("AAA" , ">> onDrawFrame mAngle " + mAngle);
// 画背景颜色
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT | GLES31.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.3f, -2.0f);
mAngle ++;
// gl.glRotatef(mAngle,1.0f,1.0f,1.0f);
coordinate.draw(gl);
}
}
Coordinate
package com.example.hejunlin.openglcoordinate;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by hejunlin on 2017/3/13.
*/
public class Coordinate {
private FloatBuffer vertexsBuffer;
private FloatBuffer colorsBuffer;
private ByteBuffer indicesBuffer;
private float vertexs[] = {
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f
};
private float colors[] = {
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f
};
private byte indices[] = {0, 1, 2};
public Coordinate() {
ByteBuffer vbb = ByteBuffer.allocateDirect(vertexs.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexsBuffer = vbb.asFloatBuffer();
vertexsBuffer.put(vertexs);
vertexsBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
colorsBuffer = cbb.asFloatBuffer();
colorsBuffer.put(colors);
colorsBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexsBuffer);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorsBuffer);
gl.glLineWidth(9);
gl.glDrawArrays(GL10.GL_LINES, 0, vertexs.length / 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
通过变换 gl.glTranslatef(0.0f, 0.3f, -2.0f)中,前两个参数,来看下变换后效果。
下图坐标:(0.0f, 0.0f, -2.0f)
参数说明:
x,y,z:分别指定沿x,y,z轴方向的平移分量。
重点就是沿着x,y,z轴移动。
注意在glTranslatef(x, y, z)中,当您移动的时候,您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。
其作用就是将你绘点坐标的原点在当前原点的基础上平移一个(x,y,z)向量。
关于 OpenGL坐标系之间的转换,可参考
http://blog.csdn.net/sac761/article/details/52179585
OpenGL ES总结(二)OpenGL坐标变换之平移及旋转
标签:frame ldo 显示 sso 坐标系 south bundle 技术分享 转换
原文地址:http://blog.csdn.net/hejjunlin/article/details/61926245