Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import com.jogamp.common.nio.Buffers;
- import com.jogamp.opengl.util.Animator;
- import javax.media.opengl.GL2;
- import javax.media.opengl.GL4;
- import javax.media.opengl.GLAutoDrawable;
- import javax.media.opengl.GLCapabilities;
- import javax.media.opengl.GLEventListener;
- import javax.media.opengl.GLProfile;
- import javax.media.opengl.awt.GLCanvas;
- import javax.swing.JFrame;
- import javax.swing.SwingUtilities;
- import java.awt.BorderLayout;
- import java.awt.event.WindowAdapter;
- import java.awt.event.WindowEvent;
- import java.nio.IntBuffer;
- public class KaliFractal extends GLCanvas implements GLEventListener{
- // вершинный шейдер, он выполняется 1 раз для каждой вершины
- // соответственно в этой программе 4 вызова на кадр, на выход он должен записать
- // положение вершины в диапазоне пространства отсечения. (clipping space)
- static final String VS =
- "#version 400\n" +
- "layout (location = 0) in vec2 VertexPosition;\n" +
- "void main() {\n" +
- " gl_Position = vec4(VertexPosition, 0.0, 1.0);\n" +
- "}";
- // фрагментный шейдер, он выполняется один раз, для кажого пикселя, в который попал рисуемый объект
- // в этом примере это все доступное пространство на окне
- // на выходе - цвет этого пикселя.
- static final String FS =
- "#version 400\n" +
- "layout (location = 0) out vec4 FragColor;\n" +
- "uniform vec2 resolution;\n" +
- "uniform float time;\n" +
- "void main(void) {\n" +
- " vec2 t = vec2(1. + cos(time), 1. + sin(time))*123.;" +
- " vec2 p = gl_FragCoord.xy;\n" +
- " vec2 q = (p + p - resolution.xy) / resolution.x;\n" +
- " for(int i = 0; i < 13; i++) {\n" +
- " q = abs(q)/dot(q,q) - t.xy/resolution.xy;\n" +
- " }\n" +
- " FragColor = vec4(q, q.x/q.y, 1.0);\n" +
- "}";
- static float[] UNIT_QUAD = {
- -1, -1,
- -1, +2,
- +1, -1,
- +1, +1
- };
- private final long start = System.currentTimeMillis();
- private int width;
- private int height;
- private GL4 gl;
- private int programId;
- private int vboId;
- private int resolutionLocation;
- private int timeLocation;
- KaliFractal() {
- super(new GLCapabilities(GLProfile.getDefault()));
- addGLEventListener(this);
- }
- public static void main(String[] args) {
- KaliFractal fullScreenTriangle = new KaliFractal();
- Animator animator = new Animator(fullScreenTriangle);
- animator.start();
- JFrame frame = new JFrame();
- frame.add(fullScreenTriangle, BorderLayout.CENTER);
- frame.setTitle("q = abs(q)/dot(q,q)");
- frame.setSize(640, 480);
- frame.setLocationRelativeTo(null);
- frame.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- animator.stop();
- frame.dispose();
- System.exit(0);
- }
- });
- SwingUtilities.invokeLater(() -> frame.setVisible(true));
- }
- @Override
- public void init(GLAutoDrawable glAutoDrawable) {
- gl = glAutoDrawable.getGL().getGL4();
- // создаем программу (из 2х шейдеров)
- programId = createProgram(VS, FS);
- // получаем адреса переменных из этой программы
- resolutionLocation = getUniformLocation(programId, "resolution");
- timeLocation = getUniformLocation(programId, "time");
- // создаем вершинный буфер, с вершинами описывающими один квадрат на весь экран
- vboId = createVertexBufferObject(UNIT_QUAD);
- }
- @Override
- public void dispose(GLAutoDrawable glAutoDrawable) {}
- @Override
- public void display(GLAutoDrawable glAutoDrawable) {
- // включаем программу
- gl.glUseProgram(programId);
- // устанавливаем значения переменных для программы
- gl.glUniform2f(resolutionLocation, width, height);
- gl.glUniform1f(timeLocation, ((float) (System.currentTimeMillis() - start))/1000f);
- // привязываем VBO
- // тут можно было этого не делать т.к.
- // это единственный VBO и он уже был привязан в момент создания
- gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vboId);
- // включаем вершинный буфер номер 0
- gl.glEnableVertexAttribArray(0);
- // конфигурируем как этот буфер будет считываться
- gl.glVertexAttribPointer( 0, 2, GL4.GL_FLOAT, false, 0, 0 );
- // рисуем 4 вершины
- gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, 0, UNIT_QUAD.length);
- // отключаем вершинный буфер номер 0
- gl.glDisableVertexAttribArray(0);
- // отключаем программу
- gl.glUseProgram(0);
- }
- @Override
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- this.width = width;
- this.height = height;
- }
- int createProgram(String vs, String fs) {
- int programId = gl.glCreateProgram();
- int vertexShader = shader(GL4.GL_VERTEX_SHADER, vs);
- int fragmentShader = shader(GL4.GL_FRAGMENT_SHADER, fs);
- gl.glAttachShader(programId, vertexShader);
- gl.glAttachShader(programId, fragmentShader);
- gl.glLinkProgram(programId);
- // это отладочный код, я его закомментил чтобы было понятно что где
- // он выводит ошибки программы
- // gl.glValidateProgram(programId);
- // IntBuffer intBuffer = IntBuffer.allocate(1);
- // gl.glGetProgramiv(programId, GL4.GL_LINK_STATUS, intBuffer);
- // if (intBuffer.get(0) != GL4.GL_TRUE) {
- // if (programId > 0)
- // gl.glDeleteProgram(programId);
- // if (vertexShader > 0)
- // gl.glDeleteShader(vertexShader);
- // if (fragmentShader > 0)
- // gl.glDeleteShader(fragmentShader);
- // throw new IllegalStateException();
- // }
- return programId;
- }
- int shader(int type, String src) {
- int id = gl.glCreateShader(type);
- gl.glShaderSource(id, 1, new String[] {src}, null, 0);
- gl.glCompileShader(id);
- // это отладочный код, я его закомментил чтобы было понятно что где
- // он выводит ошибки компиляции шейдера
- // int status = getIntFromShader(id, GL4.GL_COMPILE_STATUS);
- // if (status == 0) {
- // int logLength = getIntFromShader(id, GL4.GL_INFO_LOG_LENGTH);
- // ByteBuffer infoLog = ByteBuffer.allocate(logLength);
- // IntBuffer intValue = IntBuffer.allocate(1);
- // gl.glGetShaderInfoLog(id, logLength, intValue, infoLog);
- // int actualLength = intValue.get();
- // byte[] infoBytes = new byte[actualLength];
- // infoLog.get(infoBytes);
- // if (id > 0) gl.glDeleteShader(id);
- // throw new IllegalStateException(new String(infoBytes));
- // }
- return id;
- }
- int getIntFromShader(int shaderId, int parameter) {
- IntBuffer intValue = IntBuffer.allocate(1);
- gl.glGetShaderiv(shaderId, parameter, intValue);
- return intValue.get();
- }
- int createVertexBufferObject(float[] vertices) {
- int[] id = new int[1];
- gl.glGenBuffers(1, id, 0);
- gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, id[0]);
- gl.glBufferData(GL4.GL_ARRAY_BUFFER,vertices.length * 4,
- Buffers.newDirectFloatBuffer(vertices).rewind(),GL4.GL_STATIC_DRAW);
- return id[0];
- }
- int getUniformLocation(int programId, String uniformName) {
- int id = gl.glGetUniformLocation(programId, uniformName);
- if (id == -1)
- throw new IllegalStateException(uniformName + " uniform not found");
- return id;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement