代码之家  ›  专栏  ›  技术社区  ›  George Profenza

如何在处理中更改glsl shader参数

  •  1
  • George Profenza  · 技术社区  · 15 年前

    我正在使用处理在OpenGL中使用明暗器。我对这个很不了解,有点迷路了。

    我发现 this thread 其中有一个关于如何在处理中使用glsl明暗器的示例。

    我只是尝试在我使用的明暗器中更改lightposition参数。但是我不知道如何访问它。

    到目前为止,我的代码是:

    import processing.opengl.*;
    import javax.media.opengl.*;
    import javax.media.opengl.glu.*;
    import com.sun.opengl.util.*; 
    
    PGraphicsOpenGL pgl;
    GL gl;
    GLSL glsl;
    GLU glu;
    GLUT glut;
    boolean glInit;
    int glutSolidIndex = 7;
    
    void setup()
    {
      size(600, 500, OPENGL);
    
      glu = new GLU();
      glut = new GLUT();
    
      pgl = (PGraphicsOpenGL) g;
      gl = pgl.gl;
    }
    
    void draw()
    {
      background(0);
      PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;
      GL gl = pgl.beginGL();
    
      if(!glInit){
        glsl=new GLSL();
        glsl.loadVertexShader("toon.vs");
        glsl.loadFragmentShader("toon.fs");
        glsl.useShaders();
    
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDepthFunc(GL.GL_LESS);
        gl.glShadeModel(GL.GL_SMOOTH);
        glInit = true;
      }
    
      gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
    
      //TRS
      gl.glTranslatef(width * .5, height * .5,0.0f);
      gl.glRotatef(160,1,0,0);
      gl.glRotatef(frameCount * .5,0,1,0);
      gl.glRotatef(frameCount * .5,0,0,1);
      gl.glScalef(80,80,80);
      // draw 
      glsl.startShader();
        gl.glColor3f(1.0f, 0.5f, 0.0f);
        gl.glFrontFace(gl.GL_CW);
        glutSolid();
        gl.glFrontFace(gl.GL_CCW);
      glsl.endShader();
    
      pgl.endGL();
    }
    
    void glutSolid(){
     switch(glutSolidIndex){
       case 0:
         glut.glutSolidCube(1);
       break;
       case 1:
         glut.glutSolidTetrahedron();
       break;
       case 2:
         glut.glutSolidOctahedron();
       break;
       case 3:
         glut.glutSolidDodecahedron();
       break;
       case 4:
         glut.glutSolidIcosahedron();
       break;
       case 5:
         glut.glutSolidSphere(1,8,6);
       break;
       case 6:
         glut.glutSolidTorus(1,1.5,8,6);
       break;
       case 7:
         glut.glutSolidTeapot(1);
       break;
     }
    }
    void keyPressed(){
      if((int)key >= 49 && (int)key <= 56) glutSolidIndex = (int)(key) - 49;
    }
    

    GLSL类如下所示:

    import processing.opengl.*;
    import javax.media.opengl.*;
    import java.nio.IntBuffer;
    import java.nio.ByteBuffer;
    import com.sun.opengl.util.BufferUtil;
    
    class GLSL
    {
      int programObject;
      GL gl;
      boolean vertexShaderEnabled;
      boolean vertexShaderSupported; 
      int vs;
      int fs;
    
      GLSL()
      {
        PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;
        gl = pgl.gl;
        //gl=((PGraphicsGL)g).gl;
        String extensions = gl.glGetString(GL.GL_EXTENSIONS);
        vertexShaderSupported = extensions.indexOf("GL_ARB_vertex_shader") != -1;
        vertexShaderEnabled = true;    
        programObject = gl.glCreateProgramObjectARB(); 
        vs=-1;
        fs=-1;
      }
    
      void loadVertexShader(String file)
      {
        String shaderSource=join(loadStrings(file),"\n");
        vs = gl.glCreateShaderObjectARB(GL.GL_VERTEX_SHADER_ARB);
        gl.glShaderSourceARB(vs, 1, new String[]{shaderSource},(int[]) null, 0);
        gl.glCompileShaderARB(vs);
        checkLogInfo(gl, vs);
        gl.glAttachObjectARB(programObject, vs); 
      }
    
      void loadFragmentShader(String file)
      {
        String shaderSource=join(loadStrings(file),"\n");
        fs = gl.glCreateShaderObjectARB(GL.GL_FRAGMENT_SHADER_ARB);
        gl.glShaderSourceARB(fs, 1, new String[]{shaderSource},(int[]) null, 0);
        gl.glCompileShaderARB(fs);
        checkLogInfo(gl, fs);
        gl.glAttachObjectARB(programObject, fs); 
      }
    
      int getAttribLocation(String name)
      {
        return(gl.glGetAttribLocationARB(programObject,name));
      }
    
      int getUniformLocation(String name)
      {
        return(gl.glGetUniformLocationARB(programObject,name));
      }
    
      void useShaders()
      {
        gl.glLinkProgramARB(programObject);
        gl.glValidateProgramARB(programObject);
        checkLogInfo(gl, programObject);
      }
    
      void startShader()
      {
        gl.glUseProgramObjectARB(programObject); 
      }
    
      void endShader()
      {
        gl.glUseProgramObjectARB(0); 
      }
    
      void checkLogInfo(GL gl, int obj)  
      {
        IntBuffer iVal = BufferUtil.newIntBuffer(1);
        gl.glGetObjectParameterivARB(obj, GL.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);
    
        int length = iVal.get();
        if (length <= 1)  
        {
        return;
        }
        ByteBuffer infoLog = BufferUtil.newByteBuffer(length);
        iVal.flip();
        gl.glGetInfoLogARB(obj, length, iVal, infoLog);
        byte[] infoBytes = new byte[length];
        infoLog.get(infoBytes);
        println("GLSL Validation >> " + new String(infoBytes));
      } 
    }
    

    我用的是 toon shader 由Philip Rideout在3dlabs上写的。

    这是顶点明暗器:

    // Vertex shader for cartoon-style shading
    //
    // Author: Philip Rideout
    //
    // Copyright (c) 2005-2006 3Dlabs Inc. Ltd.
    //
    // See 3Dlabs-License.txt for license information
    //
    
    varying vec3 Normal;
    
    void main(void)
    {
        Normal = normalize(gl_NormalMatrix * gl_Normal);
        #ifdef __GLSL_CG_DATA_TYPES // Fix clipping for Nvidia and ATI
        gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
        #endif
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    }
    

    下面是片段着色:

    /* http://www.lighthouse3d.com/opengl/glsl/index.php?toon2 */
    
    varying vec3 Normal;
    vec3 LightPosition = vec3(10.0, 10.0, 20.0);
    
    void main()
    {
        vec4 color1 = gl_FrontMaterial.diffuse;
        vec4 color2;
    
        float intensity = dot(normalize(LightPosition),Normal);
    
        if (intensity > 0.95)      color2 = vec4(1.0, 1.0, 1.0, 1.0);
        else if (intensity > 0.75) color2 = vec4(0.8, 0.8, 0.8, 1.0);
        else if (intensity > 0.50) color2 = vec4(0.6, 0.6, 0.6, 1.0);
        else if (intensity > 0.25) color2 = vec4(0.4, 0.4, 0.4, 1.0);
        else                       color2 = vec4(0.2, 0.2, 0.2, 1.0);
    
        gl_FragColor = color1 * color2;
    }
    

    任何提示都会有帮助。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Daniel Yankowsky    15 年前

    你的问题是光的位置没有被宣布为制服。应该这样声明:

    uniform vec3 LightPosition;
    

    将此添加到GLSL类:

    void uniform3f(int location, float v0, float v1, float v2)
    {
      gl.glUniform3fARB(location, v0, v1, v2);
    }
    

    现在需要实际初始化lightposition参数。后 startShader() ,但在你打电话之前 glutSolid() 这样做:

    glsl.uniform3f(glsl.getUniformLocation("LightPosition"), 10.0, 10.0, 20.0);
    

    那应该管用(对我有用)。

        2
  •  1
  •   Ron Warholic    15 年前

    我没有使用处理,但在C语言中,您可以执行如下操作:

    GLint lightPos = glGetUniformLocation(shaderHandle, "LightPosition");
    glUniform3f(lightPos, 5.0f, 5.0f, 5.0f);