Hello All !
I'm far from my initial question but I found the solution I was looking for ! :)
It's actually possible to add custom attributes that affect Vertex & Fragment shader, and it's very easy to do !
Here is an exemple based on the 'TextureQuad' example :
- import java.nio.*;
- PImage img;
- PShader testShader;
- PGL pgl;
- float[] scales;
- float[] colors;
- FloatBuffer scaleData;
- FloatBuffer colorData;
- int scaleLoc;
- int colorLoc;
- void setup() {
- size(640, 360, P3D);
- img = loadImage("Desert.jpg");
- testShader = loadShader("fragment.glsl","vertex.glsl");
- scales = new float[16];
- scales[0] = scales[1] = scales[2] = scales[3] = scales[4] = scales[5] = scales[6] = scales[7] = scales[8] = scales[9] = scales[10] = scales[11] = scales[12] = scales[13] = scales[14] = scales[15] = 0.5;
- colors = new float[16];
- colors[0] = colors[4] = colors[8] = colors[12] = 1;
- colors[1] = colors[5] = colors[9] = colors[13] = 0;
- colors[2] = colors[6] = colors[10] = colors[14] = 0;
- colors[3] = colors[7] = colors[11] = colors[15] = 1;
- scaleData = allocateDirectFloatBuffer(16);
- scaleData.put(scales);
- scaleData.position(0);
- colorData = allocateDirectFloatBuffer(16);
- colorData.put(colors);
- colorData.position(0);
- noStroke();
- }
- void draw() {
- background(0);
- translate(width / 2, height / 2);
- rotateY(map(mouseX, 0, width, -PI, PI));
- rotateZ(PI/6);
- pgl = beginPGL();
- scaleLoc = pgl.getAttribLocation(testShader.glProgram, "inScale");
- pgl.enableVertexAttribArray(scaleLoc);
- pgl.vertexAttribPointer(scaleLoc, 4, PGL.FLOAT, false, 0, scaleData);
- colorLoc = pgl.getAttribLocation(testShader.glProgram, "inColour");
- pgl.enableVertexAttribArray(colorLoc);
- pgl.vertexAttribPointer(colorLoc, 4, PGL.FLOAT, false, 0, colorData);
- endPGL();
- shader(testShader);
- beginShape();
- texture(img);
- vertex(-100, -100, 0, 0, 0);
- vertex(100, -100, 0, img.width, 0);
- vertex(100, 100, 0, img.width, img.height);
- vertex(-100, 100, 0, 0, img.height);
- endShape();
- resetShader();
- }
- FloatBuffer allocateDirectFloatBuffer(int n) {
- return ByteBuffer.allocateDirect(n * Float.SIZE/8).order(ByteOrder.nativeOrder()).asFloatBuffer();
- }
My vertexShader
- uniform mat4 projmodelviewMatrix;
- //custom attributes
- attribute vec4 inScale;
- attribute vec4 inColour; //inColor cannot be overrided (it always a white color)
- //so I renamed it 'colour' for the test.
- attribute vec4 inVertex;
- attribute vec2 inTexcoord;
- varying vec2 vertTexcoord;
- varying vec4 vertColor;
- void main() {
- // Vertex in clip coordinates
- vec4 pos = projmodelviewMatrix * inVertex;
- pos.xy *= inScale.xy;
- gl_Position = pos;
- vertTexcoord = inTexcoord;
- vertColor = inColour;
- }
and my fragmentShader
- #ifdef GL_ES
- precision mediump float;
- precision mediump int;
- #endif
- uniform sampler2D textureSampler;
- varying vec2 vertTexcoord;
- varying vec4 vertColor;
- void main() {
- vec4 texture = texture2D(textureSampler, vertTexcoord);
- texture.xyz *= vertColor.xyz;
- gl_FragColor = texture;
- }
The whole code draw a textured-colorTransformed-scaled quad. The color used in the colorTransform operation come from the 'fill' instruction.
It's much more easy than Flash, I'm impressed ! :)
EDIT : I have an error "OpenGL error 1281 at top endDraw(): invalid value" but all works fine. Other people already had these error but they didn't know why (all works fine for them too)