Как редактировать вершинный шейдер в JOGL

Поэтому я работаю над приложением Java / Jogl, которое в основном просто переводит вершины треугольника. Пока я могу заставить треугольник двигаться слева направо, но я не могу понять, как отредактировать вершинный шейдер, чтобы при нажатии кнопки треугольник начинал двигаться вверх и вниз, а не влево и вправо.

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);

}

Как мне отредактировать мой вершинный шейдер так, чтобы, когда я нажимал на кнопку, расположение вершин изменялось, и треугольник начинал двигаться вверх и вниз, а не слева направо?

0

Решение

1) Не делайте обновление так

2) Не используйте int массив для ресурсов OpenGL (vao), предпочитаете прямой целочисленный буфер, вы можете использовать GLBuffers.newDirectIntBuffer(1); для вао например ..

3) Не используйте FPSAnimatorиспользовать Animator вместо

4) Не инициализируйте новый прямой буфер каждый раз в display() метод (bkgBuffer), сделайте это только один раз в объявлении переменной или в init(), Вы также должны избавиться от любого прямого буфера, так как не гарантируется, что он будет удален сборщиком мусора. У меня есть небольшой класс для этого Вот. Лучше, однако, реализация Gouessej Вот.

4) Используйте объект буфера вершин, чтобы объявить свои атрибуты вершин (например, положение)

5) Объявите переменную логического флага 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;
...
}
}

теперь у вас есть 2 возможности:

  • вы обновляете вершины напрямую

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

и ваш вершинный шейдер может быть что-то вроде

#version 430
layout (location = POSITION) in vec2 position;
void main(void)
{
gl_Position = vec4(position, 0, 1);
}
  • вы обновляете только матрицу, которая будет умножать вершины

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

и в этом случае вершина может быть

#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);
}

Если вам нужна дополнительная помощь, не стесняйтесь обращаться за помощью.
Для вдохновения вы можете обратиться к этому привет треугольник мой

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]