0

So im working on a Java/Jogl application that basically just translates the vertices of a triangle. So far I am able to get the triangle to move left to right, but I cant figure out how to edit the vertex shader so that when I click a button, the triangle begins to move up and down instead of left and right.

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.nio.*;
import javax.swing.*;
import static com.jogamp.opengl.GL4.*;

import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.FPSAnimator;
import graphicslib3D.GLSLUtils;

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.Vector;

public class a1 extends JFrame implements GLEventListener
{   
    private GLCanvas myCanvas;
    private int rendering_program;
    private int vao[] = new int[1];
    private GLSLUtils util = new GLSLUtils();
    private Button button1, button2;

    private float x = 0.0f;
    private float y = 0.0f;
    private float inc = 0.01f;
    private float incy = 0.01f;
    private int click = 1;

public a1()
{   setTitle("Chapter2 - program2");
    setSize(600, 400);
    myCanvas = new GLCanvas();
    myCanvas.addGLEventListener(this);
    getContentPane().setLayout(new BorderLayout());
    getContentPane().add(myCanvas, BorderLayout.CENTER);

    JPanel sidePanel = new JPanel();
    sidePanel.setLayout(new BoxLayout(sidePanel, BoxLayout.Y_AXIS));
    button1 = new Button("button");
    button2 = new Button("button2");
    sidePanel.add(button1);
    sidePanel.add(button2);
    getContentPane().add(sidePanel, BorderLayout.WEST);

    button2.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            click = 1;

        }
    });

    setVisible(true);
    FPSAnimator animator = new FPSAnimator(myCanvas, 30);
    animator.start();
}

public void display(GLAutoDrawable drawable)
{   GL4 gl = (GL4) GLContext.getCurrentGL();
    gl.glUseProgram(rendering_program);
    gl.glPointSize(50.0f);

    float bkg[] = {0.0f, 0.0f, 0.0f, 1.0f};
    FloatBuffer bkgBuffer = Buffers.newDirectFloatBuffer(bkg);
    gl.glClearBufferfv(GL_COLOR, 0, bkgBuffer);

    x+=inc;
    y+=incy;
    if(x > 1.0f) inc = -0.01f;
    if(x < -1.0f) inc = 0.01f;

    if(y > 1.0f) incy = -0.01f;
    if(y< -1.0f) incy = 0.01f;


    int offset_loc = gl.glGetUniformLocation(rendering_program, "inc");
    int offset_y = gl.glGetUniformLocation(rendering_program, "incy");
    int flag = gl.glGetUniformLocation(rendering_program, "flag");

    gl.glProgramUniform1f(rendering_program, offset_loc, x);
    gl.glProgramUniform1f(rendering_program, offset_y, y);
    gl.glProgramUniform1f(rendering_program, flag, click);
    gl.glDrawArrays(GL_TRIANGLES,0,3);
}


public void init(GLAutoDrawable drawable)
{   GL4 gl = (GL4) GLContext.getCurrentGL();
    rendering_program = createShaderProgram();
    gl.glGenVertexArrays(vao.length, vao, 0);
    gl.glBindVertexArray(vao[0]);
}

private int createShaderProgram()
{
    GL4 gl = (GL4) GLContext.getCurrentGL();
    int[] vertCompiled = new int[1];
    int[] fragCompiled = new int[1];
    int[] linked = new int[1];

    String vshaderSource[] = readShaderSource("src/vert.shader");
    String fshaderSource[] = readShaderSource("src/frag.shader");

    int vShader = gl.glCreateShader(GL_VERTEX_SHADER);
    gl.glShaderSource(vShader, vshaderSource.length, vshaderSource, null, 0);
    gl.glCompileShader(vShader);

    util.checkOpenGLError();
    gl.glGetShaderiv(vShader, GL_COMPILE_STATUS, vertCompiled, 0);
    if(vertCompiled[0] == 1)
    {
        System.out.println("vertex compilation success");
    }else{
        System.out.println("vertex compilation failed");
        util.printShaderLog(vShader);
    }
    int fShader = gl.glCreateShader(GL_FRAGMENT_SHADER);
    gl.glShaderSource(fShader, fshaderSource.length, fshaderSource, null, 0);
    gl.glCompileShader(fShader);

    util.checkOpenGLError();
    gl.glGetShaderiv(fShader, GL_COMPILE_STATUS, fragCompiled, 0);
    if(fragCompiled[0] == 1)
    {
        System.out.println("fragment compilation success");
    }else{
        System.out.println("fragment compilation failed");
        util.printShaderLog(fShader);
    }

    int vfprogram = gl.glCreateProgram();
    gl.glAttachShader(vfprogram, vShader);
    gl.glAttachShader(vfprogram, fShader);
    gl.glLinkProgram(vfprogram);

    util.checkOpenGLError();
    gl.glGetProgramiv(vfprogram, GL_LINK_STATUS, linked, 0);
    if(linked[0] == 1)
    {
        System.out.println("linking succeeded");
    }else{
        System.out.println("linking failed");
        util.printProgramLog(vfprogram);
    }
    //gl.glDeleteShader(vShader);
    //gl.glDeleteShader(fShader);
    return vfprogram;
}

public static void main(String[] args) { new a1(); }
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
public void dispose(GLAutoDrawable drawable) {}

private String[] readShaderSource(String filename)
{
    Vector<String> lines = new Vector<String>();
    Scanner sc;
    try
    {
        sc = new Scanner(new File(filename));
    }catch (IOException e)
    {
        System.err.println("IOException reading file: " + e);
        return null;
    }
    while(sc.hasNext())
    {
        lines.addElement(sc.nextLine());
    }
    String[] program = new String[lines.size()];
    for(int i=0; i<lines.size(); i++)
    {
        program[i] = (String) lines.elementAt(i)+ "\n";
    }
    return program;
}
}

#version 430
uniform float inc;
void main(void)
{

  if(gl_VertexID == 0) gl_Position = vec4(0.25, -0.25+inc, 0.0, 1.0);
  else if(gl_VertexID == 1) gl_Position = vec4(-0.25, -0.25+inc, 0.0, 1.0);
  else gl_Position = vec4(0.25, 0.25+inc, 0.0, 1.0);

}

How do I edit my vertex shader so that when I click on a button the location of the vertices changes and the triangle begins to move up and down instead of left to right?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Anony
  • 13
  • 1
  • Okay. What's your question? I don't see any question marks in your post. – user253751 Sep 09 '16 at 03:36
  • My question is, how do I edit my vertex shader so that when I click on a button the location of the vertices changes and the triangle begins to move up and down instead of left to right? – Anony Sep 09 '16 at 03:39
  • Vertex shaders don't know about buttons, so you can't do that just by changing the vertex shader. – user253751 Sep 09 '16 at 03:54
  • (It's like asking "how should I edit my diet so I get fit?" - you *can* get fit, but changing your diet is only part of it; *only* changing your diet won't make you fit) – user253751 Sep 09 '16 at 03:55

1 Answers1

2

1) Don't do the update like that

2) Don't use an int array for the OpenGL resources (vao), prefer a direct integer buffer, you can use GLBuffers.newDirectIntBuffer(1); for the vao for example..

3) Don't use an FPSAnimator, use Animator instead

4) Don't inialize a new direct buffer everytime in the display() method (bkgBuffer), do it just once in the variable declaration or in the init(). You should also dispose any direct buffer, since it is not guaranteed that they are gonna be removed by the garbage collector. I have a small class for that here. A better one however is the implementation of Gouessej here.

4) Use a vertex buffer object to declare your vertices attributes (like position)

5) Declare a boolean flag variable update to trigger the update.

button2.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        update = 1;
    }
});

public void display(GLAutoDrawable drawable) {   

    GL4 gl = (GL4) GLContext.getCurrentGL();

    if(update) {
        update = false;
        ...
    }
}

now you have 2 possibilities:

  • you update the vertices directly

        gl3.glBindBuffer(GL_ARRAY_BUFFER, bufferName.get(Buffer.VERTEX));
        gl3.glBufferSubData(GL_ARRAY_BUFFER, 0, vertexBuffer.capacity(), vertexBuffer);
        gl3.glBindBuffer(GL_ARRAY_BUFFER, 0);
    

and your vertex shader may be something like

#version 430    
layout (location = POSITION) in vec2 position;
void main(void)
{    
    gl_Position = vec4(position, 0, 1);
}
  • you update only the matrix that is going to multiply the vertices

    gl3.glBindBuffer(GL_UNIFORM_BUFFER, bufferName.get(Buffer.TRANSFORM));
    gl3.glBufferSubData(GL_UNIFORM_BUFFER, 0, Mat4.SIZE, matBuffer);
    gl3.glBindBuffer(GL_UNIFORM_BUFFER, 0);
    

and in this case the vertex may be

#version 430    
layout (location = POSITION) in vec2 position;

layout (binding = TRANSFORM) uniform Transform
{
    mat4 mat;
};

void main(void)
{    
    gl_Position = mat * vec4(position, 0, 1);
}

In case you need further assistance, don't hesitate to ask for help. For inspiration, you can refer to this hello triangle of mine

Community
  • 1
  • 1
elect
  • 6,765
  • 10
  • 53
  • 119
  • Excellent answer except about the destruction of the direct NIO buffer, your code is weak and works worse than my latest contribution in JMonkeyEngine, it doesn't go on working when you switch to Java 1.9, it has some other limitations, ... Rather use one of my suggestions: http://stackoverflow.com/a/26777380/458157 – gouessej Sep 09 '16 at 11:27
  • Ok, I added it in the answer – elect Sep 09 '16 at 12:59