graphics

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
Mcommon/assets/textgrid.glsl | 2+-
Mcommon/shaders.cc | 1+
Mcommon/shared.h | 39+++++++++++++++++++++++++++++++++++++++
Mcommon/textgrid.cc | 2+-
Mhello/assets/simple.glsl | 2+-
Mhello/hello.cc | 2+-
Atest/assets/flat.glsl | 16++++++++++++++++
Mtest/assets/simple.glsl | 63+++++++++++++++++++++++++++++++++++----------------------------
Mtest/object.cc | 126++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
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(); }