2009-12-04 38 views
1

我正在使用处理在openGL中使用着色器。我很喜欢这个,有点失落。如何在处理中更改GLSL着色器参数

我发现this thread有一个关于如何在Processing中使用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)); 
    } 
} 

而且我使用来自3Dlabs的书面菲利普赖德奥特的toon shader

这是顶点着色器:

// 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; 
} 

任何提示会有所帮助。

回答

3

您的问题是LightPosition未声明为一个统一的。应该声明如下:

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

这应该工作(它的工作对我来说)。

+0

woo hoo!那也适合工作!^ _ ^ –

1

我还没有使用处理但在C你会做这样的事情:

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

使得有很大的意义,它应该工作,但我有2个问题:1。 我不从哪里 2. GLSL类从加工进口论坛闪烁已经有一个类似的方法:getUniformLocation,但它返回一个int。我打印结果是-1,看起来不太好。 int lightPos = glsl.getUniformLocation(“LightPosition”); println(lightPos); println(gl.glGetUniformLocationARB(glsl.programObject,“LightPosition”)); Both print -1 :( –

+0

看到上面的答案,那实际上是写在Processing中的。 –