我的 ShaderProgram 不工作
My ShaderProgram doesn't work
我的主要语言是法语,我会尽力而为。
我尝试了解着色器,但我无法找到为什么我的着色器不起作用。我使用带有 2 个 VBO 的 VAO 进行绘制。一个用于顶点,另一个用于索引。我的对象渲染良好,但我的着色器似乎没有效果。
我的 svn 项目 eclipse ; http://sourceforge.net/projects/mad-game-engine
我的 vao 设置;
VAO
--VBO 0 个顶点
--VBO 1 指数
我的ShaderProgram;
package fr.mad.engine.shader;
import java.io.BufferedReader;
import java.io.FileReader;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GL4;
import fr.mad.engine.LOG;
public abstract class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaerID;
private LOG log;
public ShaderProgram(String vertexFile, String fragmentFile, LOG log, GL2 gl) {
this.log = new LOG(log, "shader");
vertexShaderID = loadShader(vertexFile, GL2ES2.GL_VERTEX_SHADER, gl.getGL2());
fragmentShaerID = loadShader(fragmentFile, GL2ES2.GL_FRAGMENT_SHADER, gl.getGL2());
programID = gl.glCreateProgram();
gl.glAttachShader(programID, vertexShaderID);
gl.glAttachShader(programID, fragmentShaerID);
bindAttributes(gl);
gl.glLinkProgram(programID);
gl.glValidateProgram(programID);
checkProgram(gl, programID);
}
public void start(GL2 gl) {
gl.glUseProgram(programID);
}
public void stop(GL2 gl) {
gl.glUseProgram(0);
}
public void clenUp(GL2 gl) {
stop(gl);
gl.glDetachShader(programID, vertexShaderID);
gl.glDetachShader(programID, fragmentShaerID);
gl.glDeleteShader(vertexShaderID);
gl.glDeleteShader(this.fragmentShaerID);
gl.glDeleteProgram(programID);
}
protected abstract void bindAttributes(GL2 gl);
protected void bindAttribute(GL2 gl, int i, String t) {
gl.glBindAttribLocation(programID, i, t);
}
private int loadShader(String file, int type, GL2 gl) {
log.log("Loading " + (GL2ES2.GL_VERTEX_SHADER == type ? "Vertex" : "Fragment") + " Shader");
StringBuilder shaderSource = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
shaderSource.append(line).append("\n");
}
} catch (Exception e) {
e.printStackTrace();
}
int shaderID = gl.glCreateShader(type);
gl.glShaderSource(shaderID, 1, new String[] { shaderSource.toString() }, new int[] { shaderSource.toString().length() }, 0);
gl.glCompileShader(shaderID);
checkShader(gl, shaderID);
log.log("");
return shaderID;
}
private void checkProgram(GL2 gl, int handle) {
int[] buffer = new int[1];
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_LINK_STATUS_ARB, buffer, 0);
if (buffer[0] == GL.GL_FALSE) // 1 or 0
warning("error linking program ");
gl.glValidateProgramARB(handle);
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_VALIDATE_STATUS_ARB, buffer, 0);
if (buffer[0] == GL.GL_FALSE)
warning("program not validate");
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, buffer, 0);
byte[] log = new byte[buffer[0]];
gl.glGetInfoLogARB(handle, buffer[0], buffer, 0, log, 0);
if (log[0] != 0)
warning("linker info log:\n" + new String(log));
}
private void checkShader(GL2 gl, int handle) {
int[] buffer = new int[1];
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_COMPILE_STATUS_ARB, buffer, 0);
if (buffer[0] == GL.GL_FALSE) {
warning("error compiling shader");
}
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, buffer, 0);
byte[] log = new byte[buffer[0]];
gl.glGetInfoLogARB(handle, buffer[0], buffer, 0, log, 0);
if (log[0] != 0)
warning("compiler info log:\n" + new String(log, 0, log.length - 1));
}
private void warning(String string) {
log.log(string);
}
}
顶点着色器;
#version 400 core
in vec3 position;
out vec3 colour;
void main(void){
gl_Position = vec4(position.xyz,1.0);
colour = sin(vec3(0,1,0));
}
片段着色器;
#version 400 core
in vec3 colour;
out vec4 out_Color;
void main(void){
out_Color = vec4(colour,1.0);
gl_FragColor = vec4(colour,1.0);
}
我的绘图方法;
shader.start(gl);
gl.glBindVertexArray(vaoid);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbovertid);
gl.glEnableVertexAttribArray(0);
gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, vboindexid);
gl.glEnableVertexAttribArray(1);
gl.glColor3f(1f, 0, 0);
gl.glDrawElements(GL.GL_TRIANGLES, this.indices.length, GL.GL_UNSIGNED_INT, 0);
gl.glEnableVertexAttribArray(1);
gl.glEnableVertexAttribArray(0);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
gl.glBindVertexArray(0);
shader.stop(gl);
在shaderprogram中使用theses方法;
private void checkProgram(GL2 gl, int handle) {
int[] buffer = new int[1];
gl.glGetProgramiv(handle, GL2ES2.GL_LINK_STATUS, buffer, 0);
if (buffer[0] == GL.GL_FALSE) // 1 or 0
warning("error linking program ");
gl.glValidateProgram(handle);
gl.glGetProgramiv(handle, GL2.GL_VALIDATE_STATUS, buffer, 0);
if (buffer[0] == GL.GL_FALSE)
warning("program not validate");
gl.glGetProgramiv(handle, GL2.GL_INFO_LOG_LENGTH, buffer, 0);
byte[] log = new byte[buffer[0]];
gl.glGetProgramInfoLog(handle, buffer[0], buffer, 0, log, 0);
if (log[0] != 0)
warning("linker info log:\n" + new String(log));
}
private void checkShader(GL2 gl, int handle) {
int[] buffer = new int[1];
gl.glGetProgramiv(handle, GL2.GL_COMPILE_STATUS, buffer, 0);
if (buffer[0] == GL.GL_FALSE) {
warning("error compiling shader");
}
gl.glGetProgramiv(handle, GL2.GL_INFO_LOG_LENGTH, buffer, 0);
byte[] log = new byte[buffer[0]];
if(log.length>0)
gl.glGetShaderInfoLog(handle, buffer[0], buffer, 0, log, 0);
if(log.length>0)
if (log[0] != 0)
warning("compiler info log:\n" + new String(log, 0, log.length - 1));
}
我得到了这个日志;
Loading Vertex Shader
error compiling shader
Loading Fragment Shader
error compiling shader
error linking program
program not validate
正如我之前写的那样 你的日志不是 GLSL compilation/link 日志 你把它搞砸了。当我将你的着色器放入我的引擎时,这里是 nVidia 环境的日志:
[Vertex]
OK
[Fragment]
OK
0(9) : warning C7533: global variable gl_FragColor is deprecated after version 120
[Program]
Linker error
Fragment info
-------------
0(9) : warning C7533: global variable gl_FragColor is deprecated after version 120
error: user-defined fragment shader outputs may not be used with gl_FragColor or gl_FragData
所以把片段着色器改成这样:
#version 400 core
in vec3 colour;
out vec4 out_Color;
void main(void){
out_Color = vec4(colour,1.0);
}
通过删除 gl_FragColor = vec4(colour,1.0);
因为您已经设置了输出颜色。你可以只做一次......如果你仍然需要旧式变量然后使用 compatibility
配置文件而不是 core
检查这个:glGetShaderInfoLog
我敢打赌,您正在调用链接到程序的任何基于 gl 的库所提供的不同 glGetShaderInfoLog
。这就是为什么你有那些奇怪的消息而不是 compilation/link 日志。尝试使用原始 gl 一个 returns 直接来自 gfx 驱动程序的日志 ...
我的主要语言是法语,我会尽力而为。
我尝试了解着色器,但我无法找到为什么我的着色器不起作用。我使用带有 2 个 VBO 的 VAO 进行绘制。一个用于顶点,另一个用于索引。我的对象渲染良好,但我的着色器似乎没有效果。
我的 svn 项目 eclipse ; http://sourceforge.net/projects/mad-game-engine
我的 vao 设置;
VAO
--VBO 0 个顶点
--VBO 1 指数
我的ShaderProgram;
package fr.mad.engine.shader;
import java.io.BufferedReader;
import java.io.FileReader;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GL4;
import fr.mad.engine.LOG;
public abstract class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaerID;
private LOG log;
public ShaderProgram(String vertexFile, String fragmentFile, LOG log, GL2 gl) {
this.log = new LOG(log, "shader");
vertexShaderID = loadShader(vertexFile, GL2ES2.GL_VERTEX_SHADER, gl.getGL2());
fragmentShaerID = loadShader(fragmentFile, GL2ES2.GL_FRAGMENT_SHADER, gl.getGL2());
programID = gl.glCreateProgram();
gl.glAttachShader(programID, vertexShaderID);
gl.glAttachShader(programID, fragmentShaerID);
bindAttributes(gl);
gl.glLinkProgram(programID);
gl.glValidateProgram(programID);
checkProgram(gl, programID);
}
public void start(GL2 gl) {
gl.glUseProgram(programID);
}
public void stop(GL2 gl) {
gl.glUseProgram(0);
}
public void clenUp(GL2 gl) {
stop(gl);
gl.glDetachShader(programID, vertexShaderID);
gl.glDetachShader(programID, fragmentShaerID);
gl.glDeleteShader(vertexShaderID);
gl.glDeleteShader(this.fragmentShaerID);
gl.glDeleteProgram(programID);
}
protected abstract void bindAttributes(GL2 gl);
protected void bindAttribute(GL2 gl, int i, String t) {
gl.glBindAttribLocation(programID, i, t);
}
private int loadShader(String file, int type, GL2 gl) {
log.log("Loading " + (GL2ES2.GL_VERTEX_SHADER == type ? "Vertex" : "Fragment") + " Shader");
StringBuilder shaderSource = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
shaderSource.append(line).append("\n");
}
} catch (Exception e) {
e.printStackTrace();
}
int shaderID = gl.glCreateShader(type);
gl.glShaderSource(shaderID, 1, new String[] { shaderSource.toString() }, new int[] { shaderSource.toString().length() }, 0);
gl.glCompileShader(shaderID);
checkShader(gl, shaderID);
log.log("");
return shaderID;
}
private void checkProgram(GL2 gl, int handle) {
int[] buffer = new int[1];
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_LINK_STATUS_ARB, buffer, 0);
if (buffer[0] == GL.GL_FALSE) // 1 or 0
warning("error linking program ");
gl.glValidateProgramARB(handle);
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_VALIDATE_STATUS_ARB, buffer, 0);
if (buffer[0] == GL.GL_FALSE)
warning("program not validate");
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, buffer, 0);
byte[] log = new byte[buffer[0]];
gl.glGetInfoLogARB(handle, buffer[0], buffer, 0, log, 0);
if (log[0] != 0)
warning("linker info log:\n" + new String(log));
}
private void checkShader(GL2 gl, int handle) {
int[] buffer = new int[1];
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_COMPILE_STATUS_ARB, buffer, 0);
if (buffer[0] == GL.GL_FALSE) {
warning("error compiling shader");
}
gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, buffer, 0);
byte[] log = new byte[buffer[0]];
gl.glGetInfoLogARB(handle, buffer[0], buffer, 0, log, 0);
if (log[0] != 0)
warning("compiler info log:\n" + new String(log, 0, log.length - 1));
}
private void warning(String string) {
log.log(string);
}
}
顶点着色器;
#version 400 core
in vec3 position;
out vec3 colour;
void main(void){
gl_Position = vec4(position.xyz,1.0);
colour = sin(vec3(0,1,0));
}
片段着色器;
#version 400 core
in vec3 colour;
out vec4 out_Color;
void main(void){
out_Color = vec4(colour,1.0);
gl_FragColor = vec4(colour,1.0);
}
我的绘图方法;
shader.start(gl);
gl.glBindVertexArray(vaoid);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbovertid);
gl.glEnableVertexAttribArray(0);
gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, vboindexid);
gl.glEnableVertexAttribArray(1);
gl.glColor3f(1f, 0, 0);
gl.glDrawElements(GL.GL_TRIANGLES, this.indices.length, GL.GL_UNSIGNED_INT, 0);
gl.glEnableVertexAttribArray(1);
gl.glEnableVertexAttribArray(0);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
gl.glBindVertexArray(0);
shader.stop(gl);
在shaderprogram中使用theses方法;
private void checkProgram(GL2 gl, int handle) {
int[] buffer = new int[1];
gl.glGetProgramiv(handle, GL2ES2.GL_LINK_STATUS, buffer, 0);
if (buffer[0] == GL.GL_FALSE) // 1 or 0
warning("error linking program ");
gl.glValidateProgram(handle);
gl.glGetProgramiv(handle, GL2.GL_VALIDATE_STATUS, buffer, 0);
if (buffer[0] == GL.GL_FALSE)
warning("program not validate");
gl.glGetProgramiv(handle, GL2.GL_INFO_LOG_LENGTH, buffer, 0);
byte[] log = new byte[buffer[0]];
gl.glGetProgramInfoLog(handle, buffer[0], buffer, 0, log, 0);
if (log[0] != 0)
warning("linker info log:\n" + new String(log));
}
private void checkShader(GL2 gl, int handle) {
int[] buffer = new int[1];
gl.glGetProgramiv(handle, GL2.GL_COMPILE_STATUS, buffer, 0);
if (buffer[0] == GL.GL_FALSE) {
warning("error compiling shader");
}
gl.glGetProgramiv(handle, GL2.GL_INFO_LOG_LENGTH, buffer, 0);
byte[] log = new byte[buffer[0]];
if(log.length>0)
gl.glGetShaderInfoLog(handle, buffer[0], buffer, 0, log, 0);
if(log.length>0)
if (log[0] != 0)
warning("compiler info log:\n" + new String(log, 0, log.length - 1));
}
我得到了这个日志;
Loading Vertex Shader
error compiling shader
Loading Fragment Shader
error compiling shader
error linking program
program not validate
正如我之前写的那样 你的日志不是 GLSL compilation/link 日志 你把它搞砸了。当我将你的着色器放入我的引擎时,这里是 nVidia 环境的日志:
[Vertex]
OK
[Fragment]
OK
0(9) : warning C7533: global variable gl_FragColor is deprecated after version 120
[Program]
Linker error
Fragment info
-------------
0(9) : warning C7533: global variable gl_FragColor is deprecated after version 120
error: user-defined fragment shader outputs may not be used with gl_FragColor or gl_FragData
所以把片段着色器改成这样:
#version 400 core
in vec3 colour;
out vec4 out_Color;
void main(void){
out_Color = vec4(colour,1.0);
}
通过删除 gl_FragColor = vec4(colour,1.0);
因为您已经设置了输出颜色。你可以只做一次......如果你仍然需要旧式变量然后使用 compatibility
配置文件而不是 core
检查这个:glGetShaderInfoLog
我敢打赌,您正在调用链接到程序的任何基于 gl 的库所提供的不同 glGetShaderInfoLog
。这就是为什么你有那些奇怪的消息而不是 compilation/link 日志。尝试使用原始 gl 一个 returns 直接来自 gfx 驱动程序的日志 ...