Here are my (very simple) shaders:
protected String [] codeTransformateurSommets = {
"#version 400 core",
"void main(void) {",
"const vec4 vertices[3]=vec4[3](vec4(0.25,-0.25,0.5,1.0),",
" vec4(-0.25,-0.25,0.5,1.0),",
" vec4(0.25,0.25,0.5,1.0));",
"gl_position=vertices[gl_VertexID];",
"}"
};
protected String [] codeTransformateurFragments = {
"#version 400 core",
"out vec4 color;",
"void main(void) {",
"color=vec4(1.0,0.0,0.0,1.0);",
"}"
};
Here's how I try to get a program :
private int créeProgrammeOpenGL(){
IntBuffer résultatEditionLiens;
int transformateurSommets,transformateurFaces;
int programme;
transformateurSommets = chargeTransformateur(GL4.GL_VERTEX_SHADER,codeTransformateurSommets);
transformateurFaces = chargeTransformateur(GL4.GL_FRAGMENT_SHADER, codeTransformateurFragments);
programme = gl4.glCreateProgram();
gl4.glAttachShader(programme, transformateurSommets);
gl4.glAttachShader(programme, transformateurFaces);
gl4.glLinkProgram(programme);
if(programme!=0) {
résultatEditionLiens=IntBuffer.allocate(1);
gl4.glGetProgramiv(programme, GL4.GL_LINK_STATUS, résultatEditionLiens);
if (résultatEditionLiens.get(0) == 0) {
gl4.glDeleteProgram(programme);
throw new RuntimeException("Erreur à la création du programme!!");
} else {
gl4.glUseProgram(programme);
gl4.glDeleteShader(transformateurSommets);
gl4.glDeleteShader(transformateurFaces);
}
} else {
throw new RuntimeException("Erreur à la création du programme!!");
}
return(programme);
}
public static int chargeTransformateur(int type, String [] codeTransformateur){
int transformateur,i,j;
IntBuffer résultatCompilation;
transformateur = gl4.glCreateShader(type);
if(transformateur!=0) {
// création réussie : lui indiquer le code source
gl4.glShaderSource(transformateur,codeTransformateur.length,codeTransformateur,null);
// compiler le code source
gl4.glCompileShader(transformateur);
// récupérer le diagnostic de création du shader
byte [] infoLog=new byte[10000];
int [] taille=new int[100];
gl4.glGetShaderInfoLog(transformateur,1000,taille,0,infoLog,0);
// récupérer le résultat de la compilation
résultatCompilation=IntBuffer.allocate(1);
gl4.glGetShaderiv(transformateur,GL4.GL_COMPILE_STATUS,résultatCompilation);
if(résultatCompilation.get(0)==0) {
// la compilation a échoué!
throw new RuntimeException("Erreur à la compilation du shader!!"+"\r\n"+"\r\n"+codeTransformateur+"\r\n"+"\r\n"+infoLog.toString()+"\r\n"+"\r\n"+"\r\n");
}
} else {
// la création est un échec!
throw new RuntimeException("Erreur à la création du nom du shader!!"+"\r\n"+codeTransformateur);
}
return(transformateur);
}
And the result is a GL_LINK_STATUS set to false when glLinkProgram
returns.
My investigations :
glGetShaderiv
with parameter GL_COMPILE_STATUS
returns true for both shaders.glGetProgramiv
function with parameter GL_ATTACHED_SHADERS
returns 1 after the first attachment and 2 after the second.Any idea about what I am doing wrong?
The major is is, that you've to set the source code to the shader object by glShaderSource
rather than reading the source code string from a shader object by glGetShaderSource
.
See Java Code Examples for com.jogamp.opengl.GL2.glShaderSource().
What you actually do, is to compile "empty" shader objects (of course with out any errors). But linking fails, because the vertex shader does not write to gl_Position
(of course, because it is "empty").
If you want to create and initialize an array of vec4
, then the correct syntax is:
(See Array constructors)
const vec4 vertices[3] = vec4[3](
vec4(0.25,-0.25,0.5,1.0),
vec4(-0.25,-0.25,0.5,1.0),
vec4(0.25,0.25,0.5,1.0));
Furthermore, OpenGL Shading Language (GLSL) is case sensitive. It is gl_Position
rather than gl_position
:
gl_position=vertices[gl_VertexID];
gl_Position = vertices[gl_VertexID];
I recommend to get the compile error messages by glGetShaderInfoLog
. See Java Code Examples for org.lwjgl.opengl.GL20.glCompileShader()