graphics

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

commit f5d7f7b36c7347e764353b1b7dc1d7356eed4716
parent 144f64a31905cc8a536b0d244a8aeda1b8aae29a
Author: Brian Swetland <swetland@frotz.net>
Date:   Thu, 20 Jun 2013 20:16:56 -0700

improve shader management a bit

Allow multiple shaders to be combined in one file using a syntax similar
to Philip Rideout's GLSW (http://prideout.net/blog/?p=11)

Diffstat:
Dcommon/assets/TextPS.glsl | 9---------
Dcommon/assets/TextVS.glsl | 41-----------------------------------------
Acommon/assets/textgrid.glsl | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Acommon/buffers.cc | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcommon/glapp.cc | 239-------------------------------------------------------------------------------
Mcommon/module.mk | 2++
Acommon/shaders.cc | 288+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcommon/textgrid.cc | 4++--
Dhello/assets/SimplePS.glsl | 9---------
Dhello/assets/SimpleVS.glsl | 32--------------------------------
Ahello/assets/simple.glsl | 44++++++++++++++++++++++++++++++++++++++++++++
Mhello/hello.cc | 4++--
Dtest/assets/TestPS.glsl | 9---------
Dtest/assets/TestVS.glsl | 30------------------------------
Atest/assets/simple.glsl | 41+++++++++++++++++++++++++++++++++++++++++
Mtest/test.cc | 7++++---
16 files changed, 590 insertions(+), 376 deletions(-)

diff --git a/common/assets/TextPS.glsl b/common/assets/TextPS.glsl @@ -1,9 +0,0 @@ -#version 150 - -uniform sampler2D uTexture0; - -in vec2 vTEXCOORD; - -void main() { - gl_FragColor = texture2D(uTexture0, vTEXCOORD); -} diff --git a/common/assets/TextVS.glsl b/common/assets/TextVS.glsl @@ -1,41 +0,0 @@ -#version 150 -#extension GL_ARB_explicit_attrib_location : enable - -layout(std140) uniform cb0 { - mat4 MVP; - int cw; - int ch; -}; - -layout (location = 0) in vec4 POSITION; -layout (location = 1) in vec2 TEXCOORD; -layout (location = 2) in uint CHARACTER; - -out vec2 vTEXCOORD; - -void main() { - vec4 pos = POSITION; - int id = gl_InstanceID; - - // shift unit rectangle to character cell rectangle - pos.xy += vec2(id % cw, (ch-1) - id / ch); - - // adjust unit texture coord to font cell rectangle - float tx = (CHARACTER % uint(16)); - float ty = (CHARACTER / uint(16)); - - vTEXCOORD = - // scale to size of character in fonttexture - TEXCOORD * vec2(1.0/16.0,1.0/16.0) - // move to correct character - + vec2(tx/16.0,ty/16.0) - // offset to avoid cruft - + vec2(1.0/256.0,1.0/256.0); - - - pos = MVP * pos; - // discard via clipping - if (CHARACTER == uint(0)) pos.z = -1.1; - - gl_Position = pos; -} diff --git a/common/assets/textgrid.glsl b/common/assets/textgrid.glsl @@ -0,0 +1,53 @@ +#version 150 +#extension GL_ARB_explicit_attrib_location : enable + +-- vertex + +layout(std140) uniform cb0 { + mat4 MVP; + int cw; + int ch; +}; + +layout (location = 0) in vec4 POSITION; +layout (location = 1) in vec2 TEXCOORD; +layout (location = 2) in uint CHARACTER; + +out vec2 vTEXCOORD; + +void main() { + vec4 pos = POSITION; + int id = gl_InstanceID; + + // shift unit rectangle to character cell rectangle + pos.xy += vec2(id % cw, (ch-1) - id / ch); + + // adjust unit texture coord to font cell rectangle + float tx = (CHARACTER % uint(16)); + float ty = (CHARACTER / uint(16)); + + vTEXCOORD = + // scale to size of character in fonttexture + TEXCOORD * vec2(1.0/16.0,1.0/16.0) + // move to correct character + + vec2(tx/16.0,ty/16.0) + // offset to avoid cruft + + vec2(1.0/256.0,1.0/256.0); + + + pos = MVP * pos; + // discard via clipping + if (CHARACTER == uint(0)) pos.z = -1.1; + + gl_Position = pos; +} + +-- fragment + +uniform sampler2D uTexture0; + +in vec2 vTEXCOORD; + +void main() { + gl_FragColor = texture2D(uTexture0, vTEXCOORD); +} diff --git a/common/buffers.cc b/common/buffers.cc @@ -0,0 +1,154 @@ +/* Copyright 2013 Brian Swetland <swetland@frotz.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifdef _WIN32 +#define GLUE_DEFINE_EXTENSIONS 1 +#endif + +#include "app.h" +#include "util.h" + +#if 1 +#define CHECK() do {} while (0) +#else +const char *__gl_error_string(unsigned e) { + static char buf[16]; + switch (e) { + case GL_INVALID_ENUM: return "INVALID ENUM"; + case GL_INVALID_VALUE: return "INVALID VALUE"; + case GL_INVALID_OPERATION: return "INVALID OPERATION"; + case GL_INVALID_FRAMEBUFFER_OPERATION: return "INVALID FRAMEBUFFER OPERATION"; + case GL_OUT_OF_MEMORY: return "OUT OF MEMORY"; + default: + sprintf(buf,"0x%08x", e); + return buf; + } +} + +void __check_gl_error(const char *fn, int line) { + unsigned e; + while ((e = glGetError()) != GL_NO_ERROR) + printx("%s:%d: GL ERROR %s\n", fn, line, __gl_error_string(e)); +} +#define CHECK() __check_gl_error(__func__, __LINE__) +#endif + +static unsigned vattr_type(unsigned type) { + switch (type) { + case SRC_INT8: return GL_BYTE; + case SRC_UINT8: return GL_UNSIGNED_BYTE; + case SRC_INT16: return GL_SHORT; + case SRC_UINT16: return GL_UNSIGNED_SHORT; + case SRC_INT32: return GL_INT; + case SRC_UINT32: return GL_UNSIGNED_INT; + case SRC_FLOAT: return GL_FLOAT; + default: return GL_FLOAT; + } +} + +#define OFF2PTR(off) (((char*) NULL) + off) + +void VertexAttributes::init(VertexAttrDesc *desc, VertexBuffer **data, unsigned count) { + unsigned id = 0, n; + glGenVertexArrays(1, &vao); + CHECK(); + glBindVertexArray(vao); + CHECK(); + for (n = 0; n < count; n++) { + if (data && (data[n]->id != id)) { + id = data[n]->id; + glBindBuffer(GL_ARRAY_BUFFER, id); + CHECK(); + } + switch (desc->dst_type) { + case DST_FLOAT: + glVertexAttribPointer(desc->index, desc->count, + vattr_type(desc->src_type), GL_FALSE, desc->stride, + OFF2PTR(desc->offset)); + CHECK(); + break; + case DST_NORMALIZED: + glVertexAttribPointer(desc->index, desc->count, + vattr_type(desc->src_type), GL_TRUE, desc->stride, + OFF2PTR(desc->offset)); + CHECK(); + break; + case DST_INTEGER: + glVertexAttribIPointer(desc->index, desc->count, + vattr_type(desc->src_type), desc->stride, + OFF2PTR(desc->offset)); + CHECK(); + break; + } + glVertexAttribDivisor(desc->index, desc->divisor); + CHECK(); + glEnableVertexAttribArray(desc->index); + CHECK(); + desc++; + } +} + + +void VertexBuffer::load(void *data, unsigned size) { + if (id == 0) + glGenBuffers(1, &id); + glBindBuffer(GL_ARRAY_BUFFER, id); + glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); + sz = size; +} + +void IndexBuffer::load(void *data, unsigned size) { + if (id == 0) + glGenBuffers(1, &id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); + sz = size; +} + +void UniformBuffer::load(void *data, unsigned size) { + if (id == 0) + glGenBuffers(1, &id); + glBindBuffer(GL_UNIFORM_BUFFER, id); + glBufferData(GL_UNIFORM_BUFFER, size, data, GL_STATIC_DRAW); + sz = size; +} + +int Texture2D::load(const char *fn, int genmips) { + void *data; + unsigned dw, dh; + int r; + if (!(data = load_png_rgba(fn, &dw, &dh, 0))) + return error("cannot load '%s'", fn); + r = load(data, dw, dh, genmips); + free(data); + return r; +} + +int Texture2D::load(void *data, unsigned w, unsigned h, int genmips) { + if (id == 0) + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, data); + if (genmips) + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + return 0; +} + diff --git a/common/glapp.cc b/common/glapp.cc @@ -23,31 +23,6 @@ #include "app.h" #include "util.h" -#if 1 -#define CHECK() do {} while (0) -#else -const char *__gl_error_string(unsigned e) { - static char buf[16]; - switch (e) { - case GL_INVALID_ENUM: return "INVALID ENUM"; - case GL_INVALID_VALUE: return "INVALID VALUE"; - case GL_INVALID_OPERATION: return "INVALID OPERATION"; - case GL_INVALID_FRAMEBUFFER_OPERATION: return "INVALID FRAMEBUFFER OPERATION"; - case GL_OUT_OF_MEMORY: return "OUT OF MEMORY"; - default: - sprintf(buf,"0x%08x", e); - return buf; - } -} - -void __check_gl_error(const char *fn, int line) { - unsigned e; - while ((e = glGetError()) != GL_NO_ERROR) - printx("%s:%d: GL ERROR %s\n", fn, line, __gl_error_string(e)); -} -#define CHECK() __check_gl_error(__func__, __LINE__) -#endif - #ifdef _WIN32 static void gl_map_functions(void) { int n; @@ -190,217 +165,3 @@ int main(int argc, char **argv) { return 0; } -static unsigned vattr_type(unsigned type) { - switch (type) { - case SRC_INT8: return GL_BYTE; - case SRC_UINT8: return GL_UNSIGNED_BYTE; - case SRC_INT16: return GL_SHORT; - case SRC_UINT16: return GL_UNSIGNED_SHORT; - case SRC_INT32: return GL_INT; - case SRC_UINT32: return GL_UNSIGNED_INT; - case SRC_FLOAT: return GL_FLOAT; - default: return GL_FLOAT; - } -} - -#define OFF2PTR(off) (((char*) NULL) + off) - -void VertexAttributes::init(VertexAttrDesc *desc, VertexBuffer **data, unsigned count) { - unsigned id = 0, n; - glGenVertexArrays(1, &vao); - CHECK(); - glBindVertexArray(vao); - CHECK(); - for (n = 0; n < count; n++) { - if (data && (data[n]->id != id)) { - id = data[n]->id; - glBindBuffer(GL_ARRAY_BUFFER, id); - CHECK(); - } - switch (desc->dst_type) { - case DST_FLOAT: - glVertexAttribPointer(desc->index, desc->count, - vattr_type(desc->src_type), GL_FALSE, desc->stride, - OFF2PTR(desc->offset)); - CHECK(); - break; - case DST_NORMALIZED: - glVertexAttribPointer(desc->index, desc->count, - vattr_type(desc->src_type), GL_TRUE, desc->stride, - OFF2PTR(desc->offset)); - CHECK(); - break; - case DST_INTEGER: - glVertexAttribIPointer(desc->index, desc->count, - vattr_type(desc->src_type), desc->stride, - OFF2PTR(desc->offset)); - CHECK(); - break; - } - glVertexAttribDivisor(desc->index, desc->divisor); - CHECK(); - glEnableVertexAttribArray(desc->index); - CHECK(); - desc++; - } -} - - -void VertexBuffer::load(void *data, unsigned size) { - if (id == 0) - glGenBuffers(1, &id); - glBindBuffer(GL_ARRAY_BUFFER, id); - glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); - sz = size; -} - -void IndexBuffer::load(void *data, unsigned size) { - if (id == 0) - glGenBuffers(1, &id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); - sz = size; -} - -void UniformBuffer::load(void *data, unsigned size) { - if (id == 0) - glGenBuffers(1, &id); - glBindBuffer(GL_UNIFORM_BUFFER, id); - glBufferData(GL_UNIFORM_BUFFER, size, data, GL_STATIC_DRAW); - sz = size; -} - -static void dump_compile_error(unsigned id) { - int len; - char *buf; - glGetShaderiv(id, GL_INFO_LOG_LENGTH, &len); - buf = (char*) malloc(len + 1); - if (buf != 0) { - memset(buf, 0, len); - glGetShaderInfoLog(id, len, &len, buf); - buf[len] = 0; - fprintf(stderr,"-- shader compiler error --\n%s\n", buf); - free(buf); - } -} - -static void dump_link_error(unsigned id) { - int len; - char *buf; - glGetProgramiv(id, GL_INFO_LOG_LENGTH, &len); - buf = (char*) malloc(len + 1); - if (buf != 0) { - memset(buf, 0, len); - glGetProgramInfoLog(id, len, &len, buf); - buf[len] = 0; - fprintf(stderr,"-- shader link error --\n%s\n", buf); - free(buf); - } -} - -int Program::link(VertexShader *vs, PixelShader *ps) { - return link(vs, NULL, ps); -} - -int Program::link(VertexShader *vs, GeometryShader *gs, PixelShader *ps) { - unsigned n; - int r; - n = glCreateProgram(); - glAttachShader(n, vs->id); - if (gs) - glAttachShader(n, gs->id); - glAttachShader(n, ps->id); - glLinkProgram(n); - glGetProgramiv(n, GL_LINK_STATUS, &r); - if (!r) { - dump_link_error(n); - glDeleteProgram(n); - return error("shader program link error"); - } - if (id) - glDeleteProgram(id); - id = n; - return 0; -} - -int Program::load(const char *vsfn, const char *gsfn, const char *psfn) { - VertexShader vs; - GeometryShader gs; - PixelShader ps; - if (vs.load(vsfn)) - return -1; - if (gs.load(gsfn)) - return -1; - if (ps.load(psfn)) - return -1; - return link(&vs, &gs, &ps); -} - -int Program::load(const char *vsfn, const char *psfn) { - VertexShader vs; - PixelShader ps; - if (vs.load(vsfn)) - return -1; - if (ps.load(psfn)) - return -1; - return link(&vs, &ps); -} - -static int _load_shader(unsigned *out, const char *fn, unsigned type) { - void *data; - unsigned sz; - unsigned id; - int r; - if (!(data = load_file(fn, &sz))) - return error("cannot load shader source '%s'", fn); - id = glCreateShader(type); - glShaderSource(id, 1, (const char **) &data, NULL); - glCompileShader(id); - glGetShaderiv(id, GL_COMPILE_STATUS, &r); - if (!r) { - dump_compile_error(id); - glDeleteShader(id); - return error("shader '%s' compile error", fn); - } - if (*out) - glDeleteShader(*out); - *out = id; - return 0; -} - -int VertexShader::load(const char *fn) { - return _load_shader(&id, fn, GL_VERTEX_SHADER); -} - -int PixelShader::load(const char *fn) { - return _load_shader(&id, fn, GL_FRAGMENT_SHADER); -} - -int GeometryShader::load(const char *fn) { - return _load_shader(&id, fn, GL_GEOMETRY_SHADER); -} - -int Texture2D::load(const char *fn, int genmips) { - void *data; - unsigned dw, dh; - int r; - if (!(data = load_png_rgba(fn, &dw, &dh, 0))) - return error("cannot load '%s'", fn); - r = load(data, dw, dh, genmips); - free(data); - return r; -} - -int Texture2D::load(void *data, unsigned w, unsigned h, int genmips) { - if (id == 0) - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, - GL_RGBA, GL_UNSIGNED_BYTE, data); - if (genmips) - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - return 0; -} - diff --git a/common/module.mk b/common/module.mk @@ -1,6 +1,8 @@ M_NAME := common M_OBJS := glapp.o +M_OBJS += shaders.o +M_OBJS += buffers.o M_OBJS += io.o M_OBJS += loadfile.o M_OBJS += loadpng.o diff --git a/common/shaders.cc b/common/shaders.cc @@ -0,0 +1,288 @@ +/* Copyright 2013 Brian Swetland <swetland@frotz.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifdef _WIN32 +#define GLUE_DEFINE_EXTENSIONS 1 +#endif + +#include "app.h" +#include "util.h" + +static void dump_compile_error(unsigned id) { + int len; + char *buf; + glGetShaderiv(id, GL_INFO_LOG_LENGTH, &len); + buf = (char*) malloc(len + 1); + if (buf != 0) { + memset(buf, 0, len); + glGetShaderInfoLog(id, len, &len, buf); + buf[len] = 0; + fprintf(stderr,"-- shader compiler error --\n%s\n", buf); + free(buf); + } +} + +static void dump_link_error(unsigned id) { + int len; + char *buf; + glGetProgramiv(id, GL_INFO_LOG_LENGTH, &len); + buf = (char*) malloc(len + 1); + if (buf != 0) { + memset(buf, 0, len); + glGetProgramInfoLog(id, len, &len, buf); + buf[len] = 0; + fprintf(stderr,"-- shader link error --\n%s\n", buf); + free(buf); + } +} + +int Program::link(VertexShader *vs, PixelShader *ps) { + return link(vs, NULL, ps); +} + +int Program::link(VertexShader *vs, GeometryShader *gs, PixelShader *ps) { + unsigned n; + int r; + n = glCreateProgram(); + glAttachShader(n, vs->id); + if (gs) + glAttachShader(n, gs->id); + glAttachShader(n, ps->id); + glLinkProgram(n); + glGetProgramiv(n, GL_LINK_STATUS, &r); + if (!r) { + dump_link_error(n); + glDeleteProgram(n); + return error("shader program link error"); + } + if (id) + glDeleteProgram(id); + id = n; + return 0; +} + +int Program::load(const char *vsfn, const char *gsfn, const char *psfn) { + VertexShader vs; + GeometryShader gs; + PixelShader ps; + if (vs.load(vsfn)) + return -1; + if (gs.load(gsfn)) + return -1; + if (ps.load(psfn)) + return -1; + return link(&vs, &gs, &ps); +} + +int Program::load(const char *vsfn, const char *psfn) { + VertexShader vs; + PixelShader ps; + if (vs.load(vsfn)) + return -1; + if (ps.load(psfn)) + return -1; + return link(&vs, &ps); +} + +struct section { + section *next; + unsigned lineno; + const char *name; + const char *str; + unsigned len; +}; + +struct source { + source *next; + const char *name; + section *sections; + section common; + const char *str; + unsigned len; +}; + +static source *source_cache = NULL; + +static struct source *load_shader_source(const char *fn) { + source *src; + section *part; + unsigned lineno = 1; + unsigned len; + char *x, *end, *tmp; + char buf[1024]; + + x = (char*) strchr(fn, '.'); + if (x) { + memcpy(buf, fn, x-fn); + strcpy(buf + (x - fn), ".glsl"); + } else { + sprintf(buf, "%s.glsl", fn); + } + + for (src = source_cache; src; src = src->next) + if (!strcmp(buf, src->name)) + return src; + + src = new source; + src->sections = NULL; + part = &src->common; + part->name = "$common$"; + + x = (char*) load_file(buf, &len); + if (!x) { + delete src; + return NULL; + } + src->str = x; + src->len = len; + + part->str = x; + part->lineno = lineno; + + end = x + len; + while (x < end) { + if (*x++ != '\n') + continue; + lineno++; + if ((end - x) < 3) + continue; + if ((x[0] != '-') || (x[1] != '-')) + continue; + part->len = x - part->str; + part->next = src->sections; + src->sections = part; + *x = 0; + x += 2; + + part = new section; + part->next = NULL; + part->name = ""; + + tmp = x; + while (x < end) { + if (*x == '\n') { + *x = 0; + while ((tmp < x) && (*tmp <= ' ')) + tmp++; + part->name = tmp; + while (tmp < x) { + if (*tmp <= ' ') + *tmp = 0; + tmp++; + } + x++; + break; + } + x++; + } + + lineno++; + part->str = x; + part->lineno = lineno; + } + + part->len = x - part->str; + part->next = src->sections; + src->sections = part; + +#if 0 + printx("[ source '%s' %d lines ]\n", buf, lineno); + for (part = src->sections; part; part = part->next) + printx(" [ section '%s' %d bytes @ %d]\n", + part->name, part->len, part->lineno); +#endif + + src->name = strdup(buf); + src->next = source_cache; + source_cache = src; + return src; +} + +static int compile_shader_source(source *src, const char *name, unsigned id) { + char misc[128]; + const char *data[3]; + int size[3]; + section *part; + + for (part = src->sections; part; part = part->next) { + if (!strcmp(name, part->name)) { + printx("Loaded shader section '%s' from '%s'\n", + part->name, src->name); + sprintf(misc, "#line %d\n", part->lineno - 1); + data[0] = src->common.str; + size[0] = src->common.len; + data[1] = misc; + size[1] = strlen(misc); + data[2] = part->str; + size[2] = part->len; +#if 0 + printf("----------------\n%s%s%s\n-------------\n", + data[0], data[1], data[2]); +#endif + glShaderSource(id, 3, data, size); + return 0; + } + } + return error("cannot find section '%s'", name); +} + +static int _load_shader(unsigned *out, const char *fn, unsigned type) { + unsigned id; + source *src; + const char *x; + int r; + + x = strchr(fn, '.'); + if (x == 0) + return error("shader source '%s' has no section", fn); + x++; + + src = load_shader_source(fn); + if (src == NULL) + return error("cannot load shader source '%s'", fn); + + id = glCreateShader(type); + if (compile_shader_source(src, x, id)) { + glDeleteShader(id); + return -1; + } + glCompileShader(id); + glGetShaderiv(id, GL_COMPILE_STATUS, &r); + if (!r) { + dump_compile_error(id); + glDeleteShader(id); + return error("shader '%s' compile error", fn); + } + if (*out) + glDeleteShader(*out); + *out = id; + return 0; +} + +int VertexShader::load(const char *fn) { + return _load_shader(&id, fn, GL_VERTEX_SHADER); +} + +int PixelShader::load(const char *fn) { + return _load_shader(&id, fn, GL_FRAGMENT_SHADER); +} + +int GeometryShader::load(const char *fn) { + return _load_shader(&id, fn, GL_GEOMETRY_SHADER); +} + diff --git a/common/textgrid.cc b/common/textgrid.cc @@ -76,9 +76,9 @@ int TextGrid::init(App *a, int w, int h) { if (texture.load("font-vincent-8x8.png", 0)) return -1; - if (ps.load("TextPS.glsl")) + if (ps.load("textgrid.fragment")) return -1; - if (vs.load("TextVS.glsl")) + if (vs.load("textgrid.vertex")) return -1; if (pgm.link(&vs, &ps)) return -1; diff --git a/hello/assets/SimplePS.glsl b/hello/assets/SimplePS.glsl @@ -1,9 +0,0 @@ -#version 150 - -varying vec2 vTEXCOORD; -varying float vDIFFUSE; - -void main() { - vec4 c = vec4(1.0, 0.0, 0.0, 1.0); - gl_FragColor = c * 0.25 + c * vDIFFUSE; -} diff --git a/hello/assets/SimpleVS.glsl b/hello/assets/SimpleVS.glsl @@ -1,32 +0,0 @@ -#version 150 -#extension GL_ARB_explicit_attrib_location : enable - -layout(std140) uniform cb0 { - mat4 MVP; - mat4 MV; -}; - -layout(location = 0) in vec4 POSITION; -layout(location = 1) in vec4 NORMAL; -layout(location = 2) in vec2 TEXCOORD; - -in vec4 LOCATION; - -out vec2 vTEXCOORD; -out float vDIFFUSE; - -void main() { - vec4 pos = POSITION; - - pos.xyz += LOCATION.xyz * vec3(127,127,127); - - 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 * pos; //POSITION; - vTEXCOORD = TEXCOORD; - vDIFFUSE = diffuse; -} diff --git a/hello/assets/simple.glsl b/hello/assets/simple.glsl @@ -0,0 +1,44 @@ +#version 150 +#extension GL_ARB_explicit_attrib_location : enable + +-- vertex + +layout(std140) uniform cb0 { + mat4 MVP; + mat4 MV; +}; + +layout(location = 0) in vec4 POSITION; +layout(location = 1) in vec4 NORMAL; +layout(location = 2) in vec2 TEXCOORD; + +in vec4 LOCATION; + +out vec2 vTEXCOORD; +out float vDIFFUSE; + +void main() { + vec4 pos = POSITION; + + pos.xyz += LOCATION.xyz * vec3(127,127,127); + + 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 * pos; //POSITION; + vTEXCOORD = TEXCOORD; + vDIFFUSE = diffuse; +} + +-- fragment + +varying vec2 vTEXCOORD; +varying float vDIFFUSE; + +void main() { + vec4 c = vec4(1.0, 0.0, 0.0, 1.0); + gl_FragColor = c * 0.25 + c * vDIFFUSE; +} diff --git a/hello/hello.cc b/hello/hello.cc @@ -119,9 +119,9 @@ int TestApp::init(void) { VertexBuffer *data[] = { &vbuf, &vbuf, &vbuf, &lbuf, }; - if (ps.load("SimplePS.glsl")) + if (ps.load("simple.fragment")) return -1; - if (vs.load("SimpleVS.glsl")) + if (vs.load("simple.vertex")) return -1; if (pgm.link(&vs, &ps)) return -1; diff --git a/test/assets/TestPS.glsl b/test/assets/TestPS.glsl @@ -1,9 +0,0 @@ -#version 150 - -in vec2 vTEXCOORD; -in float vDIFFUSE; - -void main() { - vec4 c = vec4(1.0, 0.0, 0.0, 1.0); - gl_FragColor = c * 0.25 + c * vDIFFUSE; -} diff --git a/test/assets/TestVS.glsl b/test/assets/TestVS.glsl @@ -1,30 +0,0 @@ -#version 150 -#extension GL_ARB_explicit_attrib_location : enable - -//uniform mat4 MVP0; - -layout(std140) uniform cb0 { - mat4 MVP; - mat4 MV; -}; - -layout (location = 0) in vec4 POSITION; -layout (location = 1) in vec4 NORMAL; -layout (location = 2) in vec2 TEXCOORD; - -out vec2 vTEXCOORD; -out float vDIFFUSE; - -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; -} diff --git a/test/assets/simple.glsl b/test/assets/simple.glsl @@ -0,0 +1,41 @@ +#version 150 +#extension GL_ARB_explicit_attrib_location : enable + +-- vertex + +layout(std140) uniform cb0 { + mat4 MVP; + mat4 MV; +}; + +layout (location = 0) in vec4 POSITION; +layout (location = 1) in vec4 NORMAL; +layout (location = 2) in vec2 TEXCOORD; + +out vec2 vTEXCOORD; +out float vDIFFUSE; + +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; +} + +-- fragment + +in vec2 vTEXCOORD; +in float vDIFFUSE; + +void main() { + vec4 c = vec4(1.0, 0.0, 0.0, 1.0); + gl_FragColor = c * 0.25 + c * vDIFFUSE; +} + diff --git a/test/test.cc b/test/test.cc @@ -54,8 +54,8 @@ private: int vs_mtime; }; -static const char *psfn = "TestPS.glsl"; -static const char *vsfn = "TestVS.glsl"; +static const char *psfn = "simple.fragment"; +static const char *vsfn = "simple.vertex"; TestApp::TestApp() : App(), r(0.0) { } @@ -96,6 +96,7 @@ void TestApp::render(void) { unsigned stride, offset; int t; +#if 0 t = file_get_mtime(psfn); if (t != ps_mtime) { printx("ps change!\n"); @@ -110,7 +111,7 @@ void TestApp::render(void) { vs_mtime = t; pgm.link(&vs, &ps); } - +#endif struct { mat4 mvp; mat4 mv;