Name
glFrustumf
, glFrustumx
- multiply the current matrix by a perspective matrixC Specification
void glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far) void glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed near, GLfixed far)
Parameters
left
,right
- Specify the coordinates for the left and right vertical clipping planes.
bottom
,top
- Specify the coordinates for the bottom and top horizontal clipping planes.
near
,far
- Specify the distances to the near and far depth clipping planes. Both distances must be positive.
Description
glFrustum
describes a perspective matrix that produces a perspective projection. The current matrix (see glMatrixMode
) is multiplied by this matrix and the result replaces the current matrix, as if glMultMatrix
were called with the following matrix as its argument:( |
| ) |
A = - (right + left)/(right - left) |
B = - (top + bottom)/(top - bottom) |
C = - (far + near)/(far - near) |
D = - 2farnear/(far - near) |
GL_PROJECTION
, and (left
, bottom
, -near
) and (right
, top
, -near
) specify the points on the near clipping plane that are mapped to the lower left and upper right corners of the window, assuming that the eye is located at (0, 0, 0). -far
specifies the location of the far clipping plane. Both near
and far
must be positive.Use
glPushMatrix
and glPopMatrix
to save and restore the current matrix stack.Notes
Depth buffer precision is affected by the values specified fornear
and far
. The greater the ratio of far
to near
is, the less effective the depth buffer will be at distinguishing between surfaces that are near each other. Ifr = far/near |
near
approaches 0, near
must never be set to 0.Errors
GL_INVALID_VALUE
is generated if near
or far
is not positive, or if left
= right
, or bottom
= top
.Copyright
Copyright © 2003 Silicon Graphics, Inc.This document is licensed under the SGI Free Software B License. For details, see http://oss.sgi.com/projects/FreeB/.
See Also
glOrtho
, glMatrixMode
, glMultMatrix
, glPushMatrix
, glViewport
Example
package com.minkandroid.ui.sample.work;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import com.minkandroid.ui.sample.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
class COpenGLRenderTest implements GLSurfaceView.Renderer {
public class TestRect
{
private IntBuffer mVertexBuffer;
private IntBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
private FloatBuffer mTexBuffer;
public TestRect()
{
int one = 0x40000;
int vertices[] = {
-one, one, one/4, //0
one, one, one/4, //1
one, -one, one/4,//2
-one, -one, one/4//3
};
// int one = 1;
// int vertices[] = {
// -one, one, 0, //0
// one, one, 0, //1
// one, -one, 0,//2
// -one, -one, 0//3
// };
/**
* 버텍스가 반시계방향이건 아니건 그냥 버텍스와 텍스쳐는 그냥 매핑된다.
* 하지만 원이미지와 화면은 상하 반전해야한다.
* V --> Texture
* 0--1 3--2
* | | | |
* 3--2 0--1
*/
float verticesTex[] = {
(float)0, (float)0,
(float)1, (float)0,
(float)1, (float)1,
(float)0, (float)1
};
// int colors[] = {
// 0, 0, 0, one,
// one, 0, 0, one,
// one, one, 0, one,
// 0, one, 0, one
// };
int colors[] = {
0, 0, 0, 0x1000,
0x1000, 0, 0, 0x1000,
0x1000, 0x1000, 0, 0x1000,
0, 0x1000, 0, 0x1000
};
byte indices[] = {
0, 1, 3, 1, 2, 3
};
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asIntBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0);
ByteBuffer fbb = ByteBuffer.allocateDirect(verticesTex.length*4);
fbb.order(ByteOrder.nativeOrder());
mTexBuffer = fbb.asFloatBuffer();
mTexBuffer.put(verticesTex);
mTexBuffer.position(0);
}
public void draw(GL10 gl)
{
//시계방향으로 감기
gl.glFrontFace(GL10.GL_CW);
// which one should NOT be drawn
//gl.glCullFace(GL10.GL_BACK);
//3: 배열의 3개씩 읽어온다.
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
//4: 배열의 4개씩 읽어온다.
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
//삼각형형태로 그린다. 6:인덱스의수
gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
}
}
TestRect m_rtTest;
int[] m_texturesID;
Context m_context;
public COpenGLRenderTest(Context context)
{
m_rtTest = new TestRect();
m_context = context;
}
@Override
public void onDrawFrame(GL10 gl)
{
//텍스쳐지원
//gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_MODULATE);
//화면을 클리어한다. (컬러와 Depth를 클리어 한다)
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW); //투영을 위한 행렬을 정의 한다.
gl.glLoadIdentity(); //좌표계 초기화를 한다.
gl.glTranslatef(0, 0, -2.0f); //이동
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //정점 Array를 사용할 수 있게 선언한다.
gl.glEnableClientState(GL10.GL_COLOR_ARRAY); //Color Array를 사용할 수 있게 선언한다.
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, m_texturesID[0]);
//gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);
//gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);
m_rtTest.draw(gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height); //뷰포트를 정의 한다.
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION); //투영을 위한 행렬을 정의 한다.
gl.glLoadIdentity(); //좌표계 초기화를 한다.
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); //투영을 비율을 정의 한다. 1:화면비율(w/h)
float diam = 8;
float zNear = 10.f;
float zFar = zNear + diam;
int cx = 0, cy = 0;
float left = cx - diam;
float right = cx + diam;
float bottom = cy - diam;
float top = cy + diam;
if ( ratio < 1.0 ) { // window taller than wide
bottom /= ratio;
top /= ratio;
} else {
left *= ratio;
right *= ratio;
}
//Z 축으로 세모가 나열되어 있다고 가정하여 앞에서 바라 봤을 경우 재일 앞 세모만 보인다.
gl.glOrthof(left, right, bottom, top, zNear, zFar);
//Z 축으로 세모가 나열되어 있다고 가정하여 앞에서 바라 봤을 경우, Z축으로 작아지면서 나열되는 세모들이 보인다.
// gl.glFrustumf(left, right, bottom, top, -zNear, zFar);
//gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); //투영을 비율을 정의 한다. 1:화면비율(w/h)
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
gl.glDisable(GL10.GL_DITHER); //움직임 효과를 빠르게 해준다. (흔들림)을 꺼둔다.
//드라이버에 원근보정을 가장 빠르게 요청한다. 하드웨어에 따라서 달라진다.
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
gl.glClearColor(.5f, .5f, .5f, 1);
gl.glEnable(GL10.GL_CULL_FACE); //폴리곤 추려 내기.
gl.glShadeModel(GL10.GL_SMOOTH);
//물체를 하나 그리고 그 앞쪽으로 물체를 하나 더 그리면 처음에 그렸던 물체에 나중에 그린 물체가 가리는 현상이 생길 수 있는다.
gl.glEnable(GL10.GL_DEPTH_TEST);
//텟스쳐 맵정의를 한다.
gl.glEnable(GL10.GL_TEXTURE_2D);
//테스처를 특정 별명을 붙혀준다.
m_texturesID = new int[1];
gl.glGenTextures(1, m_texturesID, 0);
//그 별명에 텟스처를 바인드한다.
gl.glBindTexture(GL10.GL_TEXTURE_2D, m_texturesID[0]);
//축소시 가장가까운 픽셀을 참조하여 축소를 한다.
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
//확대시 선형으로 확대를 하여 고르게 한다.
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_REPLACE 텍스처를 물체에 입힌다.
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_REPLACE);
InputStream is = m_context.getResources().openRawResource(R.drawable.test_doc);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(is);
}
finally
{
try
{
is.close();
}
catch(IOException e)
{
// Ignore.
}
}
//텍스쳐를 읽어들인다.
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
}