mirror of https://github.com/bjornbytes/lovr.git
CanvasState;
This commit is contained in:
parent
1ad0ac557b
commit
b05e2630dd
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue