Pregunta

Estoy jugando con los shaders de OpenGL usando procesamiento. Soy bastante novato en esto y un poco perdido.

este hilo que tiene un ejemplo de cómo utilizar shaders GLSL en el procesamiento.

Estoy intentando el parámetro de cambio LightPosition en el shader que estoy usando. No sé cómo acceder a él sin embargo.

Aquí está mi código hasta ahora:

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 clase GLSL se ve así:

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

Y estoy usando el toon shader escrito por Philip Rideout de 3Dlabs.

Este es el 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;
}

Y aquí está el shader fragmento:

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

¿Alguna pista serán de gran ayuda.

¿Fue útil?

Solución

Su problema es que LightPosition no se declara como un uniforme. Debe ser declarada como esto:

uniform vec3 LightPosition;

Agregue esto a la clase GLSL:

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

Ahora va a necesitar para inicializar el parámetro realidad LightPosition. Después startShader(), pero antes de llamar glutSolid(), hacer esto:

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

Eso debería funcionar (que trabajó para mí).

Otros consejos

No he utilizar Procesamiento pero en C que haría algo como:

GLint lightPos = glGetUniformLocation(shaderHandle, "LightPosition");
glUniform3f(lightPos, 5.0f, 5.0f, 5.0f);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top