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++) {
|
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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue