Fix Shader bugs;

This commit is contained in:
bjorn 2017-08-09 00:56:13 -07:00
parent 9dd9678077
commit 6c316c7587
6 changed files with 71 additions and 69 deletions

View File

@ -673,7 +673,7 @@ int l_lovrGraphicsNewShader(lua_State* L) {
const char* vertexSource = lua_tostring(L, 1);
const char* fragmentSource = lua_tostring(L, 2);
Shader* shader = lovrShaderCreate(vertexSource, fragmentSource, 0);
Shader* shader = lovrShaderCreate(vertexSource, fragmentSource);
luax_pushtype(L, Shader, shader);
lovrRelease(&shader->ref);
return 1;

View File

@ -122,9 +122,16 @@ void lovrGraphicsPresent() {
}
void lovrGraphicsPrepare() {
Shader* shader = lovrGraphicsGetActiveShader();
if (!shader) {
shader = state.defaultShaders[state.defaultShader] = lovrShaderCreateDefault(state.defaultShader);
}
mat4 transform = state.transforms[state.transform];
mat4 projection = state.canvases[state.canvas].projection;
lovrShaderBind(state.shader, transform, projection, state.color, 0);
lovrGraphicsBindProgram(shader->id);
lovrShaderBind(shader, transform, projection, state.color, 0);
}
// State
@ -310,10 +317,7 @@ void lovrGraphicsSetShader(Shader* shader) {
state.shader = shader;
if (shader) {
glUseProgram(shader->id);
lovrRetain(&state.shader->ref);
} else {
glUseProgram(0);
}
}
}
@ -470,7 +474,6 @@ void lovrGraphicsTriangle(DrawMode mode, float* points) {
}
void lovrGraphicsPlane(DrawMode mode, Texture* texture, mat4 transform) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsPush();
lovrGraphicsMatrixTransform(transform);
@ -483,6 +486,7 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, mat4 transform) {
};
lovrGraphicsBindTexture(NULL);
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetShapeData(points, 12);
lovrGraphicsDrawPrimitive(GL_LINE_LOOP, 0, 0, 0);
} else if (mode == DRAW_MODE_FILL) {
@ -494,6 +498,7 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, mat4 transform) {
};
lovrGraphicsBindTexture(texture);
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetShapeData(data, 32);
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, 1, 1, 0);
}
@ -542,6 +547,7 @@ void lovrGraphicsBox(DrawMode mode, Texture* texture, mat4 transform) {
};
lovrGraphicsBindTexture(NULL);
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetShapeData(points, 24);
lovrGraphicsSetIndexData(indices, 24);
lovrGraphicsDrawPrimitive(GL_LINES, 0, 0, 1);
@ -589,6 +595,7 @@ void lovrGraphicsBox(DrawMode mode, Texture* texture, mat4 transform) {
};
lovrGraphicsBindTexture(texture);
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetShapeData(data, 208);
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, 1, 1, 0);
}
@ -597,7 +604,6 @@ void lovrGraphicsBox(DrawMode mode, Texture* texture, mat4 transform) {
}
void lovrGraphicsCylinder(float x1, float y1, float z1, float x2, float y2, float z2, float r1, float r2, int capped, int segments) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
float axis[3] = { x1 - x2, y1 - y2, z1 - z2 };
float n[3] = { x1 - x2, y1 - y2, z1 - z2 };
float p[3];
@ -697,13 +703,13 @@ void lovrGraphicsCylinder(float x1, float y1, float z1, float x2, float y2, floa
}
lovrGraphicsBindTexture(NULL);
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsDrawPrimitive(GL_TRIANGLES, 1, 0, 1);
#undef PUSH_CYLINDER_VERTEX
#undef PUSH_CYLINDER_TRIANGLE
}
void lovrGraphicsSphere(Texture* texture, mat4 transform, int segments, Skybox* skybox) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
vec_clear(&state.streamData);
vec_clear(&state.streamIndices);
@ -746,6 +752,8 @@ void lovrGraphicsSphere(Texture* texture, mat4 transform, int segments, Skybox*
}
}
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
if (skybox) {
Texture* oldTexture = lovrGraphicsGetTexture();
glBindTexture(GL_TEXTURE_2D, skybox->texture);
@ -885,26 +893,6 @@ void lovrGraphicsBindFramebuffer(int framebuffer) {
}
}
void lovrGraphicsSetDefaultShader(DefaultShader defaultShader) {
if (state.defaultShader == defaultShader || (state.shader && !state.shader->isDefault)) {
return;
}
if (!state.defaultShaders[defaultShader]) {
Shader* shader;
switch (defaultShader) {
case SHADER_DEFAULT: shader = lovrShaderCreate(lovrDefaultVertexShader, lovrDefaultFragmentShader, 1); break;
case SHADER_SKYBOX: shader = lovrShaderCreate(lovrSkyboxVertexShader, lovrSkyboxFragmentShader, 1); break;
case SHADER_FONT: shader = lovrShaderCreate(lovrDefaultVertexShader, lovrFontFragmentShader, 1); break;
case SHADER_FULLSCREEN: shader = lovrShaderCreate(lovrNoopVertexShader, lovrDefaultFragmentShader, 1); break;
}
state.defaultShaders[defaultShader] = shader;
}
state.defaultShader = defaultShader;
lovrGraphicsSetShader(state.defaultShaders[defaultShader]);
}
Texture* lovrGraphicsGetTexture() {
return state.texture;
}
@ -924,6 +912,21 @@ void lovrGraphicsBindTexture(Texture* texture) {
}
}
void lovrGraphicsSetDefaultShader(DefaultShader shader) {
state.defaultShader = shader;
}
Shader* lovrGraphicsGetActiveShader() {
return state.shader ? state.shader : state.defaultShaders[state.defaultShader];
}
void lovrGraphicsBindProgram(uint32_t program) {
if (state.program != program) {
state.program = program;
glUseProgram(program);
}
}
void lovrGraphicsBindVertexArray(uint32_t vertexArray) {
if (state.vertexArray != vertexArray) {
state.vertexArray = vertexArray;

View File

@ -62,16 +62,10 @@ typedef struct {
int viewport[4];
} CanvasState;
typedef enum {
SHADER_DEFAULT,
SHADER_SKYBOX,
SHADER_FONT,
SHADER_FULLSCREEN
} DefaultShader;
typedef struct {
GLFWwindow* window;
Shader* defaultShaders[DEFAULT_SHADER_COUNT];
DefaultShader defaultShader;
Font* defaultFont;
Texture* defaultTexture;
float transforms[MAX_TRANSFORMS + INTERNAL_TRANSFORMS][16];
@ -97,8 +91,8 @@ typedef struct {
vec_uint_t streamIndices;
CanvasState canvases[MAX_CANVASES];
int canvas;
DefaultShader defaultShader;
Texture* texture;
uint32_t program;
uint32_t vertexArray;
uint32_t vertexBuffer;
uint32_t indexBuffer;
@ -171,7 +165,9 @@ void lovrGraphicsSetViewport(int x, int y, int w, int h);
void lovrGraphicsBindFramebuffer(int framebuffer);
Texture* lovrGraphicsGetTexture();
void lovrGraphicsBindTexture(Texture* texture);
void lovrGraphicsSetDefaultShader(DefaultShader defaultShader);
Shader* lovrGraphicsGetActiveShader();
void lovrGraphicsBindProgram(uint32_t program);
void lovrGraphicsBindVertexArray(uint32_t vao);
void lovrGraphicsBindVertexBuffer(uint32_t vbo);
void lovrGraphicsBindIndexBuffer(uint32_t ibo);
void lovrGraphicsSetDefaultShader(DefaultShader defaultShader);

View File

@ -4,8 +4,8 @@
#include <stdio.h>
static void lovrMeshBindAttributes(Mesh* mesh) {
Shader* shader = lovrGraphicsGetShader();
if (!shader || (shader == mesh->lastShader && !mesh->attributesDirty)) {
Shader* shader = lovrGraphicsGetActiveShader();
if (shader == mesh->lastShader && !mesh->attributesDirty) {
return;
}

View File

@ -4,7 +4,7 @@
#include <stdio.h>
#include <stdlib.h>
const char* lovrShaderVertexPrefix = ""
static const char* lovrShaderVertexPrefix = ""
#ifdef EMSCRIPTEN
"#version 300 es \n"
"precision mediump float; \n"
@ -19,7 +19,7 @@ const char* lovrShaderVertexPrefix = ""
"uniform mat3 lovrNormalMatrix; \n"
"uniform mat4 lovrProjection; \n";
const char* lovrShaderFragmentPrefix = ""
static const char* lovrShaderFragmentPrefix = ""
#ifdef EMSCRIPTEN
"#version 300 es \n"
"precision mediump float; \n"
@ -32,42 +32,42 @@ const char* lovrShaderFragmentPrefix = ""
"uniform vec4 lovrColor; \n"
"uniform sampler2D lovrTexture; \n";
const char* lovrShaderVertexSuffix = ""
static const char* lovrShaderVertexSuffix = ""
"void main() { \n"
" texCoord = lovrTexCoord; \n"
" gl_Position = position(lovrProjection, lovrTransform, vec4(lovrPosition, 1.0)); \n"
"}";
const char* lovrShaderFragmentSuffix = ""
static const char* lovrShaderFragmentSuffix = ""
"void main() { \n"
" lovrFragColor = color(lovrColor, lovrTexture, texCoord); \n"
"}";
const char* lovrDefaultVertexShader = ""
static const char* lovrDefaultVertexShader = ""
"vec4 position(mat4 projection, mat4 transform, vec4 vertex) { \n"
" return projection * transform * vertex; \n"
"}";
const char* lovrDefaultFragmentShader = ""
static const char* lovrDefaultFragmentShader = ""
"vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { \n"
" return graphicsColor * texture(image, uv); \n"
"}";
const char* lovrSkyboxVertexShader = ""
static const char* lovrSkyboxVertexShader = ""
"out vec3 texturePosition; \n"
"vec4 position(mat4 projection, mat4 transform, vec4 vertex) { \n"
" texturePosition = vertex.xyz; \n"
" return projection * transform * vertex; \n"
"}";
const char* lovrSkyboxFragmentShader = ""
static const char* lovrSkyboxFragmentShader = ""
"in vec3 texturePosition; \n"
"uniform samplerCube cube = 1; \n"
"vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { \n"
" return graphicsColor * texture(cube, texturePosition); \n"
"}";
const char* lovrFontFragmentShader = ""
static const char* lovrFontFragmentShader = ""
"float median(float r, float g, float b) { \n"
" return max(min(r, g), min(max(r, g), b)); \n"
"} \n"
@ -79,12 +79,12 @@ const char* lovrFontFragmentShader = ""
" return vec4(graphicsColor.rgb, graphicsColor.a * alpha); \n"
"}";
const char* lovrNoopVertexShader = ""
static const char* lovrNoopVertexShader = ""
"vec4 position(mat4 projection, mat4 transform, vec4 vertex) { \n"
" return vertex; \n"
"}";
GLuint compileShader(GLenum type, const char* source) {
static GLuint compileShader(GLenum type, const char* source) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, (const GLchar**)&source, NULL);
@ -104,7 +104,7 @@ GLuint compileShader(GLenum type, const char* source) {
return shader;
}
GLuint linkShaders(GLuint vertexShader, GLuint fragmentShader) {
static GLuint linkShaders(GLuint vertexShader, GLuint fragmentShader) {
GLuint shader = glCreateProgram();
if (vertexShader) {
@ -140,7 +140,7 @@ GLuint linkShaders(GLuint vertexShader, GLuint fragmentShader) {
return shader;
}
Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource, int isDefault) {
Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) {
Shader* shader = lovrAlloc(sizeof(Shader), lovrShaderDestroy);
if (!shader) return NULL;
@ -181,15 +181,24 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource, i
mat4_identity(shader->transform);
mat4_identity(shader->projection);
shader->color = (Color) { 0, 0, 0, 0 };
shader->isDefault = isDefault;
// Send initial uniform values to shader
lovrGraphicsSetShader(shader);
lovrGraphicsBindProgram(id);
lovrShaderBind(shader, shader->transform, shader->projection, shader->color, 1);
return shader;
}
Shader* lovrShaderCreateDefault(DefaultShader type) {
switch (type) {
case SHADER_DEFAULT: return lovrShaderCreate(NULL, NULL);
case SHADER_SKYBOX: return lovrShaderCreate(lovrSkyboxVertexShader, lovrSkyboxFragmentShader);
case SHADER_FONT: return lovrShaderCreate(NULL, lovrFontFragmentShader);
case SHADER_FULLSCREEN: return lovrShaderCreate(lovrNoopVertexShader, NULL);
default: error("Unknown default shader type");
}
}
void lovrShaderDestroy(const Ref* ref) {
Shader* shader = containerof(ref, Shader);
glDeleteProgram(shader->id);

View File

@ -8,9 +8,15 @@
#define LOVR_SHADER_POSITION 0
#define LOVR_SHADER_NORMAL 1
#define LOVR_SHADER_TEX_COORD 2
#define LOVR_MAX_UNIFORM_LENGTH 256
typedef enum {
SHADER_DEFAULT,
SHADER_SKYBOX,
SHADER_FONT,
SHADER_FULLSCREEN
} DefaultShader;
typedef struct {
GLchar name[LOVR_MAX_UNIFORM_LENGTH];
int index;
@ -28,22 +34,10 @@ typedef struct {
float transform[16];
float projection[16];
Color color;
int isDefault;
} Shader;
extern const char* lovrShaderVertexPrefix;
extern const char* lovrShaderFragmentPrefix;
extern const char* lovrDefaultVertexShader;
extern const char* lovrDefaultFragmentShader;
extern const char* lovrSkyboxVertexShader;
extern const char* lovrSkyboxFragmentShader;
extern const char* lovrFontFragmentShader;
extern const char* lovrNoopVertexShader;
GLuint compileShader(GLuint type, const char* source);
GLuint linkShaders(GLuint vertexShader, GLuint fragmentShader);
Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource, int isDefault);
Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource);
Shader* lovrShaderCreateDefault(DefaultShader type);
void lovrShaderDestroy(const Ref* ref);
void lovrShaderBind(Shader* shader, mat4 transform, mat4 projection, Color color, int force);
int lovrShaderGetAttributeId(Shader* shader, const char* name);