CanvasState;

This commit is contained in:
bjorn 2017-01-11 09:22:18 -08:00
parent 1ad0ac557b
commit b05e2630dd
6 changed files with 89 additions and 48 deletions

View File

@ -17,7 +17,9 @@ void lovrGraphicsInit() {
for (int i = 0; i < MAX_TRANSFORMS; i++) { for (int i = 0; i < MAX_TRANSFORMS; i++) {
state.transforms[i] = mat4_init(); state.transforms[i] = mat4_init();
} }
state.projection = mat4_init(); state.canvases[0].framebuffer = 0;
glGetIntegerv(GL_VIEWPORT, state.canvases[0].viewport);
state.canvases[0].isSystem = 1;
state.defaultShader = lovrShaderCreate(lovrDefaultVertexShader, lovrDefaultFragmentShader); state.defaultShader = lovrShaderCreate(lovrDefaultVertexShader, lovrDefaultFragmentShader);
state.skyboxShader = lovrShaderCreate(lovrSkyboxVertexShader, lovrSkyboxFragmentShader); state.skyboxShader = lovrShaderCreate(lovrSkyboxVertexShader, lovrSkyboxFragmentShader);
int uniformId = lovrShaderGetUniformId(state.skyboxShader, "cube"); int uniformId = lovrShaderGetUniformId(state.skyboxShader, "cube");
@ -38,7 +40,6 @@ void lovrGraphicsDestroy() {
for (int i = 0; i < MAX_TRANSFORMS; i++) { for (int i = 0; i < MAX_TRANSFORMS; i++) {
mat4_deinit(state.transforms[i]); mat4_deinit(state.transforms[i]);
} }
mat4_deinit(state.projection);
lovrRelease(&state.defaultShader->ref); lovrRelease(&state.defaultShader->ref);
lovrRelease(&state.skyboxShader->ref); lovrRelease(&state.skyboxShader->ref);
lovrRelease(&state.defaultTexture->ref); lovrRelease(&state.defaultTexture->ref);
@ -51,6 +52,7 @@ void lovrGraphicsDestroy() {
void lovrGraphicsReset() { void lovrGraphicsReset() {
state.transform = 0; state.transform = 0;
state.canvas = 0;
lovrGraphicsSetProjection(.1f, 100.f, 67 * M_PI / 180); // TODO customize via lovr.conf lovrGraphicsSetProjection(.1f, 100.f, 67 * M_PI / 180); // TODO customize via lovr.conf
lovrGraphicsSetShader(NULL); lovrGraphicsSetShader(NULL);
lovrGraphicsBindTexture(NULL); lovrGraphicsBindTexture(NULL);
@ -86,7 +88,9 @@ void lovrGraphicsPresent() {
void lovrGraphicsPrepare() { void lovrGraphicsPrepare() {
Shader* shader = lovrGraphicsGetShader(); Shader* shader = lovrGraphicsGetShader();
lovrShaderBind(shader, state.transforms[state.transform], state.projection, state.color, 0); mat4 transform = state.transforms[state.transform];
mat4 projection = state.canvases[state.canvas].projection;
lovrShaderBind(shader, transform, projection, state.color, 0);
} }
// State // State
@ -188,11 +192,7 @@ void lovrGraphicsBindTexture(Texture* texture) {
void lovrGraphicsSetProjection(float near, float far, float fov) { void lovrGraphicsSetProjection(float near, float far, float fov) {
int width, height; int width, height;
glfwGetWindowSize(window, &width, &height); glfwGetWindowSize(window, &width, &height);
mat4_setProjection(state.projection, near, far, fov, (float) width / height); mat4_setProjection(state.canvases[state.canvas].projection, near, far, fov, (float) width / height);
}
void lovrGraphicsSetProjectionRaw(mat4 projection) {
memcpy(state.projection, projection, 16 * sizeof(float));
} }
float lovrGraphicsGetLineWidth() { float lovrGraphicsGetLineWidth() {
@ -274,6 +274,30 @@ int lovrGraphicsGetHeight() {
return height; return height;
} }
void lovrGraphicsPushCanvas(CanvasState canvasState) {
if (!canvasState.isSystem && !state.canvases[state.canvas].isSystem) {
lovrGraphicsPopCanvas();
} else if (++state.canvas >= MAX_CANVASES) {
error("Canvas overflow");
}
int* viewport = canvasState.viewport;
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
glBindFramebuffer(GL_FRAMEBUFFER, canvasState.framebuffer);
state.canvases[state.canvas] = canvasState;
}
void lovrGraphicsPopCanvas() {
if (--state.canvas < 0) {
error("Canvas underflow");
}
CanvasState* canvasState = &state.canvases[state.canvas];
int* viewport = canvasState->viewport;
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
glBindFramebuffer(GL_FRAMEBUFFER, canvasState->framebuffer);
}
// Transforms // Transforms
int lovrGraphicsPush() { int lovrGraphicsPush() {

View File

@ -9,13 +9,7 @@
#define LOVR_GRAPHICS_TYPES #define LOVR_GRAPHICS_TYPES
#define MAX_TRANSFORMS 64 #define MAX_TRANSFORMS 64
#define MAX_CANVASES 4
typedef struct {
int x;
int y;
int width;
int height;
} ScissorRectangle;
typedef enum { typedef enum {
DRAW_MODE_FILL, DRAW_MODE_FILL,
@ -37,6 +31,20 @@ typedef enum {
COMPARE_GREATER = GL_GREATER COMPARE_GREATER = GL_GREATER
} CompareMode; } CompareMode;
typedef struct {
int x;
int y;
int width;
int height;
} ScissorRectangle;
typedef struct CanvasState {
int framebuffer;
float projection[16];
int viewport[4];
int isSystem;
} CanvasState;
typedef struct { typedef struct {
Shader* activeShader; Shader* activeShader;
Shader* defaultShader; Shader* defaultShader;
@ -44,7 +52,8 @@ typedef struct {
Texture* defaultTexture; Texture* defaultTexture;
int transform; int transform;
mat4 transforms[MAX_TRANSFORMS]; mat4 transforms[MAX_TRANSFORMS];
mat4 projection; int canvas;
CanvasState canvases[MAX_CANVASES];
unsigned int color; unsigned int color;
char colorMask; char colorMask;
int isScissorEnabled; int isScissorEnabled;
@ -87,7 +96,6 @@ Shader* lovrGraphicsGetShader();
void lovrGraphicsSetShader(Shader* shader); void lovrGraphicsSetShader(Shader* shader);
void lovrGraphicsBindTexture(Texture* texture); void lovrGraphicsBindTexture(Texture* texture);
void lovrGraphicsSetProjection(float near, float far, float fov); void lovrGraphicsSetProjection(float near, float far, float fov);
void lovrGraphicsSetProjectionRaw(mat4 projection);
float lovrGraphicsGetLineWidth(); float lovrGraphicsGetLineWidth();
void lovrGraphicsSetLineWidth(float width); void lovrGraphicsSetLineWidth(float width);
float lovrGraphicsGetPointSize(); float lovrGraphicsGetPointSize();
@ -102,6 +110,8 @@ int lovrGraphicsIsWireframe();
void lovrGraphicsSetWireframe(int wireframe); void lovrGraphicsSetWireframe(int wireframe);
int lovrGraphicsGetWidth(); int lovrGraphicsGetWidth();
int lovrGraphicsGetHeight(); int lovrGraphicsGetHeight();
void lovrGraphicsPushCanvas(CanvasState canvasState);
void lovrGraphicsPopCanvas();
// Transforms // Transforms
int lovrGraphicsPush(); int lovrGraphicsPush();

View File

@ -1,4 +1,5 @@
#include "graphics/texture.h" #include "graphics/texture.h"
#include "graphics/graphics.h"
#include "util.h" #include "util.h"
#include <stdlib.h> #include <stdlib.h>
@ -47,6 +48,22 @@ void lovrTextureBind(Texture* texture) {
glBindTexture(GL_TEXTURE_2D, texture->id); glBindTexture(GL_TEXTURE_2D, texture->id);
} }
CanvasState lovrTextureGetCanvasState(Texture* texture) {
if (!texture->fbo) {
error("Texture cannot be used as a canvas");
}
CanvasState canvasState = {
.framebuffer = texture->fbo,
.viewport = { 0, 0, texture->width, texture->height },
.isSystem = 0
};
mat4_setIdentity(canvasState.projection); // TODO
return canvasState;
}
int lovrTextureGetHeight(Texture* texture) { int lovrTextureGetHeight(Texture* texture) {
return texture->height; return texture->height;
} }
@ -60,20 +77,6 @@ void lovrTextureGetFilter(Texture* texture, FilterMode* min, FilterMode* mag) {
*mag = texture->filterMag; *mag = texture->filterMag;
} }
void lovrTextureRenderTo(Texture* texture, textureRenderCallback callback, void* userdata) {
if (!texture->fbo) {
error("Texture does not have a framebuffer");
}
int oldViewport[4];
glGetIntegerv(GL_VIEWPORT, oldViewport);
glViewport(0, 0, texture->textureData->width, texture->textureData->height);
glBindFramebuffer(GL_FRAMEBUFFER, texture->fbo);
callback(userdata);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
}
void lovrTextureSetFilter(Texture* texture, FilterMode min, FilterMode mag) { void lovrTextureSetFilter(Texture* texture, FilterMode min, FilterMode mag) {
texture->filterMin = min; texture->filterMin = min;
texture->filterMag = mag; texture->filterMag = mag;

View File

@ -1,13 +1,11 @@
#include "glfw.h" #include "glfw.h"
#include "util.h" #include "util.h"
struct Buffer; struct CanvasState;
#ifndef LOVR_TEXTURE_TYPES #ifndef LOVR_TEXTURE_TYPES
#define LOVR_TEXTURE_TYPES #define LOVR_TEXTURE_TYPES
typedef void (*textureRenderCallback)(void*);
typedef struct { typedef struct {
void* data; void* data;
int width; int width;
@ -27,11 +25,17 @@ typedef enum {
WRAP_CLAMP_ZERO = GL_CLAMP_TO_BORDER WRAP_CLAMP_ZERO = GL_CLAMP_TO_BORDER
} WrapMode; } WrapMode;
typedef enum {
PROJECTION_ORTHOGRAPHIC,
PROJECTION_PERSPECTIVE
} ProjectionType;
typedef struct { typedef struct {
Ref ref; Ref ref;
TextureData* textureData; TextureData* textureData;
GLuint id; GLuint id;
GLuint fbo; GLuint fbo;
ProjectionType projectionType;
int width; int width;
int height; int height;
FilterMode filterMin; FilterMode filterMin;
@ -46,10 +50,10 @@ Texture* lovrTextureCreate(TextureData* textureData, int hasFramebuffer);
void lovrTextureDestroy(const Ref* ref); void lovrTextureDestroy(const Ref* ref);
void lovrTextureDataDestroy(TextureData* textureData); void lovrTextureDataDestroy(TextureData* textureData);
void lovrTextureBind(Texture* texture); void lovrTextureBind(Texture* texture);
struct CanvasState lovrTextureGetCanvasState(Texture* texture);
void lovrTextureRefresh(Texture* texture); void lovrTextureRefresh(Texture* texture);
int lovrTextureGetHeight(Texture* texture); int lovrTextureGetHeight(Texture* texture);
int lovrTextureGetWidth(Texture* texture); int lovrTextureGetWidth(Texture* texture);
void lovrTextureRenderTo(Texture* texture, textureRenderCallback callback, void* userdata);
void lovrTextureGetFilter(Texture* texture, FilterMode* min, FilterMode* mag); void lovrTextureGetFilter(Texture* texture, FilterMode* min, FilterMode* mag);
void lovrTextureSetFilter(Texture* texture, FilterMode min, FilterMode mag); void lovrTextureSetFilter(Texture* texture, FilterMode min, FilterMode mag);
void lovrTextureGetWrap(Texture* texture, WrapMode* horizontal, WrapMode* vertical); void lovrTextureGetWrap(Texture* texture, WrapMode* horizontal, WrapMode* vertical);

View File

@ -484,7 +484,12 @@ void* viveControllerGetModel(void* headset, Controller* controller, ControllerMo
void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata) { void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata) {
Vive* vive = (Vive*) headset; Vive* vive = (Vive*) headset;
float headMatrix[16], eyeMatrix[16], projectionMatrix[16]; CanvasState canvasState = {
.framebuffer = vive->framebuffer,
.viewport = { 0, 0, vive->renderWidth, vive->renderHeight },
.isSystem = 1
};
float headMatrix[16], eyeMatrix[16];
float (*matrix)[4]; float (*matrix)[4];
vive->isRendering = 1; vive->isRendering = 1;
@ -502,21 +507,19 @@ void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata)
float near = vive->clipNear; float near = vive->clipNear;
float far = vive->clipFar; float far = vive->clipFar;
matrix = vive->system->GetProjectionMatrix(eye, near, far).m; matrix = vive->system->GetProjectionMatrix(eye, near, far).m;
mat4_fromMat44(projectionMatrix, matrix); mat4_fromMat44(canvasState.projection, matrix);
glEnable(GL_MULTISAMPLE); glEnable(GL_MULTISAMPLE);
glBindFramebuffer(GL_FRAMEBUFFER, vive->framebuffer);
glViewport(0, 0, vive->renderWidth, vive->renderHeight);
lovrGraphicsPushCanvas(canvasState);
lovrGraphicsClear(1, 1); lovrGraphicsClear(1, 1);
lovrGraphicsPush(); lovrGraphicsPush();
lovrGraphicsOrigin(); lovrGraphicsOrigin();
lovrGraphicsMatrixTransform(transformMatrix); lovrGraphicsMatrixTransform(transformMatrix);
lovrGraphicsSetProjectionRaw(projectionMatrix);
callback(i, userdata); callback(i, userdata);
lovrGraphicsPop(); lovrGraphicsPop();
lovrGraphicsPopCanvas();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_MULTISAMPLE); glDisable(GL_MULTISAMPLE);
glBindFramebuffer(GL_READ_FRAMEBUFFER, vive->framebuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, vive->framebuffer);

View File

@ -1,5 +1,6 @@
#include "lovr/types/texture.h" #include "lovr/types/texture.h"
#include "lovr/graphics.h" #include "lovr/graphics.h"
#include "graphics/graphics.h"
#include "util.h" #include "util.h"
const luaL_Reg lovrTexture[] = { const luaL_Reg lovrTexture[] = {
@ -15,12 +16,6 @@ const luaL_Reg lovrTexture[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static void renderHelper(void* userdata) {
lua_State* L = (lua_State*) userdata;
luaL_checktype(L, -1, LUA_TFUNCTION);
lua_call(L, 0, 0);
}
int l_lovrTextureBind(lua_State* L) { int l_lovrTextureBind(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture); Texture* texture = luax_checktype(L, 1, Texture);
lovrTextureBind(texture); lovrTextureBind(texture);
@ -66,8 +61,10 @@ int l_lovrTextureGetWrap(lua_State* L) {
int l_lovrTextureRenderTo(lua_State* L) { int l_lovrTextureRenderTo(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture); Texture* texture = luax_checktype(L, 1, Texture);
lovrGraphicsPushCanvas(lovrTextureGetCanvasState(texture));
lua_settop(L, 2); lua_settop(L, 2);
lovrTextureRenderTo(texture, renderHelper, L); lua_call(L, 0, 0);
lovrGraphicsPopCanvas();
return 0; return 0;
} }