简体   繁体   English

GLSL LWJGL的问题/着色器什么都不做?

[英]GLSL LWJGL woes/Shaders do nothing?

Okay, so I'm trying to get the tutorial here to work: http://lwjgl.org/wiki/index.php?title=GLSL_Shaders_with_LWJGL 好的,因此,我试图在此使用本教程: http : //lwjgl.org/wiki/index.php?title=GLSL_Shaders_with_LWJGL

My question is why aren't my shaders doing anything in this example? 我的问题是为什么在此示例中我的着色器不做任何事情? I'm very new to GLSL. 我是GLSL的新手。

here is the code for the main class 这是主类的代码

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;

/*
* Sets up the Display, the GL context, and runs the main game
loop.
*
* @author Stephen Jones
*/
public class GLSLTest{

    Box box;
    private boolean done=false; //game runs until done is set to true

    public GLSLTest(){
        init();

        while(!done){
            if(Display.isCloseRequested())
            done=true;
            render();
            Display.update();
        }

        Display.destroy();
    }

    private void render(){
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT |
        GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glLoadIdentity();

        box.draw();
    }

    private void init(){
        int w=1024;
        int h=768;

        try{
            Display.setDisplayMode(new DisplayMode(w, h));
            Display.setVSyncEnabled(true);
            Display.setTitle("Shader Setup");
            Display.create();
        }catch(Exception e){
            System.out.println("Error setting up display");
            System.exit(0);
        }

        GL11.glViewport(0,0,w,h);
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(45.0f, ((float)w/(float)h),0.1f,100.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();
        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glClearDepth(1.0f);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDepthFunc(GL11.GL_LEQUAL);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT,
        GL11.GL_NICEST);

        box = new Box();
    }

    public static void main(String[] args){
        new GLSLTest();
    }
}

Here is the code for the Box class: 这是Box类的代码:

import org.lwjgl.opengl.GL11;
import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.Util;

/**
* The vertex and fragment shaders are setup when the box object is
* constructed. They are applied to the GL state prior to the box
* being drawn, and released from that state after drawing.
* @author Stephen Jones
*/
public class Box {

    /*
    * if the shaders are setup ok we can use shaders, otherwise we just
    * use default settings
    */
    private boolean useShader=true;

    /*
    * program shader, to which is attached a vertex and fragment shaders.
    * They are set to 0 as a check because GL will assign unique int
    * values to each
    */
    private int shader=0;
    private int vertShader=0;
    private int fragShader=0;

    public Box(){

        /*
        * create the shader program. If OK, create vertex
        * and fragment shaders
        */
        shader=ARBShaderObjects.glCreateProgramObjectARB();

        if(shader!=0){
            vertShader=createVertShader("screen.vert");
            fragShader=createFragShader("screen.frag");
        }
        else useShader=false;

        /*
        * if the vertex and fragment shaders setup sucessfully,
        * attach them to the shader program, link the sahder program
        * (into the GL context I suppose), and validate
        */
        if(vertShader !=0 && fragShader !=0){
            ARBShaderObjects.glAttachObjectARB(shader, vertShader);
            ARBShaderObjects.glAttachObjectARB(shader, fragShader);
            ARBShaderObjects.glLinkProgramARB(shader);
            ARBShaderObjects.glValidateProgramARB(shader);
            useShader=printLogInfo(shader);
        }else useShader=false;
    }

    /*
    * If the shader was setup succesfully, we use the shader. Otherwise
    * we run normal drawing code.
    */
    public void draw(){
        if(useShader) {
            ARBShaderObjects.glUseProgramObjectARB(shader);
        }
        GL11.glLoadIdentity();
        GL11.glTranslatef(0.0f, 0.0f, -10.0f);
        GL11.glColor3f(1.0f, 1.0f, 1.0f);//white

        GL11.glBegin(GL11.GL_QUADS);
        GL11.glVertex3f(-1.0f, 1.0f, 0.0f);
        GL11.glVertex3f(1.0f, 1.0f, 0.0f);
        GL11.glVertex3f(1.0f, -1.0f, 0.0f);
        GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
        GL11.glEnd();

        //release the shader
        ARBShaderObjects.glUseProgramObjectARB(0);

    }

    /*
    * With the exception of syntax, setting up vertex and fragment shaders
    * is the same.
    * @param the name and path to the vertex shader
    */
    private int createVertShader(String filename){
        //vertShader will be non zero if succefully created

        vertShader=ARBShaderObjects.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);
        //if created, convert the vertex shader code to a String
        if(vertShader==0){return 0;}
        String vertexCode="";
        String line;
        try{
            BufferedReader reader=new BufferedReader(new FileReader(filename));
            while((line=reader.readLine())!=null){
                vertexCode+=line + "\n";
            }
        }catch(Exception e){
            System.out.println("Fail reading vertex shading code");
            return 0;
        }
        /*
        * associate the vertex code String with the created vertex shader
        * and compile
        */
        ARBShaderObjects.glShaderSourceARB(vertShader, vertexCode);
        ARBShaderObjects.glCompileShaderARB(vertShader);
        //if there was a problem compiling, reset vertShader to zero
        if(!printLogInfo(vertShader)){
            vertShader=0;
        }
        //if zero we won't be using the shader
        return vertShader;
    }

    //same as per the vertex shader except for method syntax
    private int createFragShader(String filename){

        fragShader=ARBShaderObjects.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
        if(fragShader==0){return 0;}
            String fragCode="";
            String line;
        try{
            BufferedReader reader=new BufferedReader(new FileReader(filename));
            while((line=reader.readLine())!=null){
                fragCode+=line + "\n";
            }
        }catch(Exception e){
            System.out.println("Fail reading fragment shading code");
            return 0;
        }
        ARBShaderObjects.glShaderSourceARB(fragShader, fragCode);
        ARBShaderObjects.glCompileShaderARB(fragShader);
        if(!printLogInfo(fragShader)){
            fragShader=0;
        }

        return fragShader;
    }

    private static boolean printLogInfo(int obj){
        IntBuffer iVal = BufferUtils.createIntBuffer(1);
        ARBShaderObjects.glGetObjectParameterARB(obj,
        ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);

        int length = iVal.get();
        if (length > 1) {
            // We have some info we need to output.
            ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
            iVal.flip();
            ARBShaderObjects.glGetInfoLogARB(obj, iVal, infoLog);
            byte[] infoBytes = new byte[length];
            infoLog.get(infoBytes);
            String out = new String(infoBytes);
            System.out.println("Info log:\n"+out);
        }
        else return true;
        return false;
    }

}

Here is the code for the fragment shader 这是片段着色器的代码

varying vec4 vertColor;

void main(){
    gl_FragColor = vertColor;
}

and vertex shader: 和顶点着色器:

varying vec4 vertColor;

void main(){
    gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
    vertColor = vec4(0.6, 0.3, 0.4, 1.0);
}

Here is the output I get when I run the code: 这是我运行代码时得到的输出:

Info log:
Vertex shader was successfully compiled to run on hardware.
Info log:
Fragment shader was successfully compiled to run on hardware.

And here is a screenshot: http://dl.dropbox.com/u/28109593/glslss.png 这是屏幕截图: http : //dl.dropbox.com/u/28109593/glslss.png

The problem is due to the fact that you're seeing anything in the Info log at all, ie it's yielding a message on success, the way some OpenGL drivers are inclined to do. 该问题是由于您实际上在Info日志中看不到任何东西,即它在成功时产生一条消息,这是某些OpenGL驱动程序倾向于这样做的方式。 printLogInfo is also doubling as a validation function, and returning false if there was any log info, which is telling createVertShader and createFragShader to zero out your perfectly good shader id and return a failure. printLogInfo还将作为验证函数加倍,如果有任何日志信息,则返回false,这告诉createVertShader和createFragShader将完美的着色器ID归零,并返回失败。 It's really not at all a good design, for reasons exactly like this (and I know it came from someone else, so I know I'm not slagging you off personally :) 出于这样的原因,它实际上根本不是一个好的设计(而且我知道它是来自其他人的,所以我知道我不会亲自给你排渣:)

A quick workaround for this program ONLY would be to simply make printLogInfo always return true. 此程序的一个快速解决方法是仅使printLogInfo始终返回true。 What you ultimately need to do is check the return status, using glGetShader(id, param), like so: 您最终要做的是使用glGetShader(id,param)检查返回状态,如下所示:

glCompileShader(obj)
if (glGetShader(obj, GL_COMPILE_STATUS) == GL_FALSE
    ... handle error here ...

Then for linking and validating: 然后进行链接和验证:

glLinkProgram(obj)
if (glGetProgram(obj, GL_LINK_STATUS) == GL_FALSE
    ... handle error here ...

glValidateProgram(obj)
if (glGetProgram(obj, GL_VALIDATE_STATUS) == GL_FALSE
    ... handle error here ...

I don't know the ARB_* equivalents of these, sorry, but you probably should be using OpenGL 2.0 API instead of ARB extensions for something this basic. 抱歉,我不知道这些的ARB_ *等效项,但是您可能应该使用OpenGL 2.0 API而不是ARB扩展来实现这一基本功能。 Anything that still only supports shaders as an extension is probably not worth doing shaders on anyway. 仍然仅支持着色器作为扩展的任何内容可能都不值得进行着色器。

The shaders are doing what they're supposed to do. 着色器正在执行应做的工作。

Don't think of shaders in the sense of what you hear in video games, shaders are simply a way of having direct access to the GPU. 不要像在视频游戏中听到的那样考虑着色器,着色器只是直接访问GPU的一种方式。

The reason you're not seeing a difference in color is due to the fact that color is not being output, try changing what is being set in the fragment shader for gl_fragColor . 之所以没有看到颜色差异,是因为没有输出颜色,请尝试更改在片段着色器中为gl_fragColor设置的gl_fragColor

If you're looking for more information on shader driven opengl I'd suggest taking a look at the online book 如果您需要有关着色器驱动的opengl的更多信息,建议您看一下在线书

Learning Modern 3D Graphics Programming 学习现代3D图形编程

If you google that title, it should be the first result. 如果您搜索该标题,它应该是第一个结果。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM