Advertisement
Guest User

Untitled

a guest
Apr 26th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.68 KB | None | 0 0
  1. import com.jogamp.common.nio.Buffers;
  2. import com.jogamp.opengl.util.Animator;
  3.  
  4. import javax.media.opengl.GL2;
  5. import javax.media.opengl.GL4;
  6. import javax.media.opengl.GLAutoDrawable;
  7. import javax.media.opengl.GLCapabilities;
  8. import javax.media.opengl.GLEventListener;
  9. import javax.media.opengl.GLProfile;
  10. import javax.media.opengl.awt.GLCanvas;
  11. import javax.swing.JFrame;
  12. import javax.swing.SwingUtilities;
  13. import java.awt.BorderLayout;
  14. import java.awt.event.WindowAdapter;
  15. import java.awt.event.WindowEvent;
  16. import java.nio.IntBuffer;
  17.  
  18. public class KaliFractal extends GLCanvas implements GLEventListener{
  19.  
  20. // вершинный шейдер, он выполняется 1 раз для каждой вершины
  21. // соответственно в этой программе 4 вызова на кадр, на выход он должен записать
  22. // положение вершины в диапазоне пространства отсечения. (clipping space)
  23. static final String VS =
  24. "#version 400\n" +
  25. "layout (location = 0) in vec2 VertexPosition;\n" +
  26.  
  27. "void main() {\n" +
  28. " gl_Position = vec4(VertexPosition, 0.0, 1.0);\n" +
  29. "}";
  30.  
  31. // фрагментный шейдер, он выполняется один раз, для кажого пикселя, в который попал рисуемый объект
  32. // в этом примере это все доступное пространство на окне
  33. // на выходе - цвет этого пикселя.
  34. static final String FS =
  35. "#version 400\n" +
  36. "layout (location = 0) out vec4 FragColor;\n" +
  37. "uniform vec2 resolution;\n" +
  38. "uniform float time;\n" +
  39.  
  40. "void main(void) {\n" +
  41. " vec2 t = vec2(1. + cos(time), 1. + sin(time))*123.;" +
  42. " vec2 p = gl_FragCoord.xy;\n" +
  43. " vec2 q = (p + p - resolution.xy) / resolution.x;\n" +
  44. " for(int i = 0; i < 13; i++) {\n" +
  45. " q = abs(q)/dot(q,q) - t.xy/resolution.xy;\n" +
  46. " }\n" +
  47. " FragColor = vec4(q, q.x/q.y, 1.0);\n" +
  48. "}";
  49.  
  50. static float[] UNIT_QUAD = {
  51. -1, -1,
  52. -1, +2,
  53. +1, -1,
  54. +1, +1
  55. };
  56.  
  57. private final long start = System.currentTimeMillis();
  58. private int width;
  59. private int height;
  60. private GL4 gl;
  61. private int programId;
  62. private int vboId;
  63. private int resolutionLocation;
  64. private int timeLocation;
  65.  
  66. KaliFractal() {
  67. super(new GLCapabilities(GLProfile.getDefault()));
  68. addGLEventListener(this);
  69. }
  70.  
  71. public static void main(String[] args) {
  72. KaliFractal fullScreenTriangle = new KaliFractal();
  73.  
  74. Animator animator = new Animator(fullScreenTriangle);
  75. animator.start();
  76.  
  77. JFrame frame = new JFrame();
  78. frame.add(fullScreenTriangle, BorderLayout.CENTER);
  79. frame.setTitle("q = abs(q)/dot(q,q)");
  80. frame.setSize(640, 480);
  81. frame.setLocationRelativeTo(null);
  82. frame.addWindowListener(new WindowAdapter() {
  83. public void windowClosing(WindowEvent e) {
  84. animator.stop();
  85. frame.dispose();
  86. System.exit(0);
  87. }
  88. });
  89. SwingUtilities.invokeLater(() -> frame.setVisible(true));
  90. }
  91.  
  92. @Override
  93. public void init(GLAutoDrawable glAutoDrawable) {
  94. gl = glAutoDrawable.getGL().getGL4();
  95.  
  96. // создаем программу (из 2х шейдеров)
  97. programId = createProgram(VS, FS);
  98.  
  99. // получаем адреса переменных из этой программы
  100. resolutionLocation = getUniformLocation(programId, "resolution");
  101. timeLocation = getUniformLocation(programId, "time");
  102.  
  103. // создаем вершинный буфер, с вершинами описывающими один квадрат на весь экран
  104. vboId = createVertexBufferObject(UNIT_QUAD);
  105. }
  106.  
  107. @Override
  108. public void dispose(GLAutoDrawable glAutoDrawable) {}
  109.  
  110. @Override
  111. public void display(GLAutoDrawable glAutoDrawable) {
  112.  
  113. // включаем программу
  114. gl.glUseProgram(programId);
  115.  
  116. // устанавливаем значения переменных для программы
  117. gl.glUniform2f(resolutionLocation, width, height);
  118. gl.glUniform1f(timeLocation, ((float) (System.currentTimeMillis() - start))/1000f);
  119.  
  120. // привязываем VBO
  121. // тут можно было этого не делать т.к.
  122. // это единственный VBO и он уже был привязан в момент создания
  123. gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vboId);
  124.  
  125. // включаем вершинный буфер номер 0
  126. gl.glEnableVertexAttribArray(0);
  127. // конфигурируем как этот буфер будет считываться
  128. gl.glVertexAttribPointer( 0, 2, GL4.GL_FLOAT, false, 0, 0 );
  129.  
  130. // рисуем 4 вершины
  131. gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, 0, UNIT_QUAD.length);
  132.  
  133. // отключаем вершинный буфер номер 0
  134. gl.glDisableVertexAttribArray(0);
  135.  
  136. // отключаем программу
  137. gl.glUseProgram(0);
  138. }
  139.  
  140. @Override
  141. public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
  142. this.width = width;
  143. this.height = height;
  144. }
  145.  
  146. int createProgram(String vs, String fs) {
  147. int programId = gl.glCreateProgram();
  148. int vertexShader = shader(GL4.GL_VERTEX_SHADER, vs);
  149. int fragmentShader = shader(GL4.GL_FRAGMENT_SHADER, fs);
  150. gl.glAttachShader(programId, vertexShader);
  151. gl.glAttachShader(programId, fragmentShader);
  152. gl.glLinkProgram(programId);
  153.  
  154. // это отладочный код, я его закомментил чтобы было понятно что где
  155. // он выводит ошибки программы
  156.  
  157. // gl.glValidateProgram(programId);
  158. // IntBuffer intBuffer = IntBuffer.allocate(1);
  159. // gl.glGetProgramiv(programId, GL4.GL_LINK_STATUS, intBuffer);
  160. // if (intBuffer.get(0) != GL4.GL_TRUE) {
  161. // if (programId > 0)
  162. // gl.glDeleteProgram(programId);
  163. // if (vertexShader > 0)
  164. // gl.glDeleteShader(vertexShader);
  165. // if (fragmentShader > 0)
  166. // gl.glDeleteShader(fragmentShader);
  167. // throw new IllegalStateException();
  168. // }
  169. return programId;
  170. }
  171.  
  172. int shader(int type, String src) {
  173. int id = gl.glCreateShader(type);
  174. gl.glShaderSource(id, 1, new String[] {src}, null, 0);
  175. gl.glCompileShader(id);
  176. // это отладочный код, я его закомментил чтобы было понятно что где
  177. // он выводит ошибки компиляции шейдера
  178.  
  179. // int status = getIntFromShader(id, GL4.GL_COMPILE_STATUS);
  180. // if (status == 0) {
  181. // int logLength = getIntFromShader(id, GL4.GL_INFO_LOG_LENGTH);
  182. // ByteBuffer infoLog = ByteBuffer.allocate(logLength);
  183. // IntBuffer intValue = IntBuffer.allocate(1);
  184. // gl.glGetShaderInfoLog(id, logLength, intValue, infoLog);
  185. // int actualLength = intValue.get();
  186. // byte[] infoBytes = new byte[actualLength];
  187. // infoLog.get(infoBytes);
  188. // if (id > 0) gl.glDeleteShader(id);
  189. // throw new IllegalStateException(new String(infoBytes));
  190. // }
  191. return id;
  192. }
  193.  
  194. int getIntFromShader(int shaderId, int parameter) {
  195. IntBuffer intValue = IntBuffer.allocate(1);
  196. gl.glGetShaderiv(shaderId, parameter, intValue);
  197. return intValue.get();
  198. }
  199.  
  200. int createVertexBufferObject(float[] vertices) {
  201. int[] id = new int[1];
  202. gl.glGenBuffers(1, id, 0);
  203. gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, id[0]);
  204. gl.glBufferData(GL4.GL_ARRAY_BUFFER,vertices.length * 4,
  205. Buffers.newDirectFloatBuffer(vertices).rewind(),GL4.GL_STATIC_DRAW);
  206. return id[0];
  207. }
  208.  
  209. int getUniformLocation(int programId, String uniformName) {
  210. int id = gl.glGetUniformLocation(programId, uniformName);
  211. if (id == -1)
  212. throw new IllegalStateException(uniformName + " uniform not found");
  213. return id;
  214. }
  215. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement