【问题标题】:My ShaderProgram doesn't work我的 ShaderProgram 不起作用
【发布时间】:2015-11-03 06:35:30
【问题描述】:

我的母语是法语,我会尽力而为。

我尝试了解着色器,但我无法找到我的着色器不起作用的原因。我使用带有 2 个 VBO 的 VAO 进行绘制。一个用于顶点,另一个用于索引。我的对象渲染得很好,但我的着色器似乎没有效果。

我的 svn 项目 eclipse ; http://sourceforge.net/projects/mad-game-engine

我的 vao 设置;
VAO
--VBO 0 个顶点
--VBO 1 指数

我的着色器程序;

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中使用这些方法;

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

【问题讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • @11mad11 您在片段着色器中遇到错误,请参阅我的答案...在更改着色器工作后(粗略的它不使用矩阵,因此模型在没有投影/旋转/的情况下渲染...但是颜色看起来很相配...)

标签: java shader jogl fragment-shader vertex-shader


【解决方案1】:

正如我之前写的,你的日志不是 GLSL 编译/链接日志,你把它搞砸了。当我将您的着色器放入我的引擎时,这里是 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。这就是为什么你有那些奇怪的消息而不是编译/链接日志。尝试使用原始的 gl 直接从 gfx 驱动程序返回日志...

【讨论】:

  • 我使用 com.jogamp.opengl.GL2ES2.glGetShaderInfoLog,Entry point to C language function: void {@native glGetShaderInfoLog}(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog) 我找不到另一个。我不知道为什么,但是使用这个片段着色器我遇到了一个致命错误。
  • 当我使用out_Color = vec4(colour,1.0); 时,它给了我一个致命错误,而使用out_Color = vec4(0,1,0,1); 我的茶壶不可见或不渲染。
  • @11mad11 是的,那是正确的glGetShaderInfoLog,有 4 个参数……你为什么要使用有 6 个参数的那个?
  • c中的函数有4个参数,而在java中,他有6个参数。
  • goo.gl/tS5EwD 带有 4 个参数的 javadoc 使用包含简单 java 表没有的信息的缓冲区。
猜你喜欢
  • 2017-12-22
  • 2016-10-02
  • 2013-04-21
  • 2013-01-11
  • 2012-07-23
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多