如何修改算法以返回具有不同顶点颜色的三角形

时间:2017-03-30 01:22:56

标签: java opengl jogl

我有片段和顶点,我无法调用java代码来编译一个三角形,每个顶点定义一个颜色。

package Projeto_2;

import com.jogamp.opengl.*;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;

import java.io.BufferedReader;
import java.io.FileReader;

/**
* JSingleTriangle.java <BR>
* 
*
* Java implementation of example (listing 2.8 and 2.9) of the OpenGL  SuperBible 6th Edition.
 * Not exactly the same but an adaptation.
*/

public final class Projeto_2 implements GLEventListener {

private GL4 gl;

private static int width=600;
private static int height=600;



private int shaderProgram;
private int vertShader;
private int fragShader;

private int[] vao; 



public static void main(String[] s) {

    // This demo is based on the GL4 GLProfile 
    GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL4));

    // The demo uses the NEWT (Native Windowing Toolkit) Programming Library
    GLWindow glWindow = GLWindow.create(caps);

    // Setup the GLWindow
    glWindow.setTitle("Single Triangle - JOGL");
    glWindow.setSize(width,height);
    glWindow.setUndecorated(false);
    glWindow.setPointerVisible(true);
    glWindow.setVisible(true);

    // Finally we connect the GLEventListener application code to the GLWindow.
    // GLWindow will call the GLEventListener init, reshape, display and dispose functions when needed.
    glWindow.addGLEventListener(new Projeto_2());
    Animator animator = new Animator();
    animator.add(glWindow);
    animator.start();
}

public void init(GLAutoDrawable drawable) {
    System.out.println("init");

    gl = drawable.getGL().getGL4();

    // Create GPU shader handles
    vertShader = loadShader(GL4.GL_VERTEX_SHADER, "./src/shader.vert");
    fragShader = loadShader(GL4.GL_FRAGMENT_SHADER, "./src/shader.frag");
    //Each shaderProgram must have one vertex shader and one fragment shader.
    shaderProgram = gl.glCreateProgram();
    gl.glAttachShader(shaderProgram, vertShader);
    gl.glAttachShader(shaderProgram, fragShader);       

    //gl.glBindAttribLocation(shaderProgram, 0, "attribute_Position"); /////////////////////////////
   // gl.glBindAttribLocation(shaderProgram, 1, "attribute_Color"); //////////////////////////// 

    gl.glLinkProgram(shaderProgram);
    // Check link status.
    int[] linked = new int[1];
    gl.glGetProgramiv(shaderProgram, GL4.GL_LINK_STATUS, linked, 0);
    if(linked[0]!=0){System.out.println("Shaders succesfully linked");}
    else {
        int[] logLength = new int[1];
        gl.glGetProgramiv(shaderProgram, GL4.GL_INFO_LOG_LENGTH, logLength, 0);

        byte[] log = new byte[logLength[0]];
        gl.glGetProgramInfoLog(shaderProgram, logLength[0], (int[])null, 0, log, 0);

        System.err.println("Error linking shaders: " + new String(log));
        System.exit(1);
    }

    gl.glUseProgram(shaderProgram);

    vao = new int[1];
    gl.glGenVertexArrays(1, vao, 0);
    gl.glBindVertexArray(vao[0]);   


};  

public void reshape(GLAutoDrawable drawable, int x, int y, int z, int h) {
    System.out.println("reshape - Window resized to width=" + z + " height=" + h);
    width = z;
    height = h;

    // Optional: Set viewport
    // Render to a square at the center of the window.
    gl.glViewport((width-height)/2, 0, height, height);
}

public void display(GLAutoDrawable drawable) {
    float[] bg = {0.0f, 0.0f, 0.0f, 1.0f};
    gl.glClearBufferfv(GL4.GL_COLOR, 0, bg, 0);

    gl.glDrawArrays(GL4.GL_TRIANGLES, 0, 3);
}

public void dispose(GLAutoDrawable drawable) {
    System.out.println("Dispose");
    System.out.println("cleanup, remember to release shaders");
    gl.glUseProgram(0);
    gl.glDetachShader(shaderProgram, vertShader);
    gl.glDeleteShader(vertShader);
    gl.glDetachShader(shaderProgram, fragShader);
    gl.glDeleteShader(fragShader);
    gl.glDeleteProgram(shaderProgram);
    System.exit(0);
    System.exit(0);
}

public int loadShader(int type, String filename ) {
    int shader;

    // Create GPU shader handle
    shader = gl.glCreateShader(type);

    // Read shader file
    String[] vlines = new String[1];
    vlines[0] = "";
    String line;

    try{
        BufferedReader reader = new BufferedReader(new FileReader(filename));
        while((line = reader.readLine()) != null) {
            vlines[0] += line + "\n";  // insert a newline character after each line
        }
        reader.close();
    } catch (Exception e) {
        System.err.println("Fail reading shader file");
    }

    gl.glShaderSource(shader, vlines.length, vlines, null);

    // Compile shader
    gl.glCompileShader(shader);

    // Check compile status.
    int[] compiled = new int[1];
    gl.glGetShaderiv(shader, GL4.GL_COMPILE_STATUS, compiled, 0);
    if(compiled[0]!=0){System.out.println("Shader succesfully compiled");}
    else {
        int[] logLength = new int[1];
        gl.glGetShaderiv(shader, GL4.GL_INFO_LOG_LENGTH, logLength, 0);

        byte[] log = new byte[logLength[0]];
        gl.glGetShaderInfoLog(shader, logLength[0], (int[])null, 0, log, 0);

        System.err.println("Error compiling the shader: " + new String(log));
        System.exit(1);
    }

    return shader;
}

我不知道调用两个着色器的函数是什么,用三个顶点生成这个三角形,每个顶点定义红色,蓝色和绿色。

Shader.frag

 #version 400 core

 in vec4 varying_Color; // incoming varying data to the 
                   // fragment shader
                   // sent from the vertex shader

 void main (void) {
 gl_FragColor = varying_Color;
 }

shader.vert

#version 400 core

in vec4 attribute_Position; // vertex shader 
in vec4 attribute_Color; // attributes

out vec4 varying_Color; // Outgoing varying data 
                    // sent to the fragment shader
void main (void) { 
varying_Color = attribute_Color;
gl_Position = attribute_Position;
} 

1 个答案:

答案 0 :(得分:1)

我不使用 JAVA JOGL ,所以我可能错了,但我的 OpenGL 体验告诉我你的顶点着色器对我来说看起来不太好,尤其是:

#version 400 core   
in vec4 attribute_Position; // vertex shader 
in vec4 attribute_Color; // attributes

您选择了GL 4.00核心配置文件并使用in作为输入。如果您的输入是从顶点上方的着色器提供的,那将会有效,但我认为情况并非如此(因为您只有顶点和片段),所以您应该有这样的东西:

#version 400 core   
layout(location=0) in vec4 attribute_Position;
layout(location=1) in vec4 attribute_Color;

此外,您应该将位置和颜色VBO绑定到这些位置,以便取消

gl.glBindAttribLocation(shaderProgram, 0, "attribute_Position"); 
gl.glBindAttribLocation(shaderProgram, 1, "attribute_Color"); 

代码中的绑定,但我不熟悉,我更习惯于此:

// bind VBO
glBindBuffer(vbotype,vboid);
glEnableVertexAttribArray(vbolocation);
glVertexAttribPointer(vbolocation,datacomponents,datatype,GL_FALSE,0,0);

// unbind VBO
glBindBuffer(vbotype,0);
glDisableVertexAttribArray(vbolocation);

每个 VBO 都有这些:

GLuint vboid;                       // OpenGL id for current VBO
int    vbolocation;                 // intended VBO atrib layout location for GLSL
GLuint vbotype;                     // GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_BUFFER
GLuint datatype;                    // GL_FLOAT,GL_UNSIGNED_INT
GLuint datacomponents;              // vector size 1,2,3,4
List<GLint> data;                   // 32bit vbo data (always overtype with datatype on any access!!!)