commit d1e663b360fae7094a973081b2e1a14d0e5dd0a9
parent 4bd631d2c7c5f09f7a23c969eb5675b9a18c3712
Author: Brian Swetland <swetland@frotz.net>
Date: Wed, 4 Sep 2013 05:38:55 -0700
shader and uniform management wip
- provide standardized c++ and glsl structs for scene, object, and material uniform blocks
- move some legacy shaders to "block3" to avoid conflicts for now
- lighting and uniform management tests have made object test more complex for now
Diffstat:
9 files changed, 198 insertions(+), 55 deletions(-)
diff --git a/common/assets/textgrid.glsl b/common/assets/textgrid.glsl
@@ -3,7 +3,7 @@
-- vertex
-layout(std140) uniform cb0 {
+layout(std140) uniform block3 {
mat4 MVP;
int cw;
int ch;
diff --git a/common/shaders.cc b/common/shaders.cc
@@ -18,6 +18,7 @@
#include "app.h"
#include "util.h"
+#include "matrix.h"
#define INCLUDE_SHADER_GLOBALS 1
#include "shared.h"
diff --git a/common/shared.h b/common/shared.h
@@ -23,11 +23,50 @@
#define A_NORMAL 1
#define A_TEXCOORD 2
+#define U_SCENE 0
+#define U_OBJECT 1
+#define U_MATERIAL 2
+
+struct ubScene {
+ mat4 Ortho; /* 1:1 2D mapping */
+ vec4 OrthoSize; /* x,y = width,height */
+ vec4 LightColor;
+ vec4 LightPosition;
+};
+
+struct ubObject {
+ mat4 mvp;
+ mat4 mv;
+};
+
+struct ubMaterial {
+ vec4 Ambient;
+ vec4 Diffuse;
+ vec4 Specular;
+ float Shininess;
+};
+
#if INCLUDE_SHADER_GLOBALS
static const char *shader_globals =
"#define A_POSITION 0\n"
"#define A_NORMAL 1\n"
"#define A_TEXCOORD 2\n"
+"layout(std140) uniform block0 {\n"
+" mat4 Ortho;\n"
+" vec4 OrthoSize;\n"
+" vec4 LightColor;\n"
+" vec4 LightPosition;\n"
+"} SCN;\n"
+"layout(std140) uniform block1 {\n"
+" mat4 MVP;\n"
+" mat4 MV;\n"
+"} OBJ;\n"
+"layout(std140) uniform block2 {\n"
+" vec4 Ambient;\n"
+" vec4 Diffuse;\n"
+" vec4 Specular;\n"
+" float Shininess;\n"
+"} MAT;\n"
;
#endif
diff --git a/common/textgrid.cc b/common/textgrid.cc
@@ -104,7 +104,7 @@ void TextGrid::render(App *a) {
}
pgm.use();
attr.use();
- ubuf.use(0);
+ ubuf.use(3);
texture.use(0);
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, width * height);
}
diff --git a/hello/assets/simple.glsl b/hello/assets/simple.glsl
@@ -3,7 +3,7 @@
-- vertex
-layout(std140) uniform block0 {
+layout(std140) uniform block3 {
mat4 MVP;
mat4 MV;
};
diff --git a/hello/hello.cc b/hello/hello.cc
@@ -205,7 +205,7 @@ oops:
pgm.use();
ubuf.load(&cb0, sizeof(cb0));
- ubuf.use(0);
+ ubuf.use(3);
attr.use();
glDrawElementsInstanced(GL_TRIANGLES, m->icount, GL_UNSIGNED_SHORT, NULL, lcount);
diff --git a/test/assets/flat.glsl b/test/assets/flat.glsl
@@ -0,0 +1,16 @@
+#version 140
+#extension GL_ARB_explicit_attrib_location : enable
+
+-- vertex
+
+layout (location = A_POSITION) in vec4 aPosition;
+
+void main() {
+ gl_Position = OBJ.MVP * aPosition;
+}
+
+-- fragment
+
+void main() {
+ gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
+}
diff --git a/test/assets/simple.glsl b/test/assets/simple.glsl
@@ -1,50 +1,57 @@
#version 140
#extension GL_ARB_explicit_attrib_location : enable
-#define TEXTURED 1
+//#define TEXTURED
+//#define SPECULAR
-- vertex
-layout(std140) uniform block0 {
- mat4 MVP;
- mat4 MV;
-};
+layout (location = A_POSITION) in vec4 aPosition;
+layout (location = A_NORMAL) in vec3 aNormal;
+layout (location = A_TEXCOORD) in vec2 aTexCoord;
-layout (location = A_POSITION) in vec4 POSITION;
-layout (location = A_NORMAL) in vec4 NORMAL;
-layout (location = A_TEXCOORD) in vec2 TEXCOORD;
-
-out vec2 vTEXCOORD;
-out float vDIFFUSE;
-out vec4 vCOLOR;
+out vec2 vTexCoord;
+out vec3 vPosition; // eye space
+out vec3 vNormal; // eye space
void main() {
- vec4 pos = POSITION;
-
- vec3 mvPosition = (MV * pos).xyz;
- vec3 mvNormal = (MV * vec4(NORMAL.xyz,0.0)).xyz;
-
- vec3 lightVec = normalize(vec3(10,20,25) - mvPosition);
- float diffuse = max(dot(mvNormal, lightVec), 0.0);
-
- gl_Position = MVP * POSITION;
- vTEXCOORD = TEXCOORD;
- vDIFFUSE = diffuse;
+ vPosition = (OBJ.MV * aPosition).xyz;
+ vNormal = (OBJ.MV * vec4(aNormal, 0.0)).xyz;
+ vTexCoord = aTexCoord;
+ gl_Position = OBJ.MVP * aPosition;
}
-- fragment
-in vec2 vTEXCOORD;
-in float vDIFFUSE;
+in vec2 vTexCoord;
+in vec3 vPosition;
+in vec3 vNormal;
uniform sampler2D sampler0;
void main() {
-#if TEXTURED
- gl_FragColor = texture2D(sampler0, vTEXCOORD);
+#ifdef TEXTURED
+ vec4 c = texture2D(sampler0, vTexCoord);
#else
vec4 c = vec4(1.0, 0.0, 0.0, 1.0);
- gl_FragColor = c * 0.25 + c * vDIFFUSE;
#endif
+ vec3 n = normalize(vNormal);
+ vec3 s;
+ if (SCN.LightPosition.w > 0) {
+ /* positional light, compute direction */
+ s = normalize(SCN.LightPosition.xyz - vPosition);
+ } else {
+ /* directional light - light position is actually a vector */
+ s = SCN.LightPosition.xyz;
+ }
+ vec3 v = normalize(-vPosition);
+ vec3 h = normalize(v + s);
+
+ gl_FragColor = MAT.Ambient * c
+ + MAT.Diffuse * c * max( dot(s, n), 0.0)
+#ifdef SPECULAR
+ + MAT.Specular * SCN.LightColor * pow( max( dot(h,n), 0.0), MAT.Shininess)
+#endif
+ ;
}
diff --git a/test/object.cc b/test/object.cc
@@ -15,17 +15,59 @@
#include "app.h"
#include "matrix.h"
+#include "shared.h"
#include "Model.h"
#include "Effect.h"
+struct Grid {
+ Grid(float size, unsigned steps) {
+ static VertexAttrDesc layout[] = {
+ { 0, SRC_FLOAT, DST_FLOAT, 3, 0, 12, 0 },
+ };
+ count = (steps + 1) * 4;
+ VertexBuffer *vb = &buf;
+ float x, z;
+ float *varr = (float*) malloc(sizeof(float) * 3 * count);
+ float *vtx = varr;
+ float min = -(size / 2.0);
+ float max = (size / 2.0) + 0.0001;
+ float step = size / ((float) steps);
+ for (x = min; x < max; x += step) {
+ vtx[0] = x;
+ vtx[1] = 0.0;
+ vtx[2] = min;
+ vtx[3] = x;
+ vtx[4] = 0.0;
+ vtx[5] = max;
+ vtx += 6;
+ }
+ for (z = min; z < max; z += step) {
+ vtx[0] = min;
+ vtx[1] = 0.0;
+ vtx[2] = z;
+ vtx[3] = max;
+ vtx[4] = 0.0;
+ vtx[5] = z;
+ vtx += 6;
+ }
+ buf.load(varr, count * 3 * sizeof(float));
+ attr.init(layout, &vb, 1);
+ }
+ void render(void) {
+ attr.use();
+ glDrawArrays(GL_LINES, 0, count);
+ }
+ VertexBuffer buf;
+ VertexAttributes attr;
+ unsigned count;
+};
+
class TestApp : public App {
public:
TestApp();
int init(void);
void render(void);
- void release(void);
- void build(void);
private:
float r;
@@ -33,46 +75,84 @@ private:
Model *m;
Effect *e;
- UniformBuffer ubuf;
+ Grid *g;
+ Effect *ge;
+
+ UniformBuffer obj, mat, scn;
mat4 proj;
};
-TestApp::TestApp() : App(), r(0.0) {
-}
-
-void TestApp::release(void) {
-}
+TestApp::TestApp() : App(), r(0.0) { }
int TestApp::init(void) {
- if (!(m = Model::load("cube")))
+ if (!(m = Model::load("unitcubeoid")))
return error("cannot load cube object");
- if (!(e = Effect::load("simple")))
+ if (!(e = Effect::load("simple+SPECULAR")))
return error("could not load simple effect");
+
+ g = new Grid(10.0, 20);
+ ge = Effect::load("flat");
proj.setPerspective(D2R(90.0), width / (float) height, 0.1f, 250.0f);
return 0;
}
+int frame = 0;
void TestApp::render(void) {
- struct {
- mat4 mvp;
- mat4 mv;
- } cb0;
- mat4 world, view, tmp;
+ struct ubScene scene;
+ struct ubObject object;
+ struct ubMaterial material;
+ mat4 model, view, tmp;
- r += 0.010;
- if (r > 360.0) r = 0.0;
+ frame ++;
- view.identity().rotateX(D2R(10)).rotateY(r).translate(0,0,-2);
- world.identity();
+ r += 1.0;
+ if (r > 360.0) r = 0.0;
- cb0.mvp = world * view * proj;
- cb0.mv = world * view;
+ view.camera(vec3(1.5, 1.0, 2.0), vec3(1.5, 1.0, 0.0), vec3(0, 1, 0));
+
+ model.identity();
+ object.mvp = model * view * proj;
+ object.mv = model * view;
+ obj.load(&object, sizeof(object));
+ obj.use(U_OBJECT);
+ ge->apply();
+ g->render();
+
+ scene.LightColor.set(1.0, 1.0, 1.0);
+ scene.LightPosition.set(0.0, 1.0, 0.0, 0.0);
+ scn.load(&scene, sizeof(scene));
+ scn.use(U_SCENE);
+
+ material.Ambient.set(0.325,0.325,0.325,1.0);
+ material.Diffuse.set(1.0,1.0,1.0,1.0);
+ material.Specular.set(1.0,1.0,1.0,1.0);
+ material.Specular.set(0, 0, 0, 0);
+ material.Shininess = 50.0f;
+ mat.load(&material, sizeof(material));
+ mat.use(U_MATERIAL);
+
+ model.identity().rotateY(D2R(r)).translate(0, 0.5, 0.0);
+ object.mvp = model * view * proj;
+ object.mv = model * view;
+ obj.load(&object, sizeof(object));
+ e->apply();
+ m->render();
- ubuf.load(&cb0, 32 * 4);
- ubuf.use(0);
+ model.identity().translate(-1.5, 0.5, 0.0);
+ object.mvp = model * view * proj;
+ object.mv = model * view;
+ obj.load(&object, sizeof(object));
+ e->apply();
+ m->render();
+ material.Specular.set(1,1,1,1);
+ mat.load(&material, sizeof(material));
+ model.identity().translate(1.50, 0.5, 0.0);
+ object.mvp = model * view * proj;
+ object.mv = model * view;
+ obj.load(&object, sizeof(object));
e->apply();
m->render();
}