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++) {
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.skyboxShader = lovrShaderCreate(lovrSkyboxVertexShader, lovrSkyboxFragmentShader);
int uniformId = lovrShaderGetUniformId(state.skyboxShader, "cube");
@ -38,7 +40,6 @@ void lovrGraphicsDestroy() {
for (int i = 0; i < MAX_TRANSFORMS; i++) {
mat4_deinit(state.transforms[i]);
}
mat4_deinit(state.projection);
lovrRelease(&state.defaultShader->ref);
lovrRelease(&state.skyboxShader->ref);
lovrRelease(&state.defaultTexture->ref);
@ -51,6 +52,7 @@ void lovrGraphicsDestroy() {
void lovrGraphicsReset() {
state.transform = 0;
state.canvas = 0;
lovrGraphicsSetProjection(.1f, 100.f, 67 * M_PI / 180); // TODO customize via lovr.conf
lovrGraphicsSetShader(NULL);
lovrGraphicsBindTexture(NULL);
@ -86,7 +88,9 @@ void lovrGraphicsPresent() {
void lovrGraphicsPrepare() {
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
@ -188,11 +192,7 @@ void lovrGraphicsBindTexture(Texture* texture) {
void lovrGraphicsSetProjection(float near, float far, float fov) {
int width, height;
glfwGetWindowSize(window, &width, &height);
mat4_setProjection(state.projection, near, far, fov, (float) width / height);
}
void lovrGraphicsSetProjectionRaw(mat4 projection) {
memcpy(state.projection, projection, 16 * sizeof(float));
mat4_setProjection(state.canvases[state.canvas].projection, near, far, fov, (float) width / height);
}
float lovrGraphicsGetLineWidth() {
@ -274,6 +274,30 @@ int lovrGraphicsGetHeight() {
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
int lovrGraphicsPush() {

View File

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

View File

@ -1,4 +1,5 @@
#include "graphics/texture.h"
#include "graphics/graphics.h"
#include "util.h"
#include <stdlib.h>
@ -47,6 +48,22 @@ void lovrTextureBind(Texture* texture) {
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) {
return texture->height;
}
@ -60,20 +77,6 @@ void lovrTextureGetFilter(Texture* texture, FilterMode* min, FilterMode* mag) {
*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) {
texture->filterMin = min;
texture->filterMag = mag;

View File

@ -1,13 +1,11 @@
#include "glfw.h"
#include "util.h"
struct Buffer;
struct CanvasState;
#ifndef LOVR_TEXTURE_TYPES
#define LOVR_TEXTURE_TYPES
typedef void (*textureRenderCallback)(void*);
typedef struct {
void* data;
int width;
@ -27,11 +25,17 @@ typedef enum {
WRAP_CLAMP_ZERO = GL_CLAMP_TO_BORDER
} WrapMode;
typedef enum {
PROJECTION_ORTHOGRAPHIC,
PROJECTION_PERSPECTIVE
} ProjectionType;
typedef struct {
Ref ref;
TextureData* textureData;
GLuint id;
GLuint fbo;
ProjectionType projectionType;
int width;
int height;
FilterMode filterMin;
@ -46,10 +50,10 @@ Texture* lovrTextureCreate(TextureData* textureData, int hasFramebuffer);
void lovrTextureDestroy(const Ref* ref);
void lovrTextureDataDestroy(TextureData* textureData);
void lovrTextureBind(Texture* texture);
struct CanvasState lovrTextureGetCanvasState(Texture* texture);
void lovrTextureRefresh(Texture* texture);
int lovrTextureGetHeight(Texture* texture);
int lovrTextureGetWidth(Texture* texture);
void lovrTextureRenderTo(Texture* texture, textureRenderCallback callback, void* userdata);
void lovrTextureGetFilter(Texture* texture, FilterMode* min, FilterMode* mag);
void lovrTextureSetFilter(Texture* texture, FilterMode min, FilterMode mag);
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) {
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];
vive->isRendering = 1;
@ -502,21 +507,19 @@ void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata)
float near = vive->clipNear;
float far = vive->clipFar;
matrix = vive->system->GetProjectionMatrix(eye, near, far).m;
mat4_fromMat44(projectionMatrix, matrix);
mat4_fromMat44(canvasState.projection, matrix);
glEnable(GL_MULTISAMPLE);
glBindFramebuffer(GL_FRAMEBUFFER, vive->framebuffer);
glViewport(0, 0, vive->renderWidth, vive->renderHeight);
lovrGraphicsPushCanvas(canvasState);
lovrGraphicsClear(1, 1);
lovrGraphicsPush();
lovrGraphicsOrigin();
lovrGraphicsMatrixTransform(transformMatrix);
lovrGraphicsSetProjectionRaw(projectionMatrix);
callback(i, userdata);
lovrGraphicsPop();
lovrGraphicsPopCanvas();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_MULTISAMPLE);
glBindFramebuffer(GL_READ_FRAMEBUFFER, vive->framebuffer);

View File

@ -1,5 +1,6 @@
#include "lovr/types/texture.h"
#include "lovr/graphics.h"
#include "graphics/graphics.h"
#include "util.h"
const luaL_Reg lovrTexture[] = {
@ -15,12 +16,6 @@ const luaL_Reg lovrTexture[] = {
{ 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) {
Texture* texture = luax_checktype(L, 1, Texture);
lovrTextureBind(texture);
@ -66,8 +61,10 @@ int l_lovrTextureGetWrap(lua_State* L) {
int l_lovrTextureRenderTo(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
lovrGraphicsPushCanvas(lovrTextureGetCanvasState(texture));
lua_settop(L, 2);
lovrTextureRenderTo(texture, renderHelper, L);
lua_call(L, 0, 0);
lovrGraphicsPopCanvas();
return 0;
}