mirror of https://github.com/bjornbytes/lovr.git
Improve CanvasState;
This commit is contained in:
parent
9f43f84577
commit
eba3996984
|
@ -17,9 +17,10 @@ void lovrGraphicsInit() {
|
|||
for (int i = 0; i < MAX_TRANSFORMS; i++) {
|
||||
state.transforms[i] = mat4_init();
|
||||
}
|
||||
state.canvases[0].framebuffer = 0;
|
||||
glGetIntegerv(GL_VIEWPORT, state.canvases[0].viewport);
|
||||
state.canvases[0].isSystem = 1;
|
||||
for (int i = 0; i < MAX_CANVASES; i++) {
|
||||
state.canvases[i] = malloc(sizeof(CanvasState));
|
||||
state.canvases[i]->projection = mat4_init();
|
||||
}
|
||||
state.defaultShader = lovrShaderCreate(lovrDefaultVertexShader, lovrDefaultFragmentShader);
|
||||
state.skyboxShader = lovrShaderCreate(lovrSkyboxVertexShader, lovrSkyboxFragmentShader);
|
||||
int uniformId = lovrShaderGetUniformId(state.skyboxShader, "cube");
|
||||
|
@ -40,6 +41,10 @@ void lovrGraphicsDestroy() {
|
|||
for (int i = 0; i < MAX_TRANSFORMS; i++) {
|
||||
mat4_deinit(state.transforms[i]);
|
||||
}
|
||||
for (int i = 0; i < MAX_CANVASES; i++) {
|
||||
mat4_deinit(state.canvases[i]->projection);
|
||||
free(state.canvases[i]);
|
||||
}
|
||||
lovrRelease(&state.defaultShader->ref);
|
||||
lovrRelease(&state.skyboxShader->ref);
|
||||
lovrRelease(&state.defaultTexture->ref);
|
||||
|
@ -53,7 +58,9 @@ void lovrGraphicsDestroy() {
|
|||
void lovrGraphicsReset() {
|
||||
state.transform = 0;
|
||||
state.canvas = 0;
|
||||
lovrGraphicsSetViewport(0, 0, lovrGraphicsGetWidth(), lovrGraphicsGetHeight());
|
||||
lovrGraphicsSetProjection(.1f, 100.f, 67 * M_PI / 180); // TODO customize via lovr.conf
|
||||
lovrGraphicsBindFramebuffer(0);
|
||||
lovrGraphicsSetShader(NULL);
|
||||
lovrGraphicsBindTexture(NULL);
|
||||
lovrGraphicsSetBackgroundColor(0, 0, 0, 0);
|
||||
|
@ -89,7 +96,7 @@ void lovrGraphicsPresent() {
|
|||
void lovrGraphicsPrepare() {
|
||||
Shader* shader = lovrGraphicsGetShader();
|
||||
mat4 transform = state.transforms[state.transform];
|
||||
mat4 projection = state.canvases[state.canvas].projection;
|
||||
mat4 projection = state.canvases[state.canvas]->projection;
|
||||
lovrShaderBind(shader, transform, projection, state.color, 0);
|
||||
}
|
||||
|
||||
|
@ -192,7 +199,11 @@ void lovrGraphicsBindTexture(Texture* texture) {
|
|||
void lovrGraphicsSetProjection(float near, float far, float fov) {
|
||||
int width, height;
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
mat4_setProjection(state.canvases[state.canvas].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.canvases[state.canvas]->projection, projection, 16 * sizeof(float));
|
||||
}
|
||||
|
||||
float lovrGraphicsGetLineWidth() {
|
||||
|
@ -274,17 +285,12 @@ int lovrGraphicsGetHeight() {
|
|||
return height;
|
||||
}
|
||||
|
||||
void lovrGraphicsPushCanvas(CanvasState canvasState) {
|
||||
if (!canvasState.isSystem && !state.canvases[state.canvas].isSystem) {
|
||||
lovrGraphicsPopCanvas();
|
||||
} else if (++state.canvas >= MAX_CANVASES) {
|
||||
void lovrGraphicsPushCanvas() {
|
||||
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;
|
||||
memcpy(state.canvases[state.canvas], state.canvases[state.canvas - 1], sizeof(CanvasState));
|
||||
}
|
||||
|
||||
void lovrGraphicsPopCanvas() {
|
||||
|
@ -292,10 +298,22 @@ void lovrGraphicsPopCanvas() {
|
|||
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);
|
||||
int* viewport = state.canvases[state.canvas]->viewport;
|
||||
lovrGraphicsSetViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
lovrGraphicsBindFramebuffer(state.canvases[state.canvas]->framebuffer);
|
||||
}
|
||||
|
||||
void lovrGraphicsSetViewport(int x, int y, int w, int h) {
|
||||
state.canvases[state.canvas]->viewport[0] = x;
|
||||
state.canvases[state.canvas]->viewport[1] = y;
|
||||
state.canvases[state.canvas]->viewport[2] = w;
|
||||
state.canvases[state.canvas]->viewport[3] = h;
|
||||
glViewport(x, y, w, h);
|
||||
}
|
||||
|
||||
void lovrGraphicsBindFramebuffer(int framebuffer) {
|
||||
state.canvases[state.canvas]->framebuffer = framebuffer;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
}
|
||||
|
||||
// Transforms
|
||||
|
|
|
@ -40,9 +40,8 @@ typedef struct {
|
|||
|
||||
typedef struct CanvasState {
|
||||
int framebuffer;
|
||||
float projection[16];
|
||||
mat4 projection;
|
||||
int viewport[4];
|
||||
int isSystem;
|
||||
} CanvasState;
|
||||
|
||||
typedef struct {
|
||||
|
@ -53,7 +52,7 @@ typedef struct {
|
|||
int transform;
|
||||
mat4 transforms[MAX_TRANSFORMS];
|
||||
int canvas;
|
||||
CanvasState canvases[MAX_CANVASES];
|
||||
CanvasState* canvases[MAX_CANVASES];
|
||||
unsigned int color;
|
||||
char colorMask;
|
||||
int isScissorEnabled;
|
||||
|
@ -96,6 +95,7 @@ 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();
|
||||
|
@ -110,8 +110,10 @@ int lovrGraphicsIsWireframe();
|
|||
void lovrGraphicsSetWireframe(int wireframe);
|
||||
int lovrGraphicsGetWidth();
|
||||
int lovrGraphicsGetHeight();
|
||||
void lovrGraphicsPushCanvas(CanvasState canvasState);
|
||||
void lovrGraphicsPushCanvas();
|
||||
void lovrGraphicsPopCanvas();
|
||||
void lovrGraphicsSetViewport(int x, int y, int w, int h);
|
||||
void lovrGraphicsBindFramebuffer(int framebuffer);
|
||||
|
||||
// Transforms
|
||||
int lovrGraphicsPush();
|
||||
|
|
|
@ -48,20 +48,16 @@ void lovrTextureBind(Texture* texture) {
|
|||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
}
|
||||
|
||||
CanvasState lovrTextureGetCanvasState(Texture* texture) {
|
||||
void lovrTextureBindFramebuffer(Texture* texture) {
|
||||
if (!texture->fbo) {
|
||||
error("Texture cannot be used as a canvas");
|
||||
}
|
||||
|
||||
CanvasState canvasState = {
|
||||
.framebuffer = texture->fbo,
|
||||
.viewport = { 0, 0, texture->textureData->width, texture->textureData->height },
|
||||
.isSystem = 0
|
||||
};
|
||||
|
||||
mat4_setIdentity(canvasState.projection); // TODO
|
||||
|
||||
return canvasState;
|
||||
lovrGraphicsBindFramebuffer(texture->fbo);
|
||||
lovrGraphicsSetViewport(0, 0, texture->textureData->width, texture->textureData->height);
|
||||
if (0) {
|
||||
// lovrGraphicsSetProjection(); // TODO ortho
|
||||
}
|
||||
}
|
||||
|
||||
int lovrTextureGetHeight(Texture* texture) {
|
||||
|
|
|
@ -42,7 +42,7 @@ 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 lovrTextureBindFramebuffer(Texture* texture);
|
||||
void lovrTextureRefresh(Texture* texture);
|
||||
int lovrTextureGetHeight(Texture* texture);
|
||||
int lovrTextureGetWidth(Texture* texture);
|
||||
|
|
|
@ -484,50 +484,53 @@ void* viveControllerGetModel(void* headset, Controller* controller, ControllerMo
|
|||
|
||||
void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata) {
|
||||
Vive* vive = (Vive*) headset;
|
||||
CanvasState canvasState = {
|
||||
.framebuffer = vive->framebuffer,
|
||||
.viewport = { 0, 0, vive->renderWidth, vive->renderHeight },
|
||||
.isSystem = 1
|
||||
};
|
||||
float headMatrix[16], eyeMatrix[16];
|
||||
float projectionMatrix[16], headMatrix[16], eyeMatrix[16];
|
||||
float (*matrix)[4];
|
||||
float near = vive->clipNear;
|
||||
float far = vive->clipFar;
|
||||
|
||||
lovrGraphicsPushCanvas();
|
||||
lovrGraphicsSetViewport(0, 0, vive->renderWidth, vive->renderHeight);
|
||||
vive->isRendering = 1;
|
||||
vive->compositor->WaitGetPoses(vive->renderPoses, 16, NULL, 0);
|
||||
|
||||
// Head transform
|
||||
matrix = vive->renderPoses[vive->headsetIndex].mDeviceToAbsoluteTracking.m;
|
||||
mat4_invert(mat4_fromMat34(headMatrix, matrix));
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
EVREye eye = (i == 0) ? EVREye_Eye_Left : EVREye_Eye_Right;
|
||||
|
||||
// Eye transform
|
||||
matrix = vive->system->GetEyeToHeadTransform(eye).m;
|
||||
mat4_invert(mat4_fromMat34(eyeMatrix, matrix));
|
||||
mat4 transformMatrix = mat4_multiply(eyeMatrix, headMatrix);
|
||||
|
||||
float near = vive->clipNear;
|
||||
float far = vive->clipFar;
|
||||
// Projection
|
||||
matrix = vive->system->GetProjectionMatrix(eye, near, far).m;
|
||||
mat4_fromMat44(canvasState.projection, matrix);
|
||||
mat4_fromMat44(projectionMatrix, matrix);
|
||||
|
||||
// Render
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
lovrGraphicsPushCanvas(canvasState);
|
||||
lovrGraphicsBindFramebuffer(vive->framebuffer);
|
||||
lovrGraphicsClear(1, 1);
|
||||
lovrGraphicsPush();
|
||||
lovrGraphicsOrigin();
|
||||
lovrGraphicsMatrixTransform(transformMatrix);
|
||||
lovrGraphicsSetProjectionRaw(projectionMatrix);
|
||||
callback(i, userdata);
|
||||
lovrGraphicsPop();
|
||||
lovrGraphicsPopCanvas();
|
||||
|
||||
lovrGraphicsBindFramebuffer(0);
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
|
||||
// Blit
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, vive->framebuffer);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, vive->resolveFramebuffer);
|
||||
glBlitFramebuffer(0, 0, vive->renderWidth, vive->renderHeight, 0, 0, vive->renderWidth, vive->renderHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
||||
// Submit
|
||||
uintptr_t texture = (uintptr_t) vive->resolveTexture;
|
||||
ETextureType textureType = ETextureType_TextureType_OpenGL;
|
||||
Texture_t eyeTexture = { (void*) texture, textureType, EColorSpace_ColorSpace_Gamma };
|
||||
|
@ -536,4 +539,5 @@ void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata)
|
|||
}
|
||||
|
||||
vive->isRendering = 0;
|
||||
lovrGraphicsPopCanvas();
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ int l_lovrTextureGetWrap(lua_State* L) {
|
|||
|
||||
int l_lovrTextureRenderTo(lua_State* L) {
|
||||
Texture* texture = luax_checktype(L, 1, Texture);
|
||||
lovrGraphicsPushCanvas(lovrTextureGetCanvasState(texture));
|
||||
lovrGraphicsPushCanvas();
|
||||
lovrTextureBindFramebuffer(texture);
|
||||
lua_settop(L, 2);
|
||||
lua_call(L, 0, 0);
|
||||
lovrGraphicsPopCanvas();
|
||||
|
|
Loading…
Reference in New Issue