Guest User

Untitled

a guest
Jan 26th, 2014
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.89 KB | None | 0 0
  1. import com.jogamp.opengl.util.FPSAnimator;
  2.  
  3. import javax.media.opengl.*;
  4. import javax.media.opengl.awt.GLCanvas;
  5. import javax.media.opengl.glu.GLU;
  6. import java.awt.*;
  7. import java.awt.event.WindowAdapter;
  8. import java.awt.event.WindowEvent;
  9. import java.nio.FloatBuffer;
  10. import java.nio.IntBuffer;
  11.  
  12. public class JOGL2ShadowAgony implements GLEventListener {
  13.     private IntBuffer DepthTex;
  14.     private int DepthTexSize = 512,
  15.             WinXSize = 640, WinYSize = 480;
  16.     private FloatBuffer PS, PT, PR, PQ;
  17.     private GLU glu;
  18.  
  19.     private GLProfile glp;
  20.     private GLCapabilities caps;
  21.     private GLCanvas canvas;
  22.     private Frame frame;
  23.     private FPSAnimator animator;
  24.  
  25.     public JOGL2ShadowAgony() {
  26.         PS = FloatBuffer.allocate(4);
  27.         PS.put(new float[]{1, 0, 0, 0});
  28.         PT = FloatBuffer.allocate(4);
  29.         PT.put(new float[]{0, 1, 0, 0});
  30.         PR = FloatBuffer.allocate(4);
  31.         PR.put(new float[]{0, 0, 1, 0});
  32.         PQ = FloatBuffer.allocate(4);
  33.         PQ.put(new float[]{0, 0, 0, 1});
  34.  
  35.         DepthTex = IntBuffer.allocate(DepthTexSize);
  36.  
  37.         GLProfile.initSingleton();
  38.  
  39.         glp = GLProfile.get(GLProfile.GL2);
  40.         caps = new GLCapabilities(glp);
  41.         canvas = new GLCanvas(caps);
  42.         canvas.addGLEventListener(this);
  43.  
  44.         frame = new Frame("JOGL2ShadowAgony");
  45.         frame.add(canvas);
  46.         frame.setSize(640, 480);
  47.  
  48.         animator = new FPSAnimator(canvas, 60);
  49.  
  50.         frame.addWindowListener(new WindowAdapter() {
  51.             public void windowClosing(WindowEvent e) {
  52.                 new Thread(new Runnable() {
  53.                     public void run() {
  54.                         animator.stop();
  55.                         System.exit(0);
  56.                     }
  57.                 }).start();
  58.             }
  59.         });
  60.  
  61.         frame.setVisible(true);
  62.         animator.start();
  63.     }
  64.  
  65.     public static void main(String[] args) {
  66.         new JOGL2ShadowAgony();
  67.     }
  68.  
  69.     public void init(GLAutoDrawable drawable) {
  70.         GL2 gl = drawable.getGL().getGL2();
  71.         glu = new GLU();
  72.         startInit(gl);
  73.     }
  74.  
  75.     public void reshape(GLAutoDrawable drawable, int x, int y, int width,
  76.                         int height) {
  77.         GL2 gl = drawable.getGL().getGL2();
  78.         if (height == 0) {
  79.             height = 1;
  80.         }
  81.  
  82.         float aspect = (float) width / (float) height;
  83.  
  84.         gl.glMatrixMode(GL2.GL_PROJECTION);
  85.         gl.glLoadIdentity();
  86.  
  87.         glu.gluPerspective(45.0f, aspect, 0.1f, 100.0f);
  88.  
  89.         gl.glMatrixMode(GL2.GL_MODELVIEW);
  90.         gl.glLoadIdentity();
  91.     }
  92.  
  93.     public void display(GLAutoDrawable drawable) {
  94.         GL2 gl = drawable.getGL().getGL2();
  95.  
  96.         pass1(gl);
  97.         pass2(gl);
  98.  
  99.     }
  100.  
  101.     public void dispose(GLAutoDrawable drawable) {
  102.     }
  103.  
  104.     private void startInit(GL2 gl) {
  105. //        Теперь нужно создать текстуру, в которой будет содержаться информация о глубине сцены (depth map). Для этого в OpenGL существует расширение ARB_depth_texture. В нем вводятся новые внутренние форматы текстуры GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24_ARB,
  106. //        GL_DEPTH_COMPONENT32_ARB.
  107.         gl.glGenTextures(1, DepthTex);
  108.         gl.glCopyTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 0, 0,
  109.                 DepthTexSize, DepthTexSize, 0);
  110.  
  111. //        Ставим фильтрацию и клампинг:
  112.         gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
  113.         gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
  114.         gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);
  115.         gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);
  116.  
  117.         gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE);
  118.  
  119. //        Если depth-текстуру мы будем использовать как обычную, пусть данные трактуются как яркость:
  120.         gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_LUMINANCE);
  121.  
  122. //        Устанавливаем режим текстуры для сравнения по Z. Z из текстуры сравнивается
  123. //        с текстурной координатой R (Z фрагмента в базисе источника света) - для этого нужно наличие расширения GL_ARB_shadow. Если указанное сравнение (GL_LEQUAL в нашем случае) не проходит, результат будет GL_TEXTURE_COMPARE_FAIL_VALUE, иначе 1:
  124.  
  125.         gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_COMPARE_MODE, GL2.GL_COMPARE_R_TO_TEXTURE);
  126.         gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_COMPARE_FUNC, GL2.GL_LEQUAL);
  127.         gl.glTexParameterf(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.5f);
  128. //        Если расширение GL_ARB_texture_ambient не поддерживается, то, когда сравнение не проходит, результатом будет 0.
  129.  
  130. //        Затем устанавливаем генерацию текстурных координат:
  131.  
  132.         gl.glTexGeni(GL2.GL_S, GL2.GL_EYE_LINEAR, GL2.GL_REFLECTION_MAP);
  133.         gl.glTexGeni(GL2.GL_T, GL2.GL_EYE_LINEAR, GL2.GL_REFLECTION_MAP);
  134.         gl.glTexGeni(GL2.GL_R, GL2.GL_EYE_LINEAR, GL2.GL_REFLECTION_MAP);
  135.         gl.glTexGeni(GL2.GL_Q, GL2.GL_EYE_LINEAR, GL2.GL_REFLECTION_MAP);
  136. //        Устанавливаем z-bias:
  137.  
  138.         gl.glPolygonOffset(4, 4);
  139. //        Зачем нужен z-bias? Так как точность z-буфера не бесконечна, могут возникать ошибки сравнения, из-за этого будут затеняться точки, которые быть затененными не должны. Смещением глубины полигонов в первом проходе мы как бы сдвигаем точки ближе к наблюдателю, чтобы избежать артефактов z-fighting'а.
  140.     }
  141.  
  142.     private void pass1(GL2 gl) {
  143. //        За первый проход мы рендерим сцену с позиции источника света, и заносим depth map в текстуру. При рендеринге запрещаем запись цвета, наложение текстур, так как они нам не нужны:
  144.  
  145.         gl.glViewport(0, 0, DepthTexSize, DepthTexSize);
  146.  
  147.         // устанавливаем матрицы
  148.  
  149.         gl.glMatrixMode(GL2.GL_PROJECTION);
  150.         gl.glLoadIdentity();
  151.         SetLightProjection();
  152.         gl.glMatrixMode(GL2.GL_MODELVIEW);
  153.         gl.glLoadIdentity();
  154.         SetLightModelview(gl);
  155.  
  156.         // подготовка и рендеринг сцены
  157.  
  158.         gl.glDisable(GL2.GL_TEXTURE_2D);
  159.         gl.glColorMask(false, false, false, false); // запрещаем запись цвета
  160.         gl.glEnable(GL2.GL_POLYGON_OFFSET_FILL); // разрешаем z-bias
  161.         DoRenderScene(gl);
  162.         gl.glCopyTexSubImage2D(GL2.GL_TEXTURE_2D, 0, 0, 0, 0, 0, DepthTexSize, DepthTexSize);
  163.         gl.glColorMask(true, true, true, true); // разрешаем запись цвета
  164.         gl.glDisable(GL2.GL_POLYGON_OFFSET_FILL);
  165.     }
  166.  
  167.     private void pass2(GL2 gl) {
  168. //        За второй проход рендерим сцену с позиции камеры, включив автоматическую генерацию текстурных координат. В текстурной матрице содержится проекционная и модельная матрицы источника света:
  169.         // устанавливаем матрицы
  170.         gl.glViewport(0, 0, WinXSize, WinYSize);
  171.         gl.glMatrixMode(GL2.GL_PROJECTION);
  172.         gl.glLoadIdentity();
  173.         SetCameraProjection();
  174.         gl.glMatrixMode(GL2.GL_MODELVIEW);
  175.         gl.glLoadIdentity();
  176.         SetCameraModelview(gl);
  177.  
  178.         // подготовка и рендеринг сцены
  179.  
  180.         gl.glEnable(GL2.GL_TEXTURE_2D);
  181.         // Устанавливаем плоскости для генерации текстурных координат
  182.         gl.glTexGenfv(GL2.GL_S, GL2.GL_EYE_PLANE, PS);
  183.         gl.glTexGenfv(GL2.GL_T, GL2.GL_EYE_PLANE, PT);
  184.         gl.glTexGenfv(GL2.GL_R, GL2.GL_EYE_PLANE, PR);
  185.         gl.glTexGenfv(GL2.GL_Q, GL2.GL_EYE_PLANE, PQ);
  186.  
  187.         // Устанавливаем текстурную матрицу
  188.         gl.glMatrixMode(GL2.GL_TEXTURE);
  189.         gl.glLoadIdentity();
  190.         // Ставим texture bias, т.е. [-1, 1] -> [0, 1]
  191.         gl.glTranslatef(0.5f, 0.5f, 0.5f);
  192.         gl.glScalef(0.5f, 0.5f, 0.5f);
  193.         // Положение и проекция источника света
  194.         SetLightProjection();
  195.         SetLightModelview(gl);
  196.         gl.glMatrixMode(GL2.GL_MODELVIEW);
  197.  
  198.         // Рендерим геометрию
  199.         DoRenderScene(gl);
  200.     }
  201.  
  202.     private void SetLightProjection() {
  203.         glu.gluPerspective(90, DepthTexSize / DepthTexSize, 1, 500);
  204.     }
  205.  
  206.     private void SetLightModelview(GL2 gl) {
  207.         gl.glTranslatef(0, 0, -10);
  208.     }
  209.  
  210.     private void SetCameraProjection() {
  211.         glu.gluPerspective(90, WinXSize / WinYSize, 1, 500);
  212.     }
  213.  
  214.     private void SetCameraModelview(GL2 gl) {
  215.         gl.glTranslatef(0, -10, -10);
  216.         gl.glRotatef(60, 1, 0, 0);
  217.     }
  218.  
  219.     private void DoRenderScene(GL2 gl) {
  220.         gl.glBegin(GL2.GL_QUADS);
  221.  
  222.         gl.glVertex3f(-1.0f, -1.0f, 2.0f);
  223.         gl.glVertex3f(1.0f, -1.0f, 0.0f);
  224.         gl.glVertex3f(1.0f, 1.0f, 0.0f);
  225.         gl.glVertex3f(-1.0f, 1.0f, 2.0f);
  226.  
  227.         gl.glEnd();
  228.     }
  229. }
Advertisement
Add Comment
Please, Sign In to add comment