JOGL 失败;我做什么都是黑屏。着色器出现故障,glGetAttribLocation returns -1
JOGL failure; whatever I do is black screen. Shaders malfunctioning, glGetAttribLocation returns -1
我遇到了 JOGL 故障。我根本无法让它显示任何东西。我已经使 Android OpenGL ES 正常工作,但这里有 2 个大问题。首先,没有任何显示。其次,我的 none 个变量存在于着色器编译器中。
很抱歉这不是 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) {
}
}
抱歉缩进,Whosebug 迫使我缩进很多。
那是我的主要 class。
这是我的 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;
}
片段着色器:
precision mediump float;
varying vec4 v_Color;
void main()
{
gl_FragColor = v_Color;
}
几个observations/hints:
保持位置分层,如 here,它不易出错并使您的代码更具可读性:
public class Semantic { // or Location
public static class Attr {
public static int POSITION = 0;
public static int COLOR = 3;
}
}
不要在display()
中的每一帧都分配一个新的FloatBuffer
,在init()
中初始化它并重新使用它。你可以用我的一个工具来处理它,我稍后告诉你。
避免重新发明轮子,你可以完全避免你的 ShaderStuff
class,使用 jogl 已经提供给我们的,here 一个例子。它会自动打印出任何编译错误。
您的目标是哪个 GLES 版本?因为在着色器中 varying
已弃用,请使用 in
和 out
代替
与gl_FragColor
相同,使用out vec4 FragColor;
我们有其他 jogl 用户正在朝这个方向努力,我们可以创建一个简单明了的 hello 三角形示例,专门为 android 制作,您会感兴趣吗?
我遇到了 JOGL 故障。我根本无法让它显示任何东西。我已经使 Android OpenGL ES 正常工作,但这里有 2 个大问题。首先,没有任何显示。其次,我的 none 个变量存在于着色器编译器中。
很抱歉这不是 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) {
}
}
抱歉缩进,Whosebug 迫使我缩进很多。 那是我的主要 class。 这是我的 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;
}
片段着色器:
precision mediump float;
varying vec4 v_Color;
void main()
{
gl_FragColor = v_Color;
}
几个observations/hints:
保持位置分层,如 here,它不易出错并使您的代码更具可读性:
public class Semantic { // or Location public static class Attr { public static int POSITION = 0; public static int COLOR = 3; } }
不要在
display()
中的每一帧都分配一个新的FloatBuffer
,在init()
中初始化它并重新使用它。你可以用我的一个工具来处理它,我稍后告诉你。避免重新发明轮子,你可以完全避免你的
ShaderStuff
class,使用 jogl 已经提供给我们的,here 一个例子。它会自动打印出任何编译错误。您的目标是哪个 GLES 版本?因为在着色器中
varying
已弃用,请使用in
和out
代替与
gl_FragColor
相同,使用out vec4 FragColor;
我们有其他 jogl 用户正在朝这个方向努力,我们可以创建一个简单明了的 hello 三角形示例,专门为 android 制作,您会感兴趣吗?