JOGL失败;无论我做什么都是黑屏。着色器出现故障,glGetAttribLocation返回-1

时间:2017-02-01 13:43:07

标签: java opengl jogl

我有一个JOGL失败。我根本无法让它显示任何东西。我已经让Android OpenGL ES工作了,但我在这里遇到了两大问题。首先,没有任何显示。其次,着色器编译器不存在任何变量。

我很抱歉这不是SSCEE。我只是有这个臭虫,我无法用更短的代码重现它。

import java.awt.Dimension;
import java.io.File;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import javax.swing.JFrame;

import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.leonidnediak.labyrinth.annoyingGLstuff.ShaderStuff;
import com.leonidnediak.labyrinth.util.FileUtil;

public class Main implements GLEventListener {

public static File codeSource;

static {
    try {
        codeSource = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI());
    } catch (URISyntaxException e) {

    }
}

public static final Dimension size = new Dimension(400, 600);



public static int program;
public static int aColorLocation;
public static int aPositionLocation;
public static int uMatrixLocation;

public static void main(String[] args) {
    GLProfile profile = GLProfile.get(GLProfile.GL2);
    GLCapabilities cap = new GLCapabilities(profile);

    GLCanvas canvas = new GLCanvas(cap);
    canvas.addGLEventListener(new Main());
    canvas.setSize(size);

    JFrame frame = new JFrame();
    frame.setSize(size);
    frame.setResizable(false);
    frame.add(canvas);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

@Override
public void display(GLAutoDrawable autoDrawable) {
    GL2 gl = autoDrawable.getGL().getGL2();
    gl.glClear(GL2.GL_COLOR_BUFFER_BIT);

    gl.glEnableVertexAttribArray(aPositionLocation);
    FloatBuffer vertexBuffer = ByteBuffer.allocateDirect(4*9).asFloatBuffer();
    vertexBuffer.put(new float[] {-1, 1, 0, 0, -1, 0, 1, 1, 0});
    vertexBuffer.position(0);
    gl.glVertexAttribPointer(aPositionLocation, 3, GL2.GL_FLOAT, false, 12, vertexBuffer);
    gl.glEnableVertexAttribArray(aColorLocation);
    FloatBuffer colorBuffer = ByteBuffer.allocateDirect(4*9).asFloatBuffer();
    colorBuffer.put(new float[] {1, 1, 1, 1, 1, 1, 1, 1, 1});
    colorBuffer.position(0);
    gl.glVertexAttribPointer(aPositionLocation, 3, GL2.GL_FLOAT, false, 12, colorBuffer);
    gl.glDrawArrays(GL2.GL_TRIANGLES, 0, 3);
}

@Override
public void dispose(GLAutoDrawable autoDrawable) {

}

@Override
public void init(GLAutoDrawable autoDrawable) {
    GL2 gl = autoDrawable.getGL().getGL2();
    program = ShaderStuff.buildProgram(gl, FileUtil.fileContents(new File(codeSource, "vertexShader.glsl")), FileUtil.fileContents(new File(codeSource, "fragmentShader.glsl")));
    int[] arr = new int[1];
    gl.glGetProgramiv(program, GL2.GL_ACTIVE_ATTRIBUTES, arr, 0);
    System.out.println(arr[0]);
    aColorLocation = gl.glGetAttribLocation(program, "a_Color");
    aPositionLocation = gl.glGetAttribLocation(program, "a_Position");
    uMatrixLocation = gl.glGetUniformLocation(program, "u_Matrix");
    System.out.println(program);
    gl.glUniformMatrix4fv(uMatrixLocation, 1, false, new float[] {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1}, 0);
}

@Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {

}

}

抱歉缩进,stackoverflow迫使我缩进很多。 那是我的主课。 这是我的ShaderStuff:

import com.jogamp.opengl.GL2;

public class ShaderStuff {

public static int compileVertexShader(GL2 gl, String shaderCode) {
    return compileShader(gl, GL2.GL_VERTEX_SHADER, shaderCode);
}

public static int compileFragmentShader(GL2 gl, String shaderCode) {
    return compileShader(gl, GL2.GL_FRAGMENT_SHADER, shaderCode);
}

private static int compileShader(GL2 gl, int type, String shaderCode) {
    final int shaderObjectId = gl.glCreateShader(type);
    if (shaderObjectId == 0) {
        return 0;

    }
    gl.glShaderSource(shaderObjectId, 1, new String[] {shaderCode}, null);
    gl.glCompileShader(shaderObjectId);
    final int[] compileStatus = new int[1];
    gl.glGetShaderiv(shaderObjectId, GL2.GL_COMPILE_STATUS, compileStatus, 0);
    if (compileStatus[0] == 0) {
        //gl.glDeleteShader(shaderObjectId);
        //return 0;
    }
    return shaderObjectId;
}

public static int linkProgram(GL2 gl, int vertexShaderId, int fragmentShaderId) {
    final int programObjectId = gl.glCreateProgram();
    if (programObjectId == 0) {
        return 0;
    }
    gl.glAttachShader(programObjectId, vertexShaderId);
    gl.glAttachShader(programObjectId, fragmentShaderId);
    gl.glLinkProgram(programObjectId);
    final int[] linkStatus = new int[1];
    gl.glGetProgramiv(programObjectId, GL2.GL_LINK_STATUS, linkStatus, 0);
    if (linkStatus[0] == 0) {
        //gl.glDeleteProgram(programObjectId);
        //return 0;
    }
    return programObjectId;
}

public static int buildProgram(GL2 gl, String vertexS, String fragS) {
    int program;
    int vertexShader = compileVertexShader(gl, vertexS);
    int fragmentShader = compileVertexShader(gl, fragS);
    program = linkProgram(gl, vertexShader, fragmentShader);
    validateProgram(gl, program);
    return program;
}

public static boolean validateProgram(GL2 gl, int programObjectId) {
    gl.glValidateProgram(programObjectId);
    final int[] validateStatus = new int[1];
    gl.glGetProgramiv(programObjectId, GL2.GL_VALIDATE_STATUS, validateStatus, 0);
    return validateStatus[0] != 0;
}

}
编辑:问题出在我的GLSL上,但我找不到我的失败。

顶点着色器:

attribute vec4 a_Color;
attribute vec4 a_Position;

uniform mat4 u_Matrix;

varying vec4 v_Color;

void main()
{
    v_Color = a_Color;
    gl_Position = u_Matrix * a_Position;
    gl_PointSize = 1.0;
}

Fragment Shader:

precision mediump float;

varying vec4 v_Color;

void main()
{
    gl_FragColor = v_Color;
}

1 个答案:

答案 0 :(得分:1)

几点观察/提示:

  • 保持位置分层,如here,它不易出错,并使代码更易读:

    public class Semantic { // or Location
    
        public static class Attr {
    
            public static int POSITION = 0;
            public static int COLOR = 3;
        }
    }
    
  • 不要在FloatBuffer的每一帧中分配新的display(),在init()中对其进行初始化并重复使用。您可以使用我的一个实用程序来处理它,我稍后会告诉您。

  • 避免重新发明轮子,你可以完全避开你的ShaderStuff课程,使用jogl已经为我们提供的内容,here一个例子。它会自动打印出任何编译错误。

  • 你正在瞄准GLES版本的
  • 在着色器varying中已弃用,请改用<{1}}和in

  • out相同,请使用gl_FragColor

我们有其他jogl用户正朝着这个方向努力,我们可以为android创建一个简单明了的hello三角形样本,这对你有意义吗?