Ported GLSL renderering from PGraphicsAndroid3D to PGraphicsOpenGL, several fixes

This commit is contained in:
codeanticode
2012-02-12 01:22:42 +00:00
parent 52b1828a49
commit 5ea73a1c41
23 changed files with 3895 additions and 3973 deletions
@@ -19,6 +19,8 @@
Boston, MA 02111-1307 USA
*/
varying vec4 vertColor;
void main() {
gl_FragColor = gl_Color;
}
gl_FragColor = vertColor;
}
@@ -19,6 +19,11 @@
Boston, MA 02111-1307 USA
*/
void main() {
gl_FragColor = gl_Color;
uniform sampler2D textureSampler;
varying vec4 vertColor;
varying vec2 vertTexcoord;
void main() {
gl_FragColor = texture2D(textureSampler, vertTexcoord) * vertColor;
}
@@ -0,0 +1,134 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2011 Andres Colubri
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
uniform mat4 modelviewMatrix;
uniform mat4 projmodelviewMatrix;
uniform mat3 normalMatrix;
uniform int lightCount;
uniform vec4 lightPosition[8];
uniform vec3 lightNormal[8];
uniform vec3 lightAmbient[8];
uniform vec3 lightDiffuse[8];
uniform vec3 lightSpecular[8];
uniform vec3 lightFalloffCoefficients[8];
uniform vec2 lightSpotParameters[8];
attribute vec4 inVertex;
attribute vec4 inColor;
attribute vec3 inNormal;
attribute vec2 inTexcoord;
attribute vec4 inAmbient;
attribute vec4 inSpecular;
attribute vec4 inEmissive;
attribute float inShine;
varying vec4 vertColor;
varying vec2 vertTexcoord;
const float zero_float = 0.0;
const float one_float = 1.0;
const vec3 zero_vec3 = vec3(0);
float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) {
vec3 lpv = lightPos - vertPos;
vec3 dist = vec3(one_float);
dist.z = dot(lpv, lpv);
dist.y = sqrt(dist.z);
return one_float / dot(dist, coeff);
}
float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) {
vec3 lpv = normalize(lightPos - vertPos);
float spotCos = dot(-lightNorm, lpv);
return spotCos <= minCos ? zero_float : pow(spotCos, spotExp);
}
float lambertFactor(vec3 lightDir, vec3 vecNormal) {
return max(zero_float, dot(lightDir, vecNormal));
}
float blinnPhongFactor(vec3 lightDir, vec3 lightPos, vec3 vecNormal, float shine) {
vec3 ldp = normalize(lightDir - lightPos);
return pow(max(zero_float, dot(ldp, vecNormal)), shine);
}
void main() {
// Vertex in clip coordinates
gl_Position = projmodelviewMatrix * inVertex;
// Vertex in eye coordinates
vec3 ecVertex = vec3(modelviewMatrix * inVertex);
// Normal vector in eye coordinates
vec3 ecNormal = normalize(normalMatrix * inNormal);
// Light calculations
vec3 totalAmbient = vec3(0, 0, 0);
vec3 totalDiffuse = vec3(0, 0, 0);
vec3 totalSpecular = vec3(0, 0, 0);
for (int i = 0; i < lightCount; i++) {
vec3 lightPos = lightPosition[i].xyz;
bool isDir = zero_float < lightPosition[i].w;
float spotCos = lightSpotParameters[i].x;
float spotExp = lightSpotParameters[i].y;
vec3 lightDir;
float falloff;
float spotf;
if (isDir) {
falloff = one_float;
lightDir = -lightNormal[i];
} else {
falloff = falloffFactor(lightPos, ecVertex, lightFalloffCoefficients[i]);
lightDir = normalize(lightPos - ecVertex);
}
spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i],
spotCos, spotExp)
: one_float;
if (any(greaterThan(lightAmbient[i], zero_vec3))) {
totalAmbient += lightAmbient[i] * falloff;
}
if (any(greaterThan(lightDiffuse[i], zero_vec3))) {
totalDiffuse += lightDiffuse[i] * falloff * spotf *
lambertFactor(lightDir, ecNormal);
}
if (any(greaterThan(lightSpecular[i], zero_vec3))) {
totalSpecular += lightSpecular[i] * falloff * spotf *
blinnPhongFactor(lightDir, lightPos, ecNormal, inShine);
}
}
// Calculating final color as result of all lights (plus emissive term)
vertColor = vec4(totalAmbient, 1) * inAmbient +
vec4(totalDiffuse, 1) * inColor +
vec4(totalSpecular, 1) * inSpecular +
inEmissive;
// Passing texture coordinates to the fragment shader
vertTexcoord = inTexcoord;
}
@@ -0,0 +1,130 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2011 Andres Colubri
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
uniform mat4 modelviewMatrix;
uniform mat4 projmodelviewMatrix;
uniform mat3 normalMatrix;
uniform int lightCount;
uniform vec4 lightPosition[8];
uniform vec3 lightNormal[8];
uniform vec3 lightAmbient[8];
uniform vec3 lightDiffuse[8];
uniform vec3 lightSpecular[8];
uniform vec3 lightFalloffCoefficients[8];
uniform vec2 lightSpotParameters[8];
attribute vec4 inVertex;
attribute vec4 inColor;
attribute vec3 inNormal;
attribute vec4 inAmbient;
attribute vec4 inSpecular;
attribute vec4 inEmissive;
attribute float inShine;
varying vec4 vertColor;
const float zero_float = 0.0;
const float one_float = 1.0;
const vec3 zero_vec3 = vec3(0);
float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) {
vec3 lpv = lightPos - vertPos;
vec3 dist = vec3(one_float);
dist.z = dot(lpv, lpv);
dist.y = sqrt(dist.z);
return one_float / dot(dist, coeff);
}
float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) {
vec3 lpv = normalize(lightPos - vertPos);
float spotCos = dot(-lightNorm, lpv);
return spotCos <= minCos ? zero_float : pow(spotCos, spotExp);
}
float lambertFactor(vec3 lightDir, vec3 vecNormal) {
return max(zero_float, dot(lightDir, vecNormal));
}
float blinnPhongFactor(vec3 lightDir, vec3 lightPos, vec3 vecNormal, float shine) {
vec3 ldp = normalize(lightDir - lightPos);
return pow(max(zero_float, dot(ldp, vecNormal)), shine);
}
void main() {
// Vertex in clip coordinates
gl_Position = projmodelviewMatrix * inVertex;
// Vertex in eye coordinates
vec3 ecVertex = vec3(modelviewMatrix * inVertex);
// Normal vector in eye coordinates
vec3 ecNormal = normalize(normalMatrix * inNormal);
// Light calculations
vec3 totalAmbient = vec3(0, 0, 0);
vec3 totalDiffuse = vec3(0, 0, 0);
vec3 totalSpecular = vec3(0, 0, 0);
for (int i = 0; i < lightCount; i++) {
vec3 lightPos = lightPosition[i].xyz;
bool isDir = zero_float < lightPosition[i].w;
float spotCos = lightSpotParameters[i].x;
float spotExp = lightSpotParameters[i].y;
vec3 lightDir;
float falloff;
float spotf;
if (isDir) {
falloff = one_float;
lightDir = -lightNormal[i];
} else {
falloff = falloffFactor(lightPos, ecVertex, lightFalloffCoefficients[i]);
lightDir = normalize(lightPos - ecVertex);
}
spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i],
spotCos, spotExp)
: one_float;
if (any(greaterThan(lightAmbient[i], zero_vec3))) {
totalAmbient += lightAmbient[i] * falloff;
}
if (any(greaterThan(lightDiffuse[i], zero_vec3))) {
totalDiffuse += lightDiffuse[i] * falloff * spotf *
lambertFactor(lightDir, ecNormal);
}
if (any(greaterThan(lightSpecular[i], zero_vec3))) {
totalSpecular += lightSpecular[i] * falloff * spotf *
blinnPhongFactor(lightDir, lightPos, ecNormal, inShine);
}
}
// Calculating final color as result of all lights (plus emissive term)
vertColor = vec4(totalAmbient, 1) * inAmbient +
vec4(totalDiffuse, 1) * inColor +
vec4(totalSpecular, 1) * inSpecular +
inEmissive;
}
@@ -0,0 +1,33 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2011 Andres Colubri
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
uniform mat4 projmodelviewMatrix;
attribute vec4 inVertex;
attribute vec4 inColor;
varying vec4 vertColor;
void main() {
gl_Position = projmodelviewMatrix * inVertex;
vertColor = inColor;
}
@@ -0,0 +1,36 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2011 Andres Colubri
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
uniform mat4 projmodelviewMatrix;
attribute vec4 inVertex;
attribute vec4 inColor;
attribute vec2 inTexcoord;
varying vec4 vertColor;
varying vec2 vertTexcoord;
void main() {
gl_Position = projmodelviewMatrix * inVertex;
vertColor = inColor;
vertTexcoord = inTexcoord;
}
@@ -1,130 +0,0 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2011 Andres Colubri
Based on glsl code from the dpix library:
http://gfx.cs.princeton.edu/proj/dpix/
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
attribute vec4 attribs;
uniform vec4 viewport;
uniform int perspective;
uniform vec4 eye;
uniform int lights;
vec3 clipToWindow(vec4 clip, vec4 viewport) {
vec3 post_div = clip.xyz / clip.w;
vec2 xypos = (post_div.xy + vec2(1.0, 1.0)) * 0.5 * viewport.zw;
return vec3(xypos, post_div.z * 0.5 + 0.5);
}
vec4 windowToClipVector(vec2 window, vec4 viewport, float clip_w) {
vec2 xypos = (window / viewport.zw) * 2.0;
return vec4(xypos, 0.0, 0.0) * clip_w;
}
// From the "Directional Lights I & II" tutorials from lighthouse 3D:
// http://www.lighthouse3d.com/tutorials/glsl-tutorial/directional-lights-i/
vec4 calculateLight(int i) {
// Per-vertex diffuse and ambient lighting.
vec3 normal, lightDir;
vec4 diffuse, ambient, specular;
float NdotL, NdotHV;
// first transform the normal into eye space and normalize the result.
normal = normalize(gl_NormalMatrix * gl_Normal);
// now normalize the light's direction. Note that according to the
// OpenGL specification, the light is stored in eye space. Also since
// we're talking about a directional light, the position field is actually
// direction
lightDir = normalize(vec3(gl_LightSource[i].position));
// compute the cos of the angle between the normal and lights direction.
// The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also
// need to clamp the result to the [0,1] range.
NdotL = max(dot(normal, lightDir), 0.0);
// Compute the diffuse term. Ambient and diffuse material components
// are stored in the vertex color, since processing uses GL_COLOR_MATERIAL
diffuse = gl_Color * gl_LightSource[i].diffuse;
// Compute the ambient and globalAmbient terms
ambient = gl_Color * gl_LightSource[i].ambient;
// compute the specular term if NdotL is larger than zero
if (NdotL > 0.0) {
// normalize the half-vector, and then compute the
// cosine (dot product) with the normal
NdotHV = max(dot(normal, gl_LightSource[i].halfVector.xyz), 0.0);
specular = gl_FrontMaterial.specular * gl_LightSource[i].specular * pow(NdotHV, gl_FrontMaterial.shininess);
}
return NdotL * diffuse + ambient;
}
void main() {
vec4 pos_p = gl_Vertex;
vec4 pos_q = vec4(attribs.xyz, 1);
vec4 v_p = gl_ModelViewMatrix * pos_p;
// Moving vertices slightly toward the camera
// to avoid depth-fighting with the polys.
// Discussed here:
// http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=252848
//v_p.xyz = v_p.xyz * 0.99;
vec4 clip_p = gl_ProjectionMatrix * v_p;
vec4 v_q = gl_ModelViewMatrix * pos_q;
//v_q.xyz = v_q.xyz * 0.99;
vec4 clip_q = gl_ProjectionMatrix * v_q;
vec3 window_p = clipToWindow(clip_p, viewport);
vec3 window_q = clipToWindow(clip_q, viewport);
vec3 tangent = window_q - window_p;
float segment_length = length(tangent.xy);
vec2 perp = normalize(vec2(-tangent.y, tangent.x));
float thickness = attribs.w;
vec2 window_offset = perp * thickness;
if (0 < perspective) {
// Perspective correction (lines will look thiner as they move away
// from the view position).
gl_Position.xy = clip_p.xy + window_offset.xy;
gl_Position.zw = clip_p.zw;
} else {
// No perspective correction.
float clip_p_w = clip_p.w;
vec4 offset_p = windowToClipVector(window_offset, viewport, clip_p_w);
gl_Position = clip_p + offset_p;
}
vec4 color = vec4(0, 0, 0, 0);
vec4 globalAmbient = gl_Color * gl_LightModel.ambient;
if (lights == 0) {
color = gl_Color;
}
for (int i = 0; i < lights; i++) {
vec4 light = calculateLight(i);
color += light;
}
color = clamp(color, 0.0, 1.0);
gl_FrontColor = color;
}
@@ -28,6 +28,7 @@ import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PFont;
import processing.core.PImage;
import java.util.HashMap;
/**
@@ -51,7 +52,7 @@ class PFontTexture implements PConstants {
protected PApplet parent;
protected PGraphicsOpenGL pg;
protected PGL pgl;
protected PGL.Context context;
protected PGL.Context context;
protected PFont font;
protected int maxTexWidth;
@@ -25,6 +25,7 @@ package processing.opengl;
import processing.core.PApplet;
import processing.core.PConstants;
import java.nio.IntBuffer;
/**
@@ -174,24 +175,24 @@ public class PFramebuffer implements PConstants {
public void clear() {
pg.pushFramebuffer();
pg.setFramebuffer(this);
pgl.setClearColor(0, 0, 0, 0);
pgl.clearAllBuffers();
pgl.glClearColor(0, 0, 0, 0);
pgl.glClear(PGL.GL_COLOR_BUFFER_BIT | PGL.GL_DEPTH_BUFFER_BIT | PGL.GL_STENCIL_BUFFER_BIT);
pg.popFramebuffer();
}
public void copy(PFramebuffer dest) {
pgl.bindReadFramebuffer(this.glFboID);
pgl.bindWriteFramebuffer(dest.glFboID);
pgl.copyFramebuffer(this.width, this.height, dest.width, dest.height);
pgl.glBindFramebuffer(PGL.GL_READ_FRAMEBUFFER, this.glFboID);
pgl.glBindFramebuffer(PGL.GL_DRAW_FRAMEBUFFER, dest.glFboID);
pgl.glBlitFramebuffer(0, 0,this.width, this.height, 0, 0, dest.width, dest.height, PGL.GL_COLOR_BUFFER_BIT, PGL.GL_NEAREST);
}
public void bind() {
if (screenFb) {
if (PGraphicsOpenGL.fboSupported) {
pgl.bindFramebuffer(0);
pgl.glBindFramebuffer(PGL.GL_FRAMEBUFFER, 0);
}
} else if (fboMode) {
pgl.bindFramebuffer(glFboID);
pgl.glBindFramebuffer(PGL.GL_FRAMEBUFFER, glFboID);
} else {
backupScreen();
@@ -202,7 +203,7 @@ public class PFramebuffer implements PConstants {
}
if (noDepth) {
pgl.disableDepthTest();
pgl.glDisable(PGL.GL_DEPTH_TEST);
}
}
}
@@ -215,9 +216,9 @@ public class PFramebuffer implements PConstants {
if (noDepth) {
// No need to clear depth buffer because depth testing was disabled.
if (pg.hintEnabled(DISABLE_DEPTH_TEST)) {
pgl.disableDepthTest();
pgl.glDisable(PGL.GL_DEPTH_TEST);
} else {
pgl.enableDepthTest();
pgl.glEnable(PGL.GL_DEPTH_TEST);
}
}
@@ -232,8 +233,8 @@ public class PFramebuffer implements PConstants {
// after this offscreen render.
// A consequence of this behavior is that all the offscreen rendering when
// no FBOs are available should be done before any onscreen drawing.
pgl.setClearColor(0, 0, 0, 0);
pgl.clearDepthBuffer();
pgl.glClearColor(0, 0, 0, 0);
pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT);
}
}
}
@@ -242,8 +243,7 @@ public class PFramebuffer implements PConstants {
public void backupScreen() {
if (pixelBuffer == null) createPixelBuffer();
pixelBuffer.rewind();
pgl.readPixels(pixelBuffer, 0, 0, width, height);
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
copyToTexture(pixelBuffer, backupTexture.glID, backupTexture.glTarget);
}
@@ -256,7 +256,7 @@ public class PFramebuffer implements PConstants {
public void copyToColorBuffers() {
if (pixelBuffer == null) createPixelBuffer();
pixelBuffer.rewind();
pgl.readPixels(pixelBuffer, 0, 0, width, height);
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
for (int i = 0; i < numColorBuffers; i++) {
copyToTexture(pixelBuffer, colorBufferTex[i].glID, colorBufferTex[i].glTarget);
}
@@ -265,7 +265,7 @@ public class PFramebuffer implements PConstants {
public void readPixels() {
if (pixelBuffer == null) createPixelBuffer();
pixelBuffer.rewind();
pgl.readPixels(pixelBuffer, 0, 0, width, height);
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
}
public void getPixels(int[] pixels) {
@@ -319,11 +319,11 @@ public class PFramebuffer implements PConstants {
// Making sure nothing is attached.
for (int i = 0; i < numColorBuffers; i++) {
pgl.cleanFramebufferTexture(i);
pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, PGL.GL_TEXTURE_2D, 0, 0);
}
for (int i = 0; i < numColorBuffers; i++) {
pgl.setFramebufferTexture(i, colorBufferTex[i].glTarget, colorBufferTex[i].glID);
pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, colorBufferTex[i].glTarget, colorBufferTex[i].glID, 0);
}
validateFbo();
@@ -344,7 +344,7 @@ public class PFramebuffer implements PConstants {
if (screenFb) {
glFboID = 0;
} else if (fboMode) {
//glFboID = ogl.createGLResource(PGraphicsOpenGL.GL_FRAME_BUFFER);
//glFboID = ogl.createGLResource(PGraphicsAndroid3D.GL_FRAME_BUFFER);
glFboID = pg.createFrameBufferObject();
} else {
glFboID = 0;
@@ -400,9 +400,9 @@ public class PFramebuffer implements PConstants {
pg.setFramebuffer(this);
glColorBufferMultisampleID = pg.createRenderBufferObject();
pgl.bindRenderbuffer(glColorBufferMultisampleID);
pgl.setRenderbufferNumSamples(nsamples, PGL.RGBA8, width, height);
pgl.setRenderbufferColorAttachment(glColorBufferMultisampleID);
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glColorBufferMultisampleID);
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_RGBA8, width, height);
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0, PGL.GL_RENDERBUFFER, glColorBufferMultisampleID);
pg.popFramebuffer();
}
@@ -421,16 +421,16 @@ public class PFramebuffer implements PConstants {
pg.setFramebuffer(this);
glDepthStencilBufferID = pg.createRenderBufferObject();
pgl.bindRenderbuffer(glDepthStencilBufferID);
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthStencilBufferID);
if (multisample) {
pgl.setRenderbufferNumSamples(nsamples, PGL.DEPTH_24BIT_STENCIL_8BIT, width, height);
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_DEPTH24_STENCIL8, width, height);
} else {
pgl.setRenderbufferStorage(PGL.DEPTH_24BIT_STENCIL_8BIT, width, height);
pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, PGL.GL_DEPTH24_STENCIL8, width, height);
}
pgl.setRenderbufferDepthAttachment(glDepthStencilBufferID);
pgl.setRenderbufferStencilAttachment(glDepthStencilBufferID);
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID);
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID);
pg.popFramebuffer();
}
@@ -449,24 +449,24 @@ public class PFramebuffer implements PConstants {
pg.setFramebuffer(this);
glDepthBufferID = pg.createRenderBufferObject();
pgl.bindRenderbuffer(glDepthBufferID);
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthBufferID);
int glConst = PGL.DEPTH_16BIT;
int glConst = PGL.GL_DEPTH_COMPONENT16;
if (depthBits == 16) {
glConst = PGL.DEPTH_16BIT;
glConst = PGL.GL_DEPTH_COMPONENT16;
} else if (depthBits == 24) {
glConst = PGL.DEPTH_24BIT;
glConst = PGL.GL_DEPTH_COMPONENT24;
} else if (depthBits == 32) {
glConst = PGL.DEPTH_32BIT;
glConst = PGL.GL_DEPTH_COMPONENT32;
}
if (multisample) {
pgl.setRenderbufferNumSamples(nsamples, glConst, width, height);
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height);
} else {
pgl.setRenderbufferStorage(glConst, width, height);
pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height);
}
pgl.setRenderbufferDepthAttachment(glDepthBufferID);
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthBufferID);
pg.popFramebuffer();
}
@@ -485,23 +485,23 @@ public class PFramebuffer implements PConstants {
pg.setFramebuffer(this);
glStencilBufferID = pg.createRenderBufferObject();
pgl.bindRenderbuffer(glStencilBufferID);
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glStencilBufferID);
int glConst = PGL.STENCIL_1BIT;
int glConst = PGL.GL_STENCIL_INDEX1;
if (stencilBits == 1) {
glConst = PGL.STENCIL_1BIT;
glConst = PGL.GL_STENCIL_INDEX1;
} else if (stencilBits == 4) {
glConst = PGL.STENCIL_4BIT;
glConst = PGL.GL_STENCIL_INDEX4;
} else if (stencilBits == 8) {
glConst = PGL.STENCIL_8BIT;
glConst = PGL.GL_STENCIL_INDEX8;
}
if (multisample) {
pgl.setRenderbufferNumSamples(nsamples, glConst, width, height);
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height);
} else {
pgl.setRenderbufferStorage(glConst, width, height);
pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height);
}
pgl.setRenderbufferStencilAttachment(glStencilBufferID);
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glStencilBufferID);
pg.popFramebuffer();
}
@@ -520,25 +520,25 @@ public class PFramebuffer implements PConstants {
// Internal copy to texture method.
protected void copyToTexture(IntBuffer buffer, int glid, int gltarget) {
pgl.enableTexturing(gltarget);
pgl.bindTexture(gltarget, glid);
pgl.copyTexSubImage(buffer, gltarget, 0, 0, 0, width, height);
pgl.unbindTexture(gltarget);
pgl.glBindTexture(gltarget, glid);
pgl.glTexSubImage2D(gltarget, 0, 0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer);
pgl.glBindTexture(gltarget, 0);
pgl.disableTexturing(gltarget);
}
public boolean validateFbo() {
int status = pgl.getFramebufferStatus();
if (status == PGL.FRAMEBUFFER_COMPLETE) {
int status = pgl.glCheckFramebufferStatus(PGL.GL_FRAMEBUFFER);
if (status == PGL.GL_FRAMEBUFFER_COMPLETE) {
return true;
} else if (status == PGL.FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
} else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT (" + Integer.toHexString(status) + ")");
} else if (status == PGL.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) {
} else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) {
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT (" + Integer.toHexString(status) + ")");
} else if (status == PGL.FRAMEBUFFER_INCOMPLETE_DIMENSIONS) {
} else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) {
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS (" + Integer.toHexString(status) + ")");
} else if (status == PGL.FRAMEBUFFER_INCOMPLETE_FORMATS) {
} else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS) {
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_FORMATS (" + Integer.toHexString(status) + ")");
} else if (status == PGL.FRAMEBUFFER_UNSUPPORTED) {
} else if (status == PGL.GL_FRAMEBUFFER_UNSUPPORTED) {
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_UNSUPPORTED" + Integer.toHexString(status));
} else {
throw new RuntimeException("PFramebuffer: unknown framebuffer error (" + Integer.toHexString(status) + ")");
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -24,54 +24,82 @@
package processing.opengl;
import processing.core.*;
import java.io.IOException;
import java.net.URL;
/**
* This class encapsulates a glsl shader. Based in the code by JohnG
* This class encapsulates a GLSL shader program, including a vertex
* and a fragment shader. Originally based in the code by JohnG
* (http://www.hardcorepawn.com/)
*/
public class PShader {
protected PApplet parent;
protected PGraphicsOpenGL pg;
protected PGL pgl;
protected URL vertexURL;
protected URL fragmentURL;
protected String vertexFilename;
protected String fragmentFilename;
protected int programObject;
protected int vertexShader;
protected int fragmentShader;
protected boolean initialized;
/**
* Creates an instance of GLSLShader.
*
* @param parent PApplet
*/
public PShader(PApplet parent) {
this.parent = parent;
pg = (PGraphicsOpenGL) parent.g;
pgl = pg.pgl;
programObject = pg.createGLSLProgramObject();
vertexShader = 0;
fragmentShader = 0;
initialized = false;
}
public PShader() {
parent = null;
pg = null;
pgl = null;
this.vertexURL = null;
this.fragmentURL = null;
this.vertexFilename = null;
this.fragmentFilename = null;
programObject = 0;
vertexShader = 0;
fragmentShader = 0;
}
/**
* Creates a read-to-use instance of GLSLShader with vertex and fragment shaders
* Creates a shader program using the specified vertex and fragment
* shaders.
*
* @param parent PApplet
* @param vertexFN String
* @param fragmentFN String
*/
public PShader(PApplet parent, String vertexFN, String fragmentFN) {
this(parent);
loadVertexShader(vertexFN);
loadFragmentShader(fragmentFN);
setup();
public PShader(PApplet parent, String vertFilename, String fragFilename) {
this.parent = parent;
pg = (PGraphicsOpenGL) parent.g;
pgl = pg.pgl;
this.vertexURL = null;
this.fragmentURL = null;
this.vertexFilename = vertFilename;
this.fragmentFilename = fragFilename;
programObject = 0;
vertexShader = 0;
fragmentShader = 0;
}
public PShader(PApplet parent, URL vertURL, URL fragURL) {
this.parent = parent;
pg = (PGraphicsOpenGL) parent.g;
pgl = pg.pgl;
this.vertexURL = vertURL;
this.fragmentURL = fragURL;
this.vertexFilename = null;
this.fragmentFilename = null;
programObject = 0;
vertexShader = 0;
fragmentShader = 0;
}
protected void finalize() throws Throwable {
try {
@@ -89,105 +117,24 @@ public class PShader {
}
}
/**
* Loads and compiles the vertex shader contained in file.
*
* @param file String
*/
public void loadVertexShader(String file) {
String shaderSource = PApplet.join(parent.loadStrings(file), "\n");
attachVertexShader(shaderSource, file);
}
public void loadVertexShaderSource(String source) {
attachVertexShader(source, "");
}
/**
* Loads and compiles the vertex shader contained in the URL.
*
* @param file String
*/
public void loadVertexShader(URL url) {
String shaderSource;
try {
shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n");
attachVertexShader(shaderSource, url.getFile());
} catch (IOException e) {
PGraphics.showException("Cannot load shader " + url.getFile());
}
}
/**
* Loads and compiles the fragment shader contained in file.
*
* @param file String
*/
public void loadFragmentShader(String file) {
String shaderSource = PApplet.join(parent.loadStrings(file), "\n");
attachFragmentShader(shaderSource, file);
}
public void loadFragmentShaderSource(String source) {
attachFragmentShader(source, "");
}
/**
* Loads and compiles the fragment shader contained in the URL.
*
* @param url URL
*/
public void loadFragmentShader(URL url) {
String shaderSource;
try {
shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n");
attachFragmentShader(shaderSource, url.getFile());
} catch (IOException e) {
PGraphics.showException("Cannot load shader " + url.getFile());
}
}
/**
* Links the shader program and validates it.
*/
public void setup() {
pgl.linkProgram(programObject);
pgl.validateProgram(programObject);
checkLogInfo("GLSL program validation: ", programObject);
initialized = true;
}
/**
* Returns true or false depending on whether the shader is initialized or not.
*/
public boolean isInitialized() {
return initialized;
}
/**
* Starts the execution of the shader program.
*/
public void start() {
if (!initialized) {
PGraphics.showWarning("This shader is not properly initialized. Call the setup() method first");
}
// TODO:
// set the texture uniforms to the currently values texture units for all the
// textures.
// gl.glUniform1iARB(loc, unit);
pgl.startProgram(programObject);
public void start() {
init();
pgl.glUseProgram(programObject);
}
/**
* Stops the execution of the shader program.
*/
public void stop() {
pgl.stopProgram();
pgl.glUseProgram(0);
}
/**
* Returns the ID location of the attribute parameter given its name.
*
@@ -195,9 +142,11 @@ public class PShader {
* @return int
*/
public int getAttribLocation(String name) {
return pgl.getAttribLocation(programObject, name);
init();
return pgl.glGetAttribLocation(programObject, name);
}
/**
* Returns the ID location of the uniform parameter given its name.
*
@@ -205,259 +154,191 @@ public class PShader {
* @return int
*/
public int getUniformLocation(String name) {
return pgl.getUniformLocation(programObject, name);
init();
return pgl.glGetUniformLocation(programObject, name);
}
/**
* Sets the texture uniform name with the texture unit to use
* in the said uniform.
*
* @param name String
* @param unit int
*/
public void setTexUniform(String name, int unit) {
int loc = getUniformLocation(name);
if (-1 < loc) {
pgl.setIntUniform(loc, unit);
}
public void setIntUniform(int loc, int x) {
pgl.glUniform1i(loc, x);
}
public void set1FloatUniform(int loc, float x) {
pgl.glUniform1f(loc, x);
}
/**
* Sets the texture uniform with the unit of tex is attached to
* at the moment of running the shader.
*
* @param name String
* @param tex GLTexture
*/
/*
public void setTexUniform(String name, PTexture tex) {
int loc = getUniformLocation(name);
if (-1 < loc) {
int tu = tex.getTextureUnit();
if (-1 < tu) {
// If tex is already bound to a texture unit, we use
// it as the value for the uniform.
gl.glUniform1iARB(loc, tu);
}
tex.setTexUniform(loc);
}
public void set2FloatUniform(int loc, float x, float y) {
pgl.glUniform2f(loc, x, y);
}
*/
/**
* Sets the int uniform with name to the given value
*
* @param name String
* @param x int
*/
public void setIntUniform(String name, int x) {
int loc = getUniformLocation(name);
if (-1 < loc) {
pgl.setIntUniform(loc, x);
}
}
/**
* Sets the float uniform with name to the given value
*
* @param name String
* @param x float
*/
public void setFloatUniform(String name, float x) {
int loc = getUniformLocation(name);
if (-1 < loc) {
pgl.setFloatUniform(loc, x);
}
}
/**
* Sets the vec2 uniform with name to the given values.
*
* @param nam String
* @param x float
* @param y float
*/
public void setVecUniform(String name, float x, float y) {
int loc = getUniformLocation(name);
if (-1 < loc) {
pgl.setFloatUniform(loc, x, y);
}
public void set3FloatUniform(int loc, float x, float y, float z) {
pgl.glUniform3f(loc, x, y, z);
}
/**
* Sets the vec3 uniform with name to the given values.
*
* @param name String
* @param x float
* @param y float
* @param z float
*/
public void setVecUniform(String name, float x, float y, float z) {
int loc = getUniformLocation(name);
if (-1 < loc) {
pgl.setFloatUniform(loc, x, y, z);
}
}
/**
* Sets the vec4 uniform with name to the given values.
*
* @param name String
* @param x float
* @param y float
* @param z float
* @param w float
*/
public void setVecUniform(String name, float x, float y, float z, float w) {
int loc = getUniformLocation(name);
if (-1 < loc) {
pgl.setFloatUniform(loc, x, y, z, w);
}
}
public void set4FloatUniform(int loc, float x, float y, float z, float w) {
pgl.glUniform4f(loc, x, y, z, w);
}
/**
* Sets the mat2 uniform with name to the given values
*
* @param name String
* @param m00 float
* ...
*/
public void setMatUniform(String name, float m00, float m01,
float m10, float m11) {
int loc = getUniformLocation(name);
if (-1 < loc) {
pgl.setMatUniform(loc, m00, m01,
m10, m11);
}
}
/**
* Sets the mat3 uniform with name to the given values
*
* @param name String
* @param m00 float
* ...
*/
public void setMatUniform(String name, float m00, float m01, float m02,
float m10, float m11, float m12,
float m20, float m21, float m22) {
int loc = getUniformLocation(name);
if (-1 < loc) {
pgl.setMatUniform(loc, m00, m01, m02,
m10, m11, m12,
m20, m21, m22);
}
public void set1FloatVecUniform(int loc, float[] vec) {
pgl.glUniform1fv(loc, vec.length, vec, 0);
}
/**
* Sets the mat3 uniform with name to the given values
*
* @param name String
* @param m00 float
* ...
*/
public void setMatUniform(String name, float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33) {
int loc = getUniformLocation(name);
if (-1 < loc) {
pgl.setMatUniform(loc, m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23,
m30, m31, m32, m33);
}
}
/**
* Sets the float attribute with name to the given value
*
* @param name String
* @param x float
*/
public void setFloatAttribute(String name, float x) {
int loc = getAttribLocation(name);
if (-1 < loc) {
pgl.setFloatAttrib(loc, x);
}
public void set2FloatVecUniform(int loc, float[] vec) {
pgl.glUniform2fv(loc, vec.length / 2, vec, 0);
}
public void set3FloatVecUniform(int loc, float[] vec) {
pgl.glUniform3fv(loc, vec.length / 3, vec, 0);
}
public void set4FloatVecUniform(int loc, float[] vec) {
pgl.glUniform4fv(loc, vec.length / 4, vec, 0);
}
public void set2x2MatUniform(int loc, float[] mat) {
pgl.glUniformMatrix2fv(loc, 1, false, mat, 0);
}
public void set3x3MatUniform(int loc, float[] mat) {
pgl.glUniformMatrix3fv(loc, 1, false, mat, 0);
}
public void set4x4MatUniform(int loc, float[] mat) {
pgl.glUniformMatrix4fv(loc, 1, false, mat, 0);
}
public void set1FloatAttribute(int loc, float x) {
pgl.glVertexAttrib1f(loc, x);
}
public void set2FloatAttribute(int loc, float x, float y) {
pgl.glVertexAttrib2f(loc, x, y);
}
public void set3FloatAttribute(int loc, float x, float y, float z) {
pgl.glVertexAttrib3f(loc, x, y, z);
}
public void set4FloatAttribute(int loc, float x, float y, float z, float w) {
pgl.glVertexAttrib4f(loc, x, y, z, w);
}
protected void init() {
if (programObject == 0) {
programObject = pg.createGLSLProgramObject();
if (vertexFilename != null && fragmentFilename != null) {
loadVertexShader(vertexFilename);
loadFragmentShader(fragmentFilename);
} else if (vertexURL != null && fragmentURL != null) {
loadVertexShader(vertexURL);
loadFragmentShader(fragmentURL);
} else {
PGraphics.showException("Shader filenames and URLs are both null!");
}
checkLogInfo("Vertex shader " + vertexFilename + " compilation: ", vertexShader);
checkLogInfo("Fragment shader " + fragmentFilename + " compilation: ", fragmentShader);
pgl.glLinkProgram(programObject);
pgl.glValidateProgram(programObject);
}
}
/**
* Sets the vec2 attribute with name to the given values
* Loads and compiles the vertex shader contained in file.
*
* @param name String
* @param float x
* @param float y
* @param file String
*/
public void setVecAttribute(String name, float x, float y) {
int loc = getAttribLocation(name);
if (-1 < loc) {
pgl.setFloatAttrib(loc, x, y);
}
}
protected void loadVertexShader(String filename) {
String shaderSource = PApplet.join(parent.loadStrings(filename), "\n");
attachVertexShader(shaderSource);
}
/**
* Sets the vec3 attribute with name to the given values
* Loads and compiles the vertex shader contained in the URL.
*
* @param name String
* @param float x
* @param float y
* @param float z
*/
public void setVecAttribute(String name, float x, float y, float z) {
int loc = getAttribLocation(name);
if (-1 < loc) {
pgl.setFloatAttrib(loc, x, y, z);
* @param file String
*/
protected void loadVertexShader(URL url) {
try {
String shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n");
attachVertexShader(shaderSource);
} catch (IOException e) {
PGraphics.showException("Cannot load shader " + url.getFile());
}
}
/**
* Loads and compiles the fragment shader contained in file.
*
* @param file String
*/
protected void loadFragmentShader(String filename) {
String shaderSource = PApplet.join(parent.loadStrings(filename), "\n");
attachFragmentShader(shaderSource);
}
/**
* Sets the vec4 attribute with name to the given values
* Loads and compiles the fragment shader contained in the URL.
*
* @param name String
* @param float x
* @param float y
* @param float z
* @param float w
*/
public void setVecAttribute(String name, float x, float y, float z, float w) {
int loc = getAttribLocation(name);
if (-1 < loc) {
pgl.setFloatAttrib(loc, x, y, z, w);
* @param url URL
*/
protected void loadFragmentShader(URL url) {
try {
String shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n");
attachFragmentShader(shaderSource);
} catch (IOException e) {
PGraphics.showException("Cannot load shader " + url.getFile());
}
}
}
/**
* @param shaderSource a string containing the shader's code
* @param filename the shader's filename, used to print error log information
*/
private void attachVertexShader(String shaderSource, String file) {
protected void attachVertexShader(String shaderSource) {
vertexShader = pg.createGLSLVertShaderObject();
pgl.setShaderSource(vertexShader, shaderSource);
pgl.compileShader(vertexShader);
checkLogInfo("Vertex shader " + file + " compilation: ", vertexShader);
pgl.attachShader(programObject, vertexShader);
pgl.glShaderSource(vertexShader, shaderSource);
pgl.glCompileShader(vertexShader);
pgl.glAttachShader(programObject, vertexShader);
}
/**
* @param shaderSource a string containing the shader's code
* @param filename the shader's filename, used to print error log information
*/
private void attachFragmentShader(String shaderSource, String file) {
protected void attachFragmentShader(String shaderSource) {
fragmentShader = pg.createGLSLFragShaderObject();
pgl.setShaderSource(fragmentShader, shaderSource);
pgl.compileShader(fragmentShader);
checkLogInfo("Fragment shader " + file + " compilation: ", fragmentShader);
pgl.attachShader(programObject, fragmentShader);
pgl.glShaderSource(fragmentShader, shaderSource);
pgl.glCompileShader(fragmentShader);
pgl.glAttachShader(programObject, fragmentShader);
}
/**
* @invisible Check the log error for the opengl object obj. Prints error
* message if needed.
* Check the log error for the opengl object obj. Prints error
* message if needed.
*/
protected void checkLogInfo(String title, int obj) {
String log = pgl.getShaderLog(obj);
@@ -467,6 +348,7 @@ public class PShader {
}
}
protected void release() {
if (vertexShader != 0) {
pg.deleteGLSLVertShaderObject(vertexShader);
@@ -480,43 +362,6 @@ public class PShader {
pg.deleteGLSLProgramObject(programObject);
programObject = 0;
}
}
/*
*
*
* GL.GL_BOOL_ARB GL.GL_BOOL_VEC2_ARB GL.GL_BOOL_VEC3_ARB GL.GL_BOOL_VEC4_ARB
* GL.GL_FLOAT GL.GL_FLOAT_MAT2_ARB GL.GL_FLOAT_MAT3_ARB GL.GL_FLOAT_MAT4_ARB
* GL.GL_FLOAT_VEC2_ARB GL.GL_FLOAT_VEC3_ARB GL.GL_FLOAT_VEC4_ARB GL.GL_INT
* GL.GL_INT_VEC2_ARB GL.GL_INT_VEC3_ARB GL.GL_INT_VEC4_ARB
*
* gl.glUseProgramObjectARB(program);
*
* // Build a mapping from texture parameters to texture units.
* texUnitMap.clear(); int count, size; int type; byte[] paramName = new
* byte[1024];
*
* int texUnit = 0;
*
* int[] iVal = { 0 }; gl.glGetObjectParameterivARB(fragmentProgram,
* GL.GL_OBJECT_COMPILE_STATUS_ARB, iVal, 0); count = iVal[0]; for (int i = 0;
* i < count; ++i) { IntBuffer iVal1 = BufferUtil.newIntBuffer(1); IntBuffer
* iVal2 = BufferUtil.newIntBuffer(1);
*
* ByteBuffer paramStr = BufferUtil.newByteBuffer(1024);
* gl.glGetActiveUniformARB(program, i, 1024, null, iVal1, iVal2, paramStr);
* size = iVal1.get(); type = iVal2.get(); paramStr.get(paramName);
*
* if ((type == GL.GL_SAMPLER_1D_ARB) || (type == GL.GL_SAMPLER_2D_ARB) ||
* (type == GL.GL_SAMPLER_3D_ARB) || (type == GL.GL_SAMPLER_CUBE_ARB) || (type
* == GL.GL_SAMPLER_1D_SHADOW_ARB) || (type == GL.GL_SAMPLER_2D_SHADOW_ARB) ||
* (type == GL.GL_SAMPLER_2D_RECT_ARB) || (type ==
* GL.GL_SAMPLER_2D_RECT_SHADOW_ARB)) { String strName = new String(paramName,
* 0, 1024); Integer unit = texUnit; texUnitMap.put(strName, unit); int
* location = gl.glGetUniformLocationARB(program, strName);
* gl.glUniform1iARB(location, texUnit); ++texUnit; } }
*
* gl.glUseProgramObjectARB(0); }
*/
}
}
File diff suppressed because it is too large Load Diff
@@ -27,6 +27,7 @@ import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PGraphics;
import processing.core.PImage;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
@@ -41,10 +42,10 @@ import java.util.NoSuchElementException;
public class PTexture implements PConstants {
public int width, height;
protected PApplet parent; // The Processing applet
protected PGraphicsOpenGL pg; // The main renderer
protected PGL pgl; // The interface between Processing and OpenGL.
protected PGL.Context context; // The context that created this texture.
protected PApplet parent; // The Processing applet
protected PGraphicsOpenGL pg; // The main renderer
protected PGL pgl; // The interface between Processing and OpenGL.
protected PGL.Context context; // The context that created this texture.
// These are public but use at your own risk!
public int glID;
@@ -247,15 +248,15 @@ public class PTexture implements PConstants {
}
pgl.enableTexturing(glTarget);
pgl.bindTexture(glTarget, glID);
pgl.glBindTexture(glTarget, glID);
if (usingMipmaps) {
if (PGraphicsOpenGL.mipmapGeneration) {
// Automatic mipmap generation.
int[] rgbaPixels = new int[w * h];
convertToRGBA(pixels, rgbaPixels, format, w, h);
pgl.enableTexMipmapGen(glTarget);
setTexels(rgbaPixels, x, y, w, h);
convertToRGBA(pixels, rgbaPixels, format, w, h);
setTexels(rgbaPixels, x, y, w, h);
pgl.glGenerateMipmap(glTarget);
rgbaPixels = null;
} else {
// TODO: Manual mipmap generation.
@@ -269,7 +270,7 @@ public class PTexture implements PConstants {
rgbaPixels = null;
}
pgl.bindTexture(glTarget, 0);
pgl.glBindTexture(glTarget, 0);
pgl.disableTexturing(glTarget);
}
@@ -412,12 +413,12 @@ public class PTexture implements PConstants {
public void bind() {
pgl.enableTexturing(glTarget);
pgl.bindTexture(glTarget, glID);
pgl.glBindTexture(glTarget, glID);
}
public void unbind() {
pgl.enableTexturing(glTarget);
pgl.unbindTexture(glTarget);
pgl.glBindTexture(glTarget, 0);
}
////////////////////////////////////////////////////////////
@@ -772,37 +773,25 @@ public class PTexture implements PConstants {
*/
protected void allocate() {
release(); // Just in the case this object is being re-allocated.
pgl.enableTexturing(glTarget);
glID = pg.createTextureObject();
pgl.bindTexture(glTarget, glID);
pgl.setTexMinFilter(glTarget, glMinFilter);
pgl.setTexMagFilter(glTarget, glMagFilter);
pgl.setTexWrapS(glTarget, glWrapS);
pgl.setTexWrapT(glTarget, glWrapT);
pgl.glBindTexture(glTarget, glID);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MIN_FILTER, glMinFilter);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MAG_FILTER, glMagFilter);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_S, glWrapS);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_T, glWrapT);
// First, we use glTexImage2D to set the full size of the texture (glW/glH might be diff
// from w/h in the case that the GPU doesn't support NPOT textures)
pgl.initTex(glTarget, glFormat, glWidth, glHeight);
pgl.glTexImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, null);
// Once OpenGL knows the size of the new texture, we make sure it doesn't
// contain any garbage in the region of interest (0, 0, width, height):
// Doing in patches of 16x16 pixels to avoid creating a (potentially)
// very large transient array which in certain situations (memory-
// constrained android devices) might lead to an out-of-memory error.
int[] texels = new int[16 * 16];
for (int y = 0; y < height + 16; y += 16) {
int h = PApplet.min(16, height - y);
for (int x = 0; x < width + 16; x += 16) {
int w = PApplet.min(16, width - x);
setTexels(texels, x, y, w, h);
}
}
texels = null;
// Makes sure that the texture buffer in video memory doesn't contain any garbage.
pgl.initTexture(glTarget, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE);
pgl.unbindTexture(glTarget);
pgl.glBindTexture(glTarget, 0);
pgl.disableTexturing(glTarget);
}
@@ -858,7 +847,7 @@ public class PTexture implements PConstants {
}
protected void setTexels(int[] pix, int level, int x, int y, int w, int h) {
pgl.copyTexSubImage(pix, glTarget, level, x, y, w, h);
pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, IntBuffer.wrap(pix));
}
protected void setTexels(IntBuffer buffer, int x, int y, int w, int h) {
@@ -866,7 +855,7 @@ public class PTexture implements PConstants {
}
protected void setTexels(IntBuffer buffer, int level, int x, int y, int w, int h) {
pgl.copyTexSubImage(buffer, glTarget, level, x, y, w, h);
pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer);
}
protected void copyObject(PTexture src) {
@@ -905,35 +894,35 @@ public class PTexture implements PConstants {
public Parameters getParameters() {
Parameters res = new Parameters();
if (glTarget == PGL.TEXTURE_2D) {
if (glTarget == PGL.GL_TEXTURE_2D) {
res.target = TEXTURE2D;
}
if (glFormat == PGL.RGB) {
if (glFormat == PGL.GL_RGB) {
res.format = RGB;
} else if (glFormat == PGL.RGBA) {
} else if (glFormat == PGL.GL_RGBA) {
res.format = ARGB;
} else if (glFormat == PGL.ALPHA) {
} else if (glFormat == PGL.GL_ALPHA) {
res.format = ALPHA;
}
if (glMinFilter == PGL.NEAREST) {
if (glMinFilter == PGL.GL_NEAREST) {
res.sampling = POINT;
} else if (glMinFilter == PGL.LINEAR) {
} else if (glMinFilter == PGL.GL_LINEAR) {
res.sampling = BILINEAR;
} else if (glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) {
} else if (glMinFilter == PGL.GL_LINEAR_MIPMAP_LINEAR) {
res.sampling = TRILINEAR;
}
if (glWrapS == PGL.CLAMP_TO_EDGE) {
if (glWrapS == PGL.GL_CLAMP_TO_EDGE) {
res.wrapU = CLAMP;
} else if (glWrapS == PGL.REPEAT) {
} else if (glWrapS == PGL.GL_REPEAT) {
res.wrapU = REPEAT;
}
if (glWrapT == PGL.CLAMP_TO_EDGE) {
if (glWrapT == PGL.GL_CLAMP_TO_EDGE) {
res.wrapV = CLAMP;
} else if (glWrapT == PGL.REPEAT) {
} else if (glWrapT == PGL.GL_REPEAT) {
res.wrapV = REPEAT;
}
@@ -948,51 +937,51 @@ public class PTexture implements PConstants {
*/
protected void setParameters(Parameters params) {
if (params.target == TEXTURE2D) {
glTarget = PGL.TEXTURE_2D;
glTarget = PGL.GL_TEXTURE_2D;
} else {
throw new RuntimeException("OPENGL2: Unknown texture target");
}
if (params.format == RGB) {
glFormat = PGL.RGB;
glFormat = PGL.GL_RGB;
} else if (params.format == ARGB) {
glFormat = PGL.RGBA;
glFormat = PGL.GL_RGBA;
} else if (params.format == ALPHA) {
glFormat = PGL.ALPHA;
glFormat = PGL.GL_ALPHA;
} else {
throw new RuntimeException("OPENGL2: Unknown texture format");
}
if (params.sampling == POINT) {
glMagFilter = PGL.NEAREST;
glMinFilter = PGL.NEAREST;
glMagFilter = PGL.GL_NEAREST;
glMinFilter = PGL.GL_NEAREST;
} else if (params.sampling == BILINEAR) {
glMagFilter = PGL.LINEAR;
glMinFilter = PGL.LINEAR;
glMagFilter = PGL.GL_LINEAR;
glMinFilter = PGL.GL_LINEAR;
} else if (params.sampling == TRILINEAR) {
glMagFilter = PGL.LINEAR;
glMinFilter = PGL.LINEAR_MIPMAP_LINEAR;
glMagFilter = PGL.GL_LINEAR;
glMinFilter = PGL.GL_LINEAR_MIPMAP_LINEAR;
} else {
throw new RuntimeException("OPENGL2: Unknown texture filtering mode");
}
if (params.wrapU == CLAMP) {
glWrapS = PGL.CLAMP_TO_EDGE;
glWrapS = PGL.GL_CLAMP_TO_EDGE;
} else if (params.wrapU == REPEAT) {
glWrapS = PGL.REPEAT;
glWrapS = PGL.GL_REPEAT;
} else {
throw new RuntimeException("OPENGL2: Unknown wrapping mode");
}
if (params.wrapV == CLAMP) {
glWrapT = PGL.CLAMP_TO_EDGE;
glWrapT = PGL.GL_CLAMP_TO_EDGE;
} else if (params.wrapV == REPEAT) {
glWrapT = PGL.REPEAT;
glWrapT = PGL.GL_REPEAT;
} else {
throw new RuntimeException("OPENGL2: Unknown wrapping mode");
}
usingMipmaps = glMinFilter == PGL.LINEAR_MIPMAP_LINEAR;
usingMipmaps = glMinFilter == PGL.GL_LINEAR_MIPMAP_LINEAR;
flippedX = false;
flippedY = false;
@@ -1,84 +0,0 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2011 Andres Colubri
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
attribute vec2 vertDisp;
uniform vec4 eye;
uniform int lights;
// From the "Directional Lights I & II" tutorials from lighthouse 3D:
// http://www.lighthouse3d.com/tutorials/glsl-tutorial/directional-lights-i/
vec4 calculateLight(int i) {
// Per-vertex diffuse and ambient lighting.
vec3 normal, lightDir;
vec4 diffuse, ambient, specular;
float NdotL, NdotHV;
// first transform the normal into eye space and normalize the result.
normal = normalize(gl_NormalMatrix * gl_Normal);
// now normalize the light's direction. Note that according to the
// OpenGL specification, the light is stored in eye space. Also since
// we're talking about a directional light, the position field is actually
// direction
lightDir = normalize(vec3(gl_LightSource[i].position));
// compute the cos of the angle between the normal and lights direction.
// The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also
// need to clamp the result to the [0,1] range.
NdotL = max(dot(normal, lightDir), 0.0);
// Compute the diffuse term. Ambient and diffuse material components
// are stored in the vertex color, since processing uses GL_COLOR_MATERIAL
diffuse = gl_Color * gl_LightSource[i].diffuse;
// Compute the ambient and globalAmbient terms
ambient = gl_Color * gl_LightSource[i].ambient;
// compute the specular term if NdotL is larger than zero
if (NdotL > 0.0) {
// normalize the half-vector, and then compute the
// cosine (dot product) with the normal
NdotHV = max(dot(normal, gl_LightSource[i].halfVector.xyz), 0.0);
specular = gl_FrontMaterial.specular * gl_LightSource[i].specular * pow(NdotHV, gl_FrontMaterial.shininess);
}
return NdotL * diffuse + ambient;
}
void main() {
vec4 pos = gl_ModelViewMatrix * gl_Vertex;
pos.xy += vertDisp.xy;
gl_Position = gl_ProjectionMatrix * pos;
vec4 color = vec4(0, 0, 0, 0);
vec4 globalAmbient = gl_Color * gl_LightModel.ambient;
if (lights == 0) {
color = gl_Color;
}
for (int i = 0; i < lights; i++) {
vec4 light = calculateLight(i);
color += light;
}
color = clamp(color, 0.0, 1.0);
gl_FrontColor = color;
}