mirror of https://github.com/bjornbytes/lovr.git
Fix Shader bugs;
This commit is contained in:
parent
9dd9678077
commit
6c316c7587
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue