Domanda

sto giocando con shader in OpenGL utilizzando Processing. Sono abbastanza niubbo a questo e un po 'perso.

questo filo che ha un esempio su come utilizzare shaders GLSL in Processing.

Sto solo cercando di cambiare il parametro LightPosition nello shader che sto utilizzando. Non so come accedervi però.

Ecco il mio codice finora:

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

la classe GLSL appare così:

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

E sto utilizzando il toon shader di scritto da Philip Rideout da 3Dlabs.

Questo è il vertex 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;
}

e qui è lo shader frammento:

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

Tutti i suggerimenti saranno utili.

È stato utile?

Soluzione

Il problema è che LightPosition non è dichiarato come una divisa. Dovrebbe essere dichiarato in questo modo:

uniform vec3 LightPosition;

Aggiungi questo alla classe GLSL:

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

Sarà ora necessario inizializzare in realtà il parametro LightPosition. Dopo startShader(), ma prima di chiamare glutSolid(), fare questo:

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

Che dovrebbe funzionare (ha funzionato per me).

Altri suggerimenti

Non ho utilizzare l'elaborazione, ma in C si dovrebbe fare qualcosa di simile:

GLint lightPos = glGetUniformLocation(shaderHandle, "LightPosition");
glUniform3f(lightPos, 5.0f, 5.0f, 5.0f);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top