我有一个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;
}
答案 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一个例子。它会自动打印出任何编译错误。
在着色器varying
中已弃用,请改用<{1}}和in
对out
相同,请使用gl_FragColor
我们有其他jogl用户正朝着这个方向努力,我们可以为android创建一个简单明了的hello三角形样本,这对你有意义吗?