Thursday, May 26, 2011

glFrustumf example java c c++ objc

Name

glFrustumf , glFrustumx - multiply the current matrix by a perspective matrix

C 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:
(
2/(right - left) 0 A 0
0 2/(top - bottom) B 0
0 0 C D
0 0 -1 0
)
where
A = - (right + left)/(right - left)
B = - (top + bottom)/(top - bottom)
C = - (far + near)/(far - near)
D = - 2farnear/(far - near)
Typically, the matrix mode is 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 for near 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. If
r = far/near
roughly log2(r) bits of depth buffer precision are lost. Because r approaches infinity as 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();
}

}