Package com.mystictri.neotextureedit

Source Code of com.mystictri.neotextureedit.OpenGLTextureRenderCanvas$GLPreviewParameters

package com.mystictri.neotextureedit;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.swing.JPopupMenu;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.AWTGLCanvas;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.Util;
import org.lwjgl.util.glu.GLU;

import engine.base.FMath;
import engine.base.Logger;
import engine.base.Utils;
import engine.base.Vector3;
import engine.graphics.synthesis.texture.Channel;
import engine.parameters.AbstractParam;
import engine.parameters.EnumParam;
import engine.parameters.FloatParam;
import engine.parameters.IntParam;
import engine.parameters.LocalParameterManager;
import engine.parameters.ParamChangeListener;

/**
* This canvas is used to preview a texture in an OpenGL renderer. It is not implemented for performance but for
* easy and flexible preview rendering (thus some textures are managed as individual textures even though they
* may be combined with other textures).
* @author Holger Dammertz
*
*/
class OpenGLTextureRenderCanvas extends AWTGLCanvas implements Runnable, MouseListener, MouseMotionListener, KeyListener, ParamChangeListener {
  private static final long serialVersionUID = -1713673512688807546L;
 
  static final boolean USE_THREAD = true; // This is a temp variable to experiment with a thread for rendering vs. selective repaint on mouse clicks (the second
                      // method currently has the problem of disappearing render windows; the first has a higher cpu load
 

  boolean initialized = false;
  Thread renderThread;
 
  public boolean running = true;
  public boolean pause = true;
 
 
  final int TEXTURE_RESX = 256;
  final int TEXTURE_RESY = 256;
 
  int GLXres, GLYres;

  long timer = 0;
  long dtCount = 0;
  long frames = 0;
 
  //!!TODO: encapsulate shader into an extra class
  int texidDiffuse = 0;
  int texidNormal = 0;
  int texidSpecWeight = 0;
  int texidHeightmap = 0;
 
  int previewProgram = 0;
 
  int u_WS_EyePos_loc;
  int u_CameraONB_loc;
  int _2dDiffuseMap_loc;
  int _2dNormalMap_loc;
  int _2dSpecWeightMap_loc;
  int _2dHeightMap_loc;
 
  int u_SpecularPower_loc;
  int u_POM_Strength_loc;
  int u_TexScale_loc;
  int u_Ambient_loc;
 
  JPopupMenu settingsPopupMenu;
 
  static class GLPreviewParameters extends LocalParameterManager {
    public EnumParam previewObject = CreateLocalEnumParam("Object", "Square,Cube,Cylinder"); // Sphere
    public FloatParam specularPower = CreateLocalFloatParam("Spec. Power", 20.0f, 0.f, 200.0f);
    public FloatParam pomStrength = CreateLocalFloatParam("POM Strength", 0.25f, 0.f, 1.0f).setDefaultIncrement(0.125f);
    public FloatParam ambient = CreateLocalFloatParam("Ambient", 0.5f, 0.f, 1.0f).setDefaultIncrement(0.125f);
    public IntParam texScaleU = CreateLocalIntParam("TexScale U", 1, 1, 8);
    public IntParam texScaleV = CreateLocalIntParam("TexScale V", 1, 1, 8);
   
    // hidden parameters
    public FloatParam rotX = CreateLocalFloatParam("CamRotX", 45.0f, 3.f, 89.0f);
    public FloatParam rotY = CreateLocalFloatParam("CamRotY", 0.0f, -1.f, 360.0f);
    public FloatParam camDist = CreateLocalFloatParam("CamDist", 2.5f, 0.5f, 8.0f);
   
    {
      rotX.hidden = true;
      rotY.hidden = true;
      camDist.hidden = true;
    }
  }
 
  GLPreviewParameters params = new GLPreviewParameters();

 
  // very basic preview shader (does compute the camera transform extra to provide world space coordinates for the fragment shader)
  String previewVertexShader =    
    "uniform vec3 u_WS_EyePos; "+
    "uniform mat3 u_CameraONB; "+
    "attribute vec3 a_OS_tangent; "+
   
    "varying vec3 v_WS_vertex; "+
    "varying vec3 v_WS_normal; "+
    "varying vec3 v_WS_tangent; "+
   
    "void main(void) { "+
    "  gl_TexCoord[0] = gl_MultiTexCoord0; "+
   
    "  v_WS_vertex = vec3(gl_ModelViewMatrix * gl_Vertex); "+
    "  v_WS_normal = vec3(gl_NormalMatrix * gl_Normal); "+
    "  v_WS_tangent = vec3(gl_NormalMatrix * a_OS_tangent); "+
   
    "  gl_Position = gl_ProjectionMatrix * vec4((v_WS_vertex - u_WS_EyePos) * u_CameraONB, 1); "+
    "}";
 
  // very basic preview shader
  String previewFragmentShader =
    "uniform vec3 u_WS_EyePos; " +

    "uniform sampler2D _2dTex0; " +
    "uniform sampler2D _2dNormalMap; " +
    "uniform sampler2D _2dSpecWeightMap; " +
    "uniform sampler2D _2dHeightMap; " +

    "varying vec3 v_WS_vertex; " +
    "varying vec3 v_WS_normal; " +
    "varying vec3 v_WS_tangent; " +
    "" +
    "uniform float u_SpecularPower; " +
    "uniform float u_POM_Strength; " +
    "uniform vec2 u_TexScale; " +
    "uniform float u_Ambient; " +
    "" +

    "void main(void){ " +
    "  vec3 lightPos = vec3(20.0, 60.0, 40.0); " +

    "  vec3 lightDir = normalize(lightPos - v_WS_vertex); " +

    "  mat3 onb; " +
    "  onb[2] = normalize(v_WS_normal); " +
    "  onb[0] = normalize(v_WS_tangent - dot(onb[2], v_WS_tangent)*onb[2]); " +
    "  onb[1] = cross(onb[2], onb[0]); " +

    "  vec3 rayDir = v_WS_vertex - u_WS_EyePos; " +
    "  vec3 eyeDir = normalize(rayDir * onb); " +

    "  vec3 pos = vec3(gl_TexCoord[0].xy * u_TexScale, 1.0); " +

    "   rayDir = eyeDir; " +
    "   if (rayDir.z > 0.0) rayDir.z = -rayDir.z; " +
    "  if (u_POM_Strength > 0.0) {" +
    "     rayDir.z /= 0.25*u_POM_Strength; " +
    "     rayDir.x *= 0.5; " +
    "     rayDir.y *= 0.5; " +
    "     for (int i = 0; i < 512; i++) { " +
    "         if (pos.z < 1.0-(texture2D(_2dHeightMap, pos.xy).r)) break; " +
    "       pos += rayDir*0.001; " +
    "     } " +
    "   } " +

    "  vec3 normal = onb * normalize(texture2D(_2dNormalMap, pos.xy).rgb * 2.0 - 1.0); " +

    "  vec3 refl = reflect(lightDir, normal); " +
    "  float SpecWeightyness = texture2D(_2dSpecWeightMap, pos.xy).x;" +
    "  float spec = pow(max(dot(refl, eyeDir), 0.0), u_SpecularPower)*0.5*SpecWeightyness; " +
    "  float diff = dot(lightDir, normal); " +
    "  if (diff < 0.0) diff = 0.0; " +
    "  diff = min(diff+u_Ambient, 1.0); " +
    "  vec4 color = vec4(texture2D(_2dTex0, pos.xy).xyz, 0.0) * diff + spec; " +

    "  gl_FragColor = color; " +
    "}";
 

 
 
 
  int getUniformLocation(String loc_name, int programID) {
    byte[] bs = loc_name.getBytes();
    ByteBuffer b = Utils.allocByteBuffer(bs.length+1);
    b.put(bs); b.put((byte)0);
    b.flip();
    int ret = ARBShaderObjects.glGetUniformLocationARB(programID, b);
    if (ret == -1) {
      Logger.logWarning(this, "    WARNING: Shader: "+programID+": could not get uniform location " + loc_name);
    }
    Util.checkGLError();
    return ret;
  }
 
  void loadShaderLocations() {
    u_WS_EyePos_loc = getUniformLocation("u_WS_EyePos", previewProgram);
    u_CameraONB_loc = getUniformLocation("u_CameraONB", previewProgram);
   
    _2dDiffuseMap_loc = getUniformLocation("_2dTex0", previewProgram);
    _2dNormalMap_loc  = getUniformLocation("_2dNormalMap", previewProgram);
    _2dSpecWeightMap_loc  = getUniformLocation("_2dSpecWeightMap", previewProgram);
    _2dHeightMap_loc  = getUniformLocation("_2dHeightMap", previewProgram);
   
    u_SpecularPower_loc = getUniformLocation("u_SpecularPower", previewProgram);
    u_POM_Strength_loc = getUniformLocation("u_POM_Strength", previewProgram);
    u_TexScale_loc = getUniformLocation("u_TexScale", previewProgram);
    u_Ambient_loc = getUniformLocation("u_Ambient", previewProgram);
   
    bindTangentAttribute("a_OS_tangent");
  }
 
 
 
  public void bindTangentAttribute(String name) {
    ByteBuffer nameb = Utils.allocByteBuffer(name.length()+1);
    nameb.put(name.getBytes()); nameb.put((byte)0);
    nameb.flip();
    GL20.glBindAttribLocation(previewProgram, 1, nameb);
  }
 
 
 
  public OpenGLTextureRenderCanvas(int xres, int yres, JPopupMenu settingsPopupMenu) throws LWJGLException {
    super();

    GLXres = xres;
    GLYres = yres;
    this.settingsPopupMenu = settingsPopupMenu;
   
    addMouseMotionListener(this);
    addMouseListener(this);
    addKeyListener(this);
   
    for (AbstractParam p : params.m_LocalParameters) {
      if (p.hidden) continue;
      p.addParamChangeListener(this);
    }
  }
 
  public void startRenderThread() {
    if (!USE_THREAD) return;
   
    if (renderThread == null) {
      renderThread = new Thread(this);
      renderThread.start();
    } else {
      System.err.println("WARNING: Render Thread is already running");
    }
  }

  public void run() {
    while (renderThread.isAlive()) {
      repaint();
      try {
        Thread.sleep(1000/10);
      } catch (InterruptedException ie) {
        ie.printStackTrace();
      }
    }
  }
 
  void initGLState() {
    GL11.glViewport(0, 0, getWidth(), getHeight());
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    //GL11.glClearColor(62.0f / 100.0f, 77.0f / 100.0f, 100.0f / 100.0f, 1.0f);
    GL11.glClearColor(64.0f / 255.0f, 64.0f / 255.0f, 64.0f / 255.0f, 1.0f);

   
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GLU.gluPerspective(60.0f, (float)GLXres/(float)GLYres, 0.1f, 100.0f);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);

   
    previewProgram = getShaderProgram(previewVertexShader, previewFragmentShader);
   
   
    loadShaderLocations();

    // hmm: temp initialization here
    // create the empty textures (later they are updated from the channels)
    texidDiffuse = create2dTexture(0x7F7FFFFF);
    texidNormal = create2dTexture(0x7F7FFFFF);
    texidSpecWeight = create2dTexture(0xFFFFFFFF);
    texidHeightmap = create2dTexture(0xFFFFFFFF);
   
  }
 
 
  boolean requestUpdateDiffuse = false;
  boolean requestUpdateNormal = false;
  boolean requestUpdateSpecWeight = false;
  boolean requestUpdateHeightmap = false;
  Channel _updateDiffuse = null;
  Channel _updateNormal = null;
  Channel _updateSpecWeight = null;
  Channel _updateHeightmap = null;
 
  public synchronized void updateDiffuseMap(Channel c) {
    if (c != null && !c.chechkInputChannels()) {
      Logger.logWarning(this, "Incomplete input channel in diffuse map.");
      _updateDiffuse = null;
    } else {
      _updateDiffuse = c;
    }
    requestUpdateDiffuse = true;
    repaint();
  }
 
  public synchronized void updateNormalMap(Channel c) {
    if (c != null && !c.chechkInputChannels()) {
      Logger.logWarning(this, "Incomplete input channel in normal map.");
      _updateNormal = null;
    } else {
      _updateNormal = c;
    }
    requestUpdateNormal = true;
    repaint();
  }
 
  public synchronized void updateSpecWeightMap(Channel c) {
    if (c != null && !c.chechkInputChannels()) {
      Logger.logWarning(this, "Incomplete input channel in specular map.");
      _updateSpecWeight = null;
    } else {
      _updateSpecWeight = c;
    }
    requestUpdateSpecWeight = true;
    repaint();
  }
 
  public synchronized void updateHeightMap(Channel c) {
    if (c != null && !c.chechkInputChannels()) {
      Logger.logWarning(this, "Incomplete input channel in height map.");
      _updateHeightmap = null;
    } else {
      _updateHeightmap = c;
    }
    requestUpdateHeightmap = true;
    repaint();
  }
 
 
  public FloatBuffer m_CamONB = Utils.allocFloatBuffer(9);
 
  final Vector3 UP = new Vector3(0,0,1);
  void updateCamera() {
    final Vector3 u = new Vector3();
    final Vector3 v = new Vector3();
    final Vector3 w = new Vector3();
    final Vector3 eye = new Vector3();
    float t = (params.rotY.get()-90) * ((float) Math.PI / 180.0f);
    float p = (90 - params.rotX.get()) * ((float) Math.PI / 180.0f);

    w.set(FMath.cos(t) * FMath.sin(p), FMath.sin(t) * FMath.sin(p), FMath.cos(p));
    w.normalize();
    u.cross_ip(UP, w);
    u.normalize();
    v.cross_ip(w, u);
   
   
    m_CamONB.put(0, u.x);
    m_CamONB.put(1, u.y);
    m_CamONB.put(2, u.z);
    m_CamONB.put(3, v.x);
    m_CamONB.put(4, v.y);
    m_CamONB.put(5, v.z);
    m_CamONB.put(6, w.x);
    m_CamONB.put(7, w.y);
    m_CamONB.put(8, w.z);
   
    eye.mult_add_ip(params.camDist.get(), w);

    ARBShaderObjects.glUniform3fARB(u_WS_EyePos_loc, eye.x, eye.y, eye.z);
    ARBShaderObjects.glUniformMatrix3ARB(u_CameraONB_loc, false, m_CamONB);
  }
 
  synchronized void render() {
    // Process the requests made from another thread:
   
    if (requestUpdateDiffuse) {
      if (_updateDiffuse != null) update2dTexture(ChannelUtils.createAndComputeImage(_updateDiffuse, TEXTURE_RESX, TEXTURE_RESY, null, 0), texidDiffuse);
      else update2dTexture_ConstanctColor(0x7F7FFFFF, texidDiffuse);
      _updateDiffuse = null;
      requestUpdateDiffuse = false;
    }
    if (requestUpdateNormal) {
      if (_updateNormal != null) update2dTexture(ChannelUtils.createAndComputeImage(_updateNormal, TEXTURE_RESX, TEXTURE_RESY, null, 0), texidNormal);
      else update2dTexture_ConstanctColor(0x7F7FFFFF, texidNormal);
      _updateNormal = null;
      requestUpdateNormal = false;
    }
    if (requestUpdateSpecWeight) {
      if (_updateSpecWeight != null) update2dTexture(ChannelUtils.createAndComputeImage(_updateSpecWeight, TEXTURE_RESX, TEXTURE_RESY, null, 0), texidSpecWeight);
      else update2dTexture_ConstanctColor(0xFFFFFFFF, texidSpecWeight);
      _updateSpecWeight = null;
      requestUpdateSpecWeight = false;
    }
    if (requestUpdateHeightmap) {
      if (_updateHeightmap != null) update2dTexture(ChannelUtils.createAndComputeImage(_updateHeightmap, TEXTURE_RESX, TEXTURE_RESY, null, 0), texidHeightmap);
      else update2dTexture_ConstanctColor(0xFFFFFFFF, texidHeightmap);
      _updateHeightmap = null;
      requestUpdateHeightmap = false;
    }

   
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
   
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();
   
   
    ARBShaderObjects.glUseProgramObjectARB(previewProgram);
    updateCamera();
   
    GL13.glActiveTexture(GL13.GL_TEXTURE0+0);
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texidDiffuse);
    ARBShaderObjects.glUniform1iARB(_2dDiffuseMap_loc, 0);     
   
    GL13.glActiveTexture(GL13.GL_TEXTURE0+1);
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texidNormal);
    ARBShaderObjects.glUniform1iARB(_2dNormalMap_loc, 1);     
   
    GL13.glActiveTexture(GL13.GL_TEXTURE0+2);
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texidSpecWeight);
    ARBShaderObjects.glUniform1iARB(_2dSpecWeightMap_loc, 2);     

    GL13.glActiveTexture(GL13.GL_TEXTURE0+3);
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texidHeightmap);
    ARBShaderObjects.glUniform1iARB(_2dHeightMap_loc, 3);     

    ARBShaderObjects.glUniform1fARB(u_SpecularPower_loc, params.specularPower.get());
    ARBShaderObjects.glUniform1fARB(u_POM_Strength_loc, params.pomStrength.get());
    ARBShaderObjects.glUniform2fARB(u_TexScale_loc, params.texScaleU.get(), params.texScaleV.get());
    ARBShaderObjects.glUniform1fARB(u_Ambient_loc, params.ambient.get());
   
    float[] vData;
    int[] idx;
    if (params.previewObject.getEnumPos() == 0) {
      vData = PlaneVertexData;
      idx = PlaneIndices;
    } else if (params.previewObject.getEnumPos() == 1) {
      vData = CubeVertexData;
      idx = CubeIndices;
    } else  {
      vData = CylinderVertexData;
      idx = CylinderIndices;
    }
   
   
    GL11.glBegin(GL11.GL_TRIANGLES);
    for (int i = 0; i < idx.length; i++) {
      int j = idx[i]*11;
      GL11.glNormal3f(vData[j+3],vData[j+4],vData[j+5]);
      GL11.glTexCoord2f(vData[j+9],vData[j+10]);
      GL20.glVertexAttrib3f(1, vData[j+6],vData[j+7],vData[j+8]);
      GL11.glVertex3f(vData[j+0],vData[j+1],vData[j+2]);
    }
    GL11.glEnd();
   
   
    GL13.glActiveTexture(GL13.GL_TEXTURE0);
  }
 
 
 
 
  protected void paintGL() {
    try {
      if (!initialized) {
        if (getContext() != null) {
          initGLState();
          timer = System.currentTimeMillis();
          initialized = true;
        }
      }
     
      if (initialized) {
        render();
        swapBuffers();
      }
    } catch (LWJGLException e) {
      e.printStackTrace();
    }
  }

 
  int mouseOX = 0;
  int mouseOY = 0;
  int mouseButton;

  public void mouseDragged(MouseEvent e) {
    int dx = e.getX() - mouseOX;
    int dy = e.getY() - mouseOY;

    mouseOX = e.getX();
    mouseOY = e.getY();
   
    if (e.isShiftDown()) {
      params.camDist.increment(dy/10.0f);
    } else {
      params.rotX.increment(dy);
      params.rotY.increment(-dx);
     
      if (params.rotY.get() >= 360) params.rotY.increment(-360);
      if (params.rotY.get() < 0) params.rotY.increment(360);
    }
   
    repaint();
  }

  public void mouseMoved(MouseEvent e) {
  }

  public void keyPressed(KeyEvent e) {
  }

  public void keyReleased(KeyEvent e) {
  }

  public void keyTyped(KeyEvent e) {
  }

  public void mouseClicked(MouseEvent e) {
    System.out.println(e);
  }

  public void mouseEntered(MouseEvent e) {
    requestFocus();
  }

  public void mouseExited(MouseEvent e) {
  }

  public void mousePressed(MouseEvent e) {
    mouseOX = e.getX();
    mouseOY = e.getY();
    mouseButton = e.getButton();
   
    if (e.isPopupTrigger()) {
      settingsPopupMenu.show(e.getComponent(), e.getX(), e.getY());
    }
  }

  public void mouseReleased(MouseEvent e) {
  }
 
 
  public int genTexID() {
    IntBuffer i = Utils.allocIntBuffer(1);
    GL11.glGenTextures(i);
    return i.get(0);
  }
 
 
 
  ByteBuffer bbuf = Utils.allocByteBuffer(TEXTURE_RESX * TEXTURE_RESY * 4);

  //!!TODO: it is inefficient to do the texture creation over a temporary BufferedImage as a procedural texture channel alrady operates
  //        on a float buffer that could be directly send to OpenGL for conversion (or at least converted directly in the convertImageData
  //        function below.
  public int create2dTexture(int color) {
    int id = genTexID();
   
    IntBuffer ibuf = bbuf.asIntBuffer();
    for (int i = 0; i < ibuf.capacity(); i++) ibuf.put(i, color);

    GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
    int targetFormat = GL11.GL_RGBA;
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, targetFormat, TEXTURE_RESX, TEXTURE_RESY, 0, GL11.GL_RGBA,
        GL11.GL_UNSIGNED_BYTE, bbuf.asIntBuffer());
    GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, targetFormat, TEXTURE_RESX, TEXTURE_RESY, GL11.GL_RGBA,
        GL11.GL_UNSIGNED_BYTE, bbuf);

    return id;
  }
 
  public synchronized void update2dTexture_ConstanctColor(int color, int id) {
    IntBuffer ibuf = bbuf.asIntBuffer();
    for (int i = 0; i < ibuf.capacity(); i++) ibuf.put(i, color);

    GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
    int targetFormat = GL11.GL_RGBA;
    GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, targetFormat, TEXTURE_RESX, TEXTURE_RESY, 0, GL11.GL_RGBA,
        GL11.GL_UNSIGNED_BYTE, bbuf.asIntBuffer());
    GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, targetFormat, TEXTURE_RESX, TEXTURE_RESY, GL11.GL_RGBA,
        GL11.GL_UNSIGNED_BYTE, bbuf);
  }

 
  // here are the same performance problems as in create2dTexture
  public synchronized void update2dTexture(BufferedImage img, int id) {
    if (img.getWidth() != TEXTURE_RESX || img.getHeight() != TEXTURE_RESY) {
      Logger.logError(this, "TextureResolution does not match image resolution for update.");
      return;
    }
    convertImageData(bbuf.asIntBuffer(), img);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
    //int targetFormat = (img.getColorModel().hasAlpha()) ? GL11.GL_RGBA : GL11.GL_RGB;
    int targetFormat = GL11.GL_RGBA;
    GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, targetFormat, TEXTURE_RESX, TEXTURE_RESY, 0, GL11.GL_RGBA,
        GL11.GL_UNSIGNED_BYTE, bbuf.asIntBuffer());
    GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, targetFormat, TEXTURE_RESX, TEXTURE_RESY, GL11.GL_RGBA,
        GL11.GL_UNSIGNED_BYTE, bbuf);
  }
 
 
 
 
  // !!TODO: this is a slow conversion operation because each byte is touched by hand...
  public void convertImageData(IntBuffer result, BufferedImage img) {
    int xres = img.getWidth();
    int yres = img.getHeight();
    int[] data = new int[xres * yres];
    img.getRGB(0, 0, xres, yres, data, 0, xres);

    for (int i = 0; i < xres * yres; i++) {
      int A = ((data[i] >> 24) & 0xFF);
      int R = ((data[i] >> 16) & 0xFF);
      int G = ((data[i] >> 8) & 0xFF);
      int B = ((data[i] >> 0) & 0xFF);
      data[i] = (R << 24) | (G << 16) | (B << 8) | (A << 0);
    }

    result.put(data);
    result.rewind();
  }
 
 
  ByteBuffer loadShaderCodeFromFile(String filename) {
    byte[] code = null;

    try {
      InputStream fs = OpenGLPreviewPanel.class.getResourceAsStream(filename);
      if (fs == null) {
        System.err.println("Error opening file "+filename);
        return null;
      }
      fs.read(code = new byte[fs.available()]);
      fs.close();
    } catch (IOException e) {
      System.out.println(e);
      return null;
    }

    ByteBuffer shaderCode = Utils.allocByteBuffer(code.length);
   
    shaderCode.put(code);
    shaderCode.flip();

    return shaderCode;
  }
 
 
  private void printLogInfo(int obj, String name) {
    IntBuffer iVal = Utils.allocIntBuffer(1);
    ARBShaderObjects.glGetObjectParameterARB(obj, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);

    int length = iVal.get();
    if (length > 1) {
      System.out.println();
      ByteBuffer infoLog = Utils.allocByteBuffer(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: " + name + "\n" + out);
    }

    Util.checkGLError();
  }
 
  public int getShaderProgram(String vcode, String fcode) {
    ByteBuffer vc = ByteBuffer.allocateDirect(vcode.length());
    vc.put(vcode.getBytes()); vc.flip();
    ByteBuffer fc = ByteBuffer.allocateDirect(fcode.length());
    fc.put(fcode.getBytes()); fc.flip();
    return getShaderProgram(vc, fc);
  }
 
  /**
   * Loads a vertex and fragment shader pair, compiles them and links them to a ProgramObjectARB
   * @param name
   * @return the program object ID
   */
  public int getShaderProgram(ByteBuffer vcode, ByteBuffer fcode) {
    int progID = -1;

    int vid = ARBShaderObjects.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);
    int fid = ARBShaderObjects.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);

    ARBShaderObjects.glShaderSourceARB(vid, vcode);
    ARBShaderObjects.glCompileShaderARB(vid);
    printLogInfo(vid, "Compile Vertex Shader");

    ARBShaderObjects.glShaderSourceARB(fid, fcode);
    ARBShaderObjects.glCompileShaderARB(fid);
    printLogInfo(fid, "Compile Fragment Shader");
   
    progID = ARBShaderObjects.glCreateProgramObjectARB();
    ARBShaderObjects.glAttachObjectARB(progID, vid);
    ARBShaderObjects.glAttachObjectARB(progID, fid);
   
    ARBShaderObjects.glLinkProgramARB(progID);
    printLogInfo(progID, "Link");
    ARBShaderObjects.glValidateProgramARB(progID);
    printLogInfo(progID, "Validate");
   
    return progID;
  }

 
  public void parameterChanged(AbstractParam source) {
    repaint();
  }


  static final float CubeVertexData[] = { -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.0f, 0.0f, -0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.0f, 0.0f, 0.0f, -0.0f, -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, -0.0f, 0.0f, 1.0f, 0.0f, -0.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, -0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.0f, -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, -0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, -0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -0.0f, -1.0f, -0.0f, -1.0f, 0.0f, -0.0f, -0.0f, 1.0f, -1.0f, -1.0f, -1.0f, -0.0f, -1.0f, -0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -0.0f, 1.0f, -1.0f, -1.0f, -0.0f, -1.0f, -0.0f, -1.0f, 0.0f, -0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, -0.0f, -1.0f, -0.0f, -1.0f, 0.0f, -0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -0.0f, 0.0f, -0.0f, -1.0f, 0.0f, -0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -0.0f, 1.0f, 1.0f, -1.0f, 1.0f, -0.0f, 0.0f, -0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.0f, 0.0f, -0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, -0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.0f, -0.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, };
  static final int CubeIndices[] = { 0 , 1 , 2 , 0 , 2 , 3 , 4 , 5 , 6 , 4 , 6 , 7 , 8 , 9 , 10 , 8 , 10 , 11 , 12 , 13 , 14 , 12 , 14 , 15 , 16 , 17 , 18 , 16 , 18 , 19 , 20 , 21 , 22 , 20 , 22 , 23 , };


  static final float PlaneVertexData[] = { 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, -0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, -0.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, -0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, -0.0f, 0.0f, 0.0f, 1.0f, };
  static final int PlaneIndices[] = { 0, 1, 2, 0, 2, 3, };

  static final float CylinderVertexData[] = { 0.55557f, 0.83147f, -1.0f, 0.55556f, 0.83145f, 0.0f, 0.81279f, -0.58255f, 0.0f, 1.28125f, 0.0f, 0.55556f, 0.83147f, 1.0f, 0.55556f, 0.83145f, 0.0f, 0.84925f, -0.52799f, 0.0f, 1.28125f, 1.0f, 0.70711f, 0.70711f, 1.0f, 0.70708f, 0.70708f, 0.0f, 0.72993f, -0.68352f, 0.0f, 1.21875f, 1.0f, 0.70711f, 0.70711f, -1.0f, 0.70708f, 0.70708f, 0.0f, 0.68352f, -0.72993f, 0.0f, 1.21875f, 0.0f, 0.38269f, 0.92388f, -1.0f, 0.38267f, 0.92386f, 0.0f, 0.91083f, -0.41279f, 0.0f, 1.34375f, 0.0f, 0.38268f, 0.92388f, 1.0f, 0.38267f, 0.92386f, 0.0f, 0.93594f, -0.35216f, 0.0f, 1.34375f, 1.0f, 0.19509f, 0.98078f, -1.0f, 0.19507f, 0.98077f, 0.0f, 0.97386f, -0.22717f, 0.0f, 1.40625f, 0.0f, 0.19508f, 0.98079f, 1.0f, 0.19507f, 0.98077f, 0.0f, 0.98666f, -0.1628f, 0.0f, 1.40625f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.99946f, -0.03281f, 0.0f, 1.46875f, 0.0f, -1e-05f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.99946f, 0.03282f, 0.0f, 1.46875f, 1.0f, -0.19509f, 0.98079f, -1.0f, -0.19507f, 0.98077f, 0.0f, 0.99518f, 0.09802f, 0.0f, 1.53125f, 0.0f, -0.1951f, 0.98078f, 1.0f, -0.19507f, 0.98077f, 0.0f, 0.99518f, 0.09802f, 0.0f, 1.53125f, 1.0f, -0.38268f, 0.92388f, -1.0f, -0.38267f, 0.92386f, 0.0f, 0.93594f, 0.35216f, 0.0f, -0.40625f, 0.0f, -0.38269f, 0.92388f, 1.0f, -0.38267f, 0.92386f, 0.0f, 0.91082f, 0.4128f, 0.0f, -0.40625f, 1.0f, -0.1951f, 0.98078f, 1.0f, -0.19507f, 0.98077f, 0.0f, 0.95694f, 0.29029f, 0.0f, -0.46875f, 1.0f, -0.19509f, 0.98079f, -1.0f, -0.19507f, 0.98077f, 0.0f, 0.95694f, 0.29028f, 0.0f, -0.46875f, 0.0f, -0.55557f, 0.83147f, -1.0f, -0.55556f, 0.83145f, 0.0f, 0.84925f, 0.52799f, 0.0f, -0.34375f, 0.0f, -0.55557f, 0.83147f, 1.0f, -0.55556f, 0.83145f, 0.0f, 0.81279f, 0.58256f, 0.0f, -0.34375f, 1.0f, -0.70711f, 0.70711f, -1.0f, -0.70708f, 0.70708f, 0.0f, 0.72993f, 0.68352f, 0.0f, -0.28125f, 0.0f, -0.70711f, 0.7071f, 1.0f, -0.70708f, 0.70708f, 0.0f, 0.68352f, 0.72993f, 0.0f, -0.28125f, 1.0f, -0.83147f, 0.55557f, -1.0f, -0.83145f, 0.55556f, 0.0f, 0.58255f, 0.81279f, 0.0f, -0.21875f, 0.0f, -0.83147f, 0.55557f, 1.0f, -0.83145f, 0.55556f, 0.0f, 0.52799f, 0.84925f, 0.0f, -0.21875f, 1.0f, -0.92388f, 0.38268f, -1.0f, -0.92386f, 0.38267f, 0.0f, 0.41279f, 0.91083f, 0.0f, -0.15625f, 0.0f, -0.92388f, 0.38268f, 1.0f, -0.92386f, 0.38267f, 0.0f, 0.35216f, 0.93594f, 0.0f, -0.15625f, 1.0f, -0.98079f, 0.19509f, -1.0f, -0.98077f, 0.19507f, 0.0f, 0.22717f, 0.97386f, -0.0f, -0.09375f, 0.0f, -0.98079f, 0.19509f, 1.0f, -0.98077f, 0.19507f, 0.0f, 0.1628f, 0.98666f, -0.0f, -0.09375f, 1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.03281f, 0.99946f, -0.0f, -0.03125f, 0.0f, -1.0f, -0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -0.03281f, 0.99946f, 0.0f, -0.03125f, 1.0f, -0.98079f, -0.19509f, -1.0f, -0.98077f, -0.19507f, 0.0f, -0.1628f, 0.98666f, 0.0f, 0.03125f, 0.0f, -0.98078f, -0.19509f, 1.0f, -0.98077f, -0.19507f, 0.0f, -0.22717f, 0.97386f, 0.0f, 0.03125f, 1.0f, -0.92388f, -0.38268f, -1.0f, -0.92386f, -0.38267f, 0.0f, -0.35216f, 0.93594f, -0.0f, 0.09375f, 0.0f, -0.92388f, -0.38269f, 1.0f, -0.92386f, -0.38267f, 0.0f, -0.41279f, 0.91082f, -0.0f, 0.09375f, 1.0f, -0.83147f, -0.55557f, -1.0f, -0.83145f, -0.55556f, 0.0f, -0.52799f, 0.84925f, -0.0f, 0.15625f, 0.0f, -0.83147f, -0.55557f, 1.0f, -0.83145f, -0.55556f, 0.0f, -0.58256f, 0.81279f, 0.0f, 0.15625f, 1.0f, -0.70711f, -0.70711f, -1.0f, -0.70708f, -0.70708f, 0.0f, -0.68352f, 0.72993f, 0.0f, 0.21875f, 0.0f, -0.70711f, -0.70711f, 1.0f, -0.70708f, -0.70708f, 0.0f, -0.72993f, 0.68352f, 0.0f, 0.21875f, 1.0f, -0.55557f, -0.83147f, -1.0f, -0.55556f, -0.83145f, 0.0f, -0.81279f, 0.58255f, -0.0f, 0.28125f, 0.0f, -0.55557f, -0.83147f, 1.0f, -0.55556f, -0.83145f, 0.0f, -0.84925f, 0.52799f, -0.0f, 0.28125f, 1.0f, -0.38268f, -0.92388f, -1.0f, -0.38267f, -0.92386f, 0.0f, -0.91083f, 0.41279f, -0.0f, 0.34375f, 0.0f, -0.38268f, -0.92388f, 1.0f, -0.38267f, -0.92386f, 0.0f, -0.93594f, 0.35216f, -0.0f, 0.34375f, 1.0f, -0.19509f, -0.98079f, -1.0f, -0.19507f, -0.98077f, 0.0f, -0.97386f, 0.22717f, 0.0f, 0.40625f, 0.0f, -0.19509f, -0.98079f, 1.0f, -0.19507f, -0.98077f, 0.0f, -0.98666f, 0.1628f, 0.0f, 0.40625f, 1.0f, -0.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, -0.99946f, 0.03281f, 0.0f, 0.46875f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, -0.99946f, -0.03281f, -0.0f, 0.46875f, 1.0f, 0.19509f, -0.98079f, -1.0f, 0.19507f, -0.98077f, 0.0f, -0.98666f, -0.1628f, -0.0f, 0.53125f, 0.0f, 0.19509f, -0.98079f, 1.0f, 0.19507f, -0.98077f, 0.0f, -0.97386f, -0.22717f, -0.0f, 0.53125f, 1.0f, 0.38268f, -0.92388f, -1.0f, 0.38267f, -0.92386f, 0.0f, -0.93594f, -0.35216f, 0.0f, 0.59375f, 0.0f, 0.38268f, -0.92388f, 1.0f, 0.38267f, -0.92386f, 0.0f, -0.91083f, -0.41279f, 0.0f, 0.59375f, 1.0f, 0.55557f, -0.83147f, -1.0f, 0.55556f, -0.83145f, 0.0f, -0.84925f, -0.52799f, 0.0f, 0.65625f, 0.0f, 0.55557f, -0.83147f, 1.0f, 0.55556f, -0.83145f, 0.0f, -0.81279f, -0.58255f, 0.0f, 0.65625f, 1.0f, 0.70711f, -0.70711f, -1.0f, 0.70708f, -0.70708f, 0.0f, -0.72993f, -0.68352f, 0.0f, 0.71875f, 0.0f, 0.70711f, -0.70711f, 1.0f, 0.70708f, -0.70708f, 0.0f, -0.68352f, -0.72993f, 0.0f, 0.71875f, 1.0f, 0.83147f, -0.55557f, -1.0f, 0.83145f, -0.55556f, 0.0f, -0.58255f, -0.81279f, 0.0f, 0.78125f, 0.0f, 0.83147f, -0.55557f, 1.0f, 0.83145f, -0.55556f, 0.0f, -0.52799f, -0.84925f, 0.0f, 0.78125f, 1.0f, 0.92388f, -0.38268f, -1.0f, 0.92386f, -0.38267f, 0.0f, -0.41279f, -0.91082f, 0.0f, 0.84375f, 0.0f, 0.92388f, -0.38269f, 1.0f, 0.92386f, -0.38267f, 0.0f, -0.35216f, -0.93594f, 0.0f, 0.84375f, 1.0f, 0.98079f, -0.19509f, -1.0f, 0.98077f, -0.19507f, 0.0f, -0.22717f, -0.97386f, 0.0f, 0.90625f, 0.0f, 0.98078f, -0.19509f, 1.0f, 0.98077f, -0.19507f, 0.0f, -0.1628f, -0.98666f, 0.0f, 0.90625f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, -0.03281f, -0.99946f, 0.0f, 0.96875f, 0.0f, 1.0f, -0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.03281f, -0.99946f, 0.0f, 0.96875f, 1.0f, 0.98079f, 0.19509f, -1.0f, 0.98077f, 0.19507f, 0.0f, 0.1628f, -0.98666f, 0.0f, 1.03125f, 0.0f, 0.98079f, 0.19509f, 1.0f, 0.98077f, 0.19507f, 0.0f, 0.22717f, -0.97386f, 0.0f, 1.03125f, 1.0f, 0.92388f, 0.38268f, -1.0f, 0.92386f, 0.38267f, 0.0f, 0.35216f, -0.93594f, 0.0f, 1.09375f, 0.0f, 0.92388f, 0.38268f, 1.0f, 0.92386f, 0.38267f, 0.0f, 0.41279f, -0.91083f, 0.0f, 1.09375f, 1.0f, 0.83147f, 0.55557f, -1.0f, 0.83145f, 0.55556f, 0.0f, 0.52799f, -0.84925f, 0.0f, 1.15625f, 0.0f, 0.83147f, 0.55557f, 1.0f, 0.83145f, 0.55556f, 0.0f, 0.58255f, -0.81279f, 0.0f, 1.15625f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.70711f, 0.70711f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.85355f, 0.85355f, 0.83147f, 0.55557f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.91573f, 0.77779f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.83147f, 0.55557f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.91574f, 0.77778f, 0.70711f, 0.70711f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.85355f, 0.85355f, 0.92388f, 0.38268f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.96194f, 0.69134f, 0.92388f, 0.38268f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.96194f, 0.69134f, 0.98079f, 0.19509f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.99039f, 0.59755f, 0.98079f, 0.19509f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.99039f, 0.59754f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f, -0.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.98079f, -0.19509f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.99039f, 0.40245f, 0.98078f, -0.19509f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.99039f, 0.40245f, 0.92388f, -0.38268f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.96194f, 0.30866f, 0.92388f, -0.38269f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.96194f, 0.30866f, 0.83147f, -0.55557f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.91573f, 0.22221f, 0.83147f, -0.55557f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.91573f, 0.22221f, 0.70711f, -0.70711f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.85355f, 0.14645f, 0.70711f, -0.70711f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.85355f, 0.14645f, 0.55557f, -0.83147f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.77779f, 0.08427f, 0.55557f, -0.83147f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.77778f, 0.08427f, 0.38268f, -0.92388f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.69134f, 0.03806f, 0.38268f, -0.92388f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.69134f, 0.03806f, 0.19509f, -0.98079f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.59755f, 0.00961f, 0.19509f, -0.98079f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.59755f, 0.00961f, -0.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.5f, 0.0f, -0.19509f, -0.98079f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.40245f, 0.00961f, -0.19509f, -0.98079f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.40246f, 0.00961f, -0.38268f, -0.92388f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.30866f, 0.03806f, -0.38268f, -0.92388f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.30866f, 0.03806f, -0.55557f, -0.83147f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.22221f, 0.08427f, -0.55557f, -0.83147f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.22222f, 0.08426f, -0.70711f, -0.70711f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.14645f, 0.14645f, -0.70711f, -0.70711f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.14645f, 0.14645f, -0.83147f, -0.55557f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.08427f, 0.22222f, -0.83147f, -0.55557f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.08427f, 0.22221f, -0.92388f, -0.38268f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.03806f, 0.30866f, -0.92388f, -0.38269f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.03806f, 0.30866f, -0.98079f, -0.19509f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.00961f, 0.40246f, -0.98078f, -0.19509f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.00961f, 0.40245f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.0f, 0.5f, -1.0f, -0.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.0f, 0.5f, -0.98079f, 0.19509f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.00961f, 0.59755f, -0.98079f, 0.19509f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.00961f, 0.59754f, -0.92388f, 0.38268f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.03806f, 0.69134f, -0.92388f, 0.38268f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.03806f, 0.69134f, -0.83147f, 0.55557f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.08427f, 0.77779f, -0.83147f, 0.55557f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.08426f, 0.77778f, -0.70711f, 0.70711f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.14645f, 0.85355f, -0.70711f, 0.7071f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.14644f, 0.85355f, -0.55557f, 0.83147f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.22222f, 0.91574f, -0.55557f, 0.83147f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.22221f, 0.91573f, -0.38268f, 0.92388f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.30866f, 0.96194f, -0.38269f, 0.92388f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.30866f, 0.96194f, -0.19509f, 0.98079f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.40246f, 0.99039f, -0.1951f, 0.98078f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.40245f, 0.99039f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.0f, -1e-05f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.19509f, 0.98078f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.59755f, 0.99039f, 0.19508f, 0.98079f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.59754f, 0.99039f, 0.38269f, 0.92388f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.69134f, 0.96194f, 0.38268f, 0.92388f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.69134f, 0.96194f, 0.55557f, 0.83147f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -0.0f, 0.0f, 0.77779f, 0.91573f, 0.55556f, 0.83147f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -0.0f, 0.0f, 0.77778f, 0.91574f, };
  static final int CylinderIndices[] = { 0 , 1 , 2 , 0 , 2 , 3 , 1 , 0 , 4 , 1 , 4 , 5 , 6 , 7 , 5 , 6 , 5 , 4 , 8 , 9 , 7 , 8 , 7 , 6 , 10 , 11 , 9 , 10 , 9 , 8 , 12 , 13 , 14 , 12 , 14 , 15 , 16 , 17 , 13 , 16 , 13 , 12 , 18 , 19 , 17 , 18 , 17 , 16 , 20 , 21 , 19 , 20 , 19 , 18 , 22 , 23 , 21 , 22 , 21 , 20 , 24 , 25 , 23 , 24 , 23 , 22 , 26 , 27 , 25 , 26 , 25 , 24 , 28 , 29 , 27 , 28 , 27 , 26 , 30 , 31 , 29 , 30 , 29 , 28 , 32 , 33 , 31 , 32 , 31 , 30 , 34 , 35 , 33 , 34 , 33 , 32 , 36 , 37 , 35 , 36 , 35 , 34 , 38 , 39 , 37 , 38 , 37 , 36 , 40 , 41 , 39 , 40 , 39 , 38 , 42 , 43 , 41 , 42 , 41 , 40 , 44 , 45 , 43 , 44 , 43 , 42 , 46 , 47 , 45 , 46 , 45 , 44 , 48 , 49 , 47 , 48 , 47 , 46 , 50 , 51 , 49 , 50 , 49 , 48 , 52 , 53 , 51 , 52 , 51 , 50 , 54 , 55 , 53 , 54 , 53 , 52 , 56 , 57 , 55 , 56 , 55 , 54 , 58 , 59 , 57 , 58 , 57 , 56 , 60 , 61 , 59 , 60 , 59 , 58 , 62 , 63 , 61 , 62 , 61 , 60 , 64 , 65 , 63 , 64 , 63 , 62 , 3 , 2 , 65 , 3 , 65 , 64 , 66 , 67 , 68 , 69 , 70 , 71 , 66 , 68 , 72 , 69 , 73 , 70 , 66 , 72 , 74 , 69 , 75 , 73 , 66 , 74 , 76 , 69 , 77 , 75 , 66 , 76 , 78 , 69 , 79 , 77 , 66 , 78 , 80 , 69 , 81 , 79 , 66 , 80 , 82 , 69 , 83 , 81 , 66 , 82 , 84 , 69 , 85 , 83 , 66 , 84 , 86 , 69 , 87 , 85 , 66 , 86 , 88 , 69 , 89 , 87 , 66 , 88 , 90 , 69 , 91 , 89 , 66 , 90 , 92 , 69 , 93 , 91 , 66 , 92 , 94 , 69 , 95 , 93 , 66 , 94 , 96 , 69 , 97 , 95 , 66 , 96 , 98 , 69 , 99 , 97 , 66 , 98 , 100 , 69 , 101 , 99 , 66 , 100 , 102 , 69 , 103 , 101 , 66 , 102 , 104 , 69 , 105 , 103 , 66 , 104 , 106 , 69 , 107 , 105 , 66 , 106 , 108 , 69 , 109 , 107 , 66 , 108 , 110 , 69 , 111 , 109 , 66 , 110 , 112 , 69 , 113 , 111 , 66 , 112 , 114 , 69 , 115 , 113 , 66 , 114 , 116 , 69 , 117 , 115 , 66 , 116 , 118 , 69 , 119 , 117 , 66 , 118 , 120 , 69 , 121 , 119 , 66 , 120 , 122 , 69 , 123 , 121 , 66 , 122 , 124 , 69 , 125 , 123 , 66 , 124 , 126 , 69 , 127 , 125 , 66 , 126 , 128 , 69 , 129 , 127 , 66 , 128 , 130 , 69 , 131 , 129 , 130 , 67 , 66 , 69 , 71 , 131 , };
}
TOP

Related Classes of com.mystictri.neotextureedit.OpenGLTextureRenderCanvas$GLPreviewParameters

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.