2016-09-09 5 views
0

그래서 기본적으로 삼각형의 꼭지점을 변환하는 Java/Jogl 응용 프로그램에서 작업하고 있습니다. 지금까지 삼각형을 왼쪽에서 오른쪽으로 움직일 수 있었지만, 버텍스 쉐이더를 편집하는 방법을 이해할 수 없었습니다. 그래서 버튼을 클릭하면 삼각형이 왼쪽과 오른쪽 대신 위아래로 움직이기 시작합니다. 나는 버튼을 정점의 위치가 변경을 클릭하고 삼각형이 오른쪽으로 이동하기 시작 아래 대신 떠날 때 있도록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

오케이. 질문이 뭐야? 귀하의 게시물에 물음표가 표시되지 않습니다. – immibis

+0

제 질문은 버텍스 쉐이더를 편집하여 버튼을 클릭 할 때 버텍스의 위치가 바뀌고 삼각형이 왼쪽에서 오른쪽으로 위아래로 움직이기 시작하도록하는 것입니다. – Anony

+0

버텍스 쉐이더는 버튼에 대해 알지 못하므로 버텍스 쉐이더를 변경하는 것만으로는 할 수 없습니다. – immibis

답변

2

1)과 같은 업데이트를하지 마십시오 OpenGL을 자원 (VAO), 직접 정수 버퍼를 선호, 당신은 예를 들어 VAO에 대한 GLBuffers.newDirectIntBuffer(1);을 사용할 수 있습니다에 대한 int 배열을 사용하지 마십시오

2) 그 ..

3) 변수 선언 번만 그것을 대신

4)가 display() 방법 (bkgBuffer)에서 새로운 직접 버퍼 매번 inialize 안 Animator을 사용 FPSAnimator 사용하지 마십시오에 10. 가비지 컬렉터에 의해 제거 될 것이라는 보장이 없으므로 직접 버퍼를 처리해야합니다. 그 작은 클래스가 here입니다. 그러나 더 나은 방법은 Gouessej here을 구현하는 것입니다.

4) 정점을 선언하는 정점 버퍼 오브젝트를 사용 (업데이트를 트리거하는 부울 플래그 변수 update를 선언)

5) 위치와 같은 속성.

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; 
     ... 
    } 
} 

지금 당신은이 가능성이 있습니다

  • 당신이 정점 직접

    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); 
} 
등 16,
  • 당신이 정점

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

을 할 수있다 주저하지 말고 도움을 요청하십시오. 영감을 얻으려면 hello triangle 광산

+0

오른쪽 NIO 버퍼의 파괴를 제외하고 훌륭한 대답, 귀하의 코드가 약해지고 JMonkeyEngine에서 가장 최근에 기여한 것보다 나빠졌습니다. Java 1.9로 전환 할 때 작동하지 않습니다. 다른 제한 사항이 있습니다 ... 오히려 내 제안 중 하나를 사용하십시오. http://stackoverflow.com/a/26777380/458157 – gouessej

+0

좋아, 답변에 추가했습니다. – elect