2012-01-11 11 views
0

さて、私はここでチュートリアルを仕事にしようとしています:http://lwjgl.org/wiki/index.php?title=GLSL_Shaders_with_LWJGLGLSL LWJGLの不具合/シェイダーは何もしませんか?

私の質問は、この例で何もしていないのですか?私はGLSLの新機能です。

ここでの主なクラスのコード

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(); 
    } 
} 

ここでは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; 
    } 

} 

は、フラグメントシェーダ

varying vec4 vertColor; 

void main(){ 
    gl_FragColor = vertColor; 
} 

のコードです頂点シェーダ:

ここで

は、私は、コードを実行したときに私が手に出力されます:http://dl.dropbox.com/u/28109593/glslss.png

答えて

3

問題は、情報ログに何も表示されていない、つまり、成功した場合にOpenGLドライバが行う傾向にあるメッセージを表示していることが原因です。 printLogInfoも検証関数として倍増しています。ログ情報があればfalseを返します。これはcreateVertShaderとcreateFragShaderに完全に良いシェーダIDをゼロにして失敗を返すように指示しています。これはまったく良いデザインではありません。これはまさにこのような理由からです(私はそれが他の誰かから来たことを知っていますので、私はあなたから個人的に離れていません)。

このプログラムのすばやい回避方法は単にprintLogInfoを常にtrueにするだけです。リンクおよび検証するためのその後

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

:あなたが最終的に行う必要があることはそうのように、glGetShader(ID、PARAM)を使用して、戻り値の状態を確認している

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 ... 

私はこれらのARB_ *の同等物を知りません、申し訳ありませんが、あなたはおそらくこの基本的なもののためにARB拡張の代わりにOpenGL 2.0 APIを使用しているはずです。とにかくシェーダを拡張機能としてサポートしているものは、とにかくシェーダを実行する価値はありません。

0

シェーダは、彼らが行うことになっているものをやっている:

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

そして、ここではスクリーンショットです。

ビデオゲームでのシェイダーの意味でのシェイダーは、シェーダーは単にGPUに直接アクセスできる方法ではないと考えてください。

色の違いが表示されないのは、色が出力されないためです。フラグメントシェーダーで設定しているものをgl_fragColorに変更してみてください。

はあなたがそのタイトルをグーグル場合は、私がオンラインブック

Learning Modern 3D Graphics Programming

でご覧になることをお勧めしたいシェーダ駆動型のOpenGL上でより多くの情報を探しているなら、それはする必要があります最初の結果。

希望すると便利です。

+0

shadersがやっていることをやっていたら、白ではなく、 'vec4(0.6、0.3、0.4、1.0)'にするべきですか? – Jimmy

+0

そのベクトル情報をgl_FragColorに格納すると、色の違いが表示されるはずです – dardo

関連する問題