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++) {
|
for (int i = 0; i < MAX_TRANSFORMS; i++) {
|
||||||
state.transforms[i] = mat4_init();
|
state.transforms[i] = mat4_init();
|
||||||
}
|
}
|
||||||
state.canvases[0].framebuffer = 0;
|
for (int i = 0; i < MAX_CANVASES; i++) {
|
||||||
glGetIntegerv(GL_VIEWPORT, state.canvases[0].viewport);
|
state.canvases[i] = malloc(sizeof(CanvasState));
|
||||||
state.canvases[0].isSystem = 1;
|
state.canvases[i]->projection = mat4_init();
|
||||||
|
}
|
||||||
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");
|
||||||
|
@ -40,6 +41,10 @@ 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]);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < MAX_CANVASES; i++) {
|
||||||
|
mat4_deinit(state.canvases[i]->projection);
|
||||||
|
free(state.canvases[i]);
|
||||||
|
}
|
||||||
lovrRelease(&state.defaultShader->ref);
|
lovrRelease(&state.defaultShader->ref);
|
||||||
lovrRelease(&state.skyboxShader->ref);
|
lovrRelease(&state.skyboxShader->ref);
|
||||||
lovrRelease(&state.defaultTexture->ref);
|
lovrRelease(&state.defaultTexture->ref);
|
||||||
|
@ -53,7 +58,9 @@ void lovrGraphicsDestroy() {
|
||||||
void lovrGraphicsReset() {
|
void lovrGraphicsReset() {
|
||||||
state.transform = 0;
|
state.transform = 0;
|
||||||
state.canvas = 0;
|
state.canvas = 0;
|
||||||
|
lovrGraphicsSetViewport(0, 0, lovrGraphicsGetWidth(), lovrGraphicsGetHeight());
|
||||||
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
|
||||||
|
lovrGraphicsBindFramebuffer(0);
|
||||||
lovrGraphicsSetShader(NULL);
|
lovrGraphicsSetShader(NULL);
|
||||||
lovrGraphicsBindTexture(NULL);
|
lovrGraphicsBindTexture(NULL);
|
||||||
lovrGraphicsSetBackgroundColor(0, 0, 0, 0);
|
lovrGraphicsSetBackgroundColor(0, 0, 0, 0);
|
||||||
|
@ -89,7 +96,7 @@ void lovrGraphicsPresent() {
|
||||||
void lovrGraphicsPrepare() {
|
void lovrGraphicsPrepare() {
|
||||||
Shader* shader = lovrGraphicsGetShader();
|
Shader* shader = lovrGraphicsGetShader();
|
||||||
mat4 transform = state.transforms[state.transform];
|
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);
|
lovrShaderBind(shader, transform, projection, state.color, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +199,11 @@ 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.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() {
|
float lovrGraphicsGetLineWidth() {
|
||||||
|
@ -274,17 +285,12 @@ int lovrGraphicsGetHeight() {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsPushCanvas(CanvasState canvasState) {
|
void lovrGraphicsPushCanvas() {
|
||||||
if (!canvasState.isSystem && !state.canvases[state.canvas].isSystem) {
|
if (++state.canvas >= MAX_CANVASES) {
|
||||||
lovrGraphicsPopCanvas();
|
|
||||||
} else if (++state.canvas >= MAX_CANVASES) {
|
|
||||||
error("Canvas overflow");
|
error("Canvas overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
int* viewport = canvasState.viewport;
|
memcpy(state.canvases[state.canvas], state.canvases[state.canvas - 1], sizeof(CanvasState));
|
||||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, canvasState.framebuffer);
|
|
||||||
state.canvases[state.canvas] = canvasState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrGraphicsPopCanvas() {
|
void lovrGraphicsPopCanvas() {
|
||||||
|
@ -292,10 +298,22 @@ void lovrGraphicsPopCanvas() {
|
||||||
error("Canvas underflow");
|
error("Canvas underflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasState* canvasState = &state.canvases[state.canvas];
|
int* viewport = state.canvases[state.canvas]->viewport;
|
||||||
int* viewport = canvasState->viewport;
|
lovrGraphicsSetViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
lovrGraphicsBindFramebuffer(state.canvases[state.canvas]->framebuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, canvasState->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
|
// Transforms
|
||||||
|
|
|
@ -40,9 +40,8 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct CanvasState {
|
typedef struct CanvasState {
|
||||||
int framebuffer;
|
int framebuffer;
|
||||||
float projection[16];
|
mat4 projection;
|
||||||
int viewport[4];
|
int viewport[4];
|
||||||
int isSystem;
|
|
||||||
} CanvasState;
|
} CanvasState;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -53,7 +52,7 @@ typedef struct {
|
||||||
int transform;
|
int transform;
|
||||||
mat4 transforms[MAX_TRANSFORMS];
|
mat4 transforms[MAX_TRANSFORMS];
|
||||||
int canvas;
|
int canvas;
|
||||||
CanvasState canvases[MAX_CANVASES];
|
CanvasState* canvases[MAX_CANVASES];
|
||||||
unsigned int color;
|
unsigned int color;
|
||||||
char colorMask;
|
char colorMask;
|
||||||
int isScissorEnabled;
|
int isScissorEnabled;
|
||||||
|
@ -96,6 +95,7 @@ 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();
|
||||||
|
@ -110,8 +110,10 @@ int lovrGraphicsIsWireframe();
|
||||||
void lovrGraphicsSetWireframe(int wireframe);
|
void lovrGraphicsSetWireframe(int wireframe);
|
||||||
int lovrGraphicsGetWidth();
|
int lovrGraphicsGetWidth();
|
||||||
int lovrGraphicsGetHeight();
|
int lovrGraphicsGetHeight();
|
||||||
void lovrGraphicsPushCanvas(CanvasState canvasState);
|
void lovrGraphicsPushCanvas();
|
||||||
void lovrGraphicsPopCanvas();
|
void lovrGraphicsPopCanvas();
|
||||||
|
void lovrGraphicsSetViewport(int x, int y, int w, int h);
|
||||||
|
void lovrGraphicsBindFramebuffer(int framebuffer);
|
||||||
|
|
||||||
// Transforms
|
// Transforms
|
||||||
int lovrGraphicsPush();
|
int lovrGraphicsPush();
|
||||||
|
|
|
@ -48,20 +48,16 @@ void lovrTextureBind(Texture* texture) {
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasState lovrTextureGetCanvasState(Texture* texture) {
|
void lovrTextureBindFramebuffer(Texture* texture) {
|
||||||
if (!texture->fbo) {
|
if (!texture->fbo) {
|
||||||
error("Texture cannot be used as a canvas");
|
error("Texture cannot be used as a canvas");
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasState canvasState = {
|
lovrGraphicsBindFramebuffer(texture->fbo);
|
||||||
.framebuffer = texture->fbo,
|
lovrGraphicsSetViewport(0, 0, texture->textureData->width, texture->textureData->height);
|
||||||
.viewport = { 0, 0, texture->textureData->width, texture->textureData->height },
|
if (0) {
|
||||||
.isSystem = 0
|
// lovrGraphicsSetProjection(); // TODO ortho
|
||||||
};
|
}
|
||||||
|
|
||||||
mat4_setIdentity(canvasState.projection); // TODO
|
|
||||||
|
|
||||||
return canvasState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int lovrTextureGetHeight(Texture* texture) {
|
int lovrTextureGetHeight(Texture* texture) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ 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 lovrTextureBindFramebuffer(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);
|
||||||
|
|
|
@ -484,50 +484,53 @@ 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;
|
||||||
CanvasState canvasState = {
|
float projectionMatrix[16], headMatrix[16], eyeMatrix[16];
|
||||||
.framebuffer = vive->framebuffer,
|
|
||||||
.viewport = { 0, 0, vive->renderWidth, vive->renderHeight },
|
|
||||||
.isSystem = 1
|
|
||||||
};
|
|
||||||
float headMatrix[16], eyeMatrix[16];
|
|
||||||
float (*matrix)[4];
|
float (*matrix)[4];
|
||||||
|
float near = vive->clipNear;
|
||||||
|
float far = vive->clipFar;
|
||||||
|
|
||||||
|
lovrGraphicsPushCanvas();
|
||||||
|
lovrGraphicsSetViewport(0, 0, vive->renderWidth, vive->renderHeight);
|
||||||
vive->isRendering = 1;
|
vive->isRendering = 1;
|
||||||
vive->compositor->WaitGetPoses(vive->renderPoses, 16, NULL, 0);
|
vive->compositor->WaitGetPoses(vive->renderPoses, 16, NULL, 0);
|
||||||
|
|
||||||
|
// Head transform
|
||||||
matrix = vive->renderPoses[vive->headsetIndex].mDeviceToAbsoluteTracking.m;
|
matrix = vive->renderPoses[vive->headsetIndex].mDeviceToAbsoluteTracking.m;
|
||||||
mat4_invert(mat4_fromMat34(headMatrix, matrix));
|
mat4_invert(mat4_fromMat34(headMatrix, matrix));
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
EVREye eye = (i == 0) ? EVREye_Eye_Left : EVREye_Eye_Right;
|
EVREye eye = (i == 0) ? EVREye_Eye_Left : EVREye_Eye_Right;
|
||||||
|
|
||||||
|
// Eye transform
|
||||||
matrix = vive->system->GetEyeToHeadTransform(eye).m;
|
matrix = vive->system->GetEyeToHeadTransform(eye).m;
|
||||||
mat4_invert(mat4_fromMat34(eyeMatrix, matrix));
|
mat4_invert(mat4_fromMat34(eyeMatrix, matrix));
|
||||||
mat4 transformMatrix = mat4_multiply(eyeMatrix, headMatrix);
|
mat4 transformMatrix = mat4_multiply(eyeMatrix, headMatrix);
|
||||||
|
|
||||||
float near = vive->clipNear;
|
// Projection
|
||||||
float far = vive->clipFar;
|
|
||||||
matrix = vive->system->GetProjectionMatrix(eye, near, far).m;
|
matrix = vive->system->GetProjectionMatrix(eye, near, far).m;
|
||||||
mat4_fromMat44(canvasState.projection, matrix);
|
mat4_fromMat44(projectionMatrix, matrix);
|
||||||
|
|
||||||
|
// Render
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
lovrGraphicsBindFramebuffer(vive->framebuffer);
|
||||||
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();
|
lovrGraphicsBindFramebuffer(0);
|
||||||
|
|
||||||
glDisable(GL_MULTISAMPLE);
|
glDisable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
|
// Blit
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, vive->framebuffer);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, vive->framebuffer);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, vive->resolveFramebuffer);
|
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);
|
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_READ_FRAMEBUFFER, 0);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
// Submit
|
||||||
uintptr_t texture = (uintptr_t) vive->resolveTexture;
|
uintptr_t texture = (uintptr_t) vive->resolveTexture;
|
||||||
ETextureType textureType = ETextureType_TextureType_OpenGL;
|
ETextureType textureType = ETextureType_TextureType_OpenGL;
|
||||||
Texture_t eyeTexture = { (void*) texture, textureType, EColorSpace_ColorSpace_Gamma };
|
Texture_t eyeTexture = { (void*) texture, textureType, EColorSpace_ColorSpace_Gamma };
|
||||||
|
@ -536,4 +539,5 @@ void viveRenderTo(void* headset, headsetRenderCallback callback, void* userdata)
|
||||||
}
|
}
|
||||||
|
|
||||||
vive->isRendering = 0;
|
vive->isRendering = 0;
|
||||||
|
lovrGraphicsPopCanvas();
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,8 @@ 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));
|
lovrGraphicsPushCanvas();
|
||||||
|
lovrTextureBindFramebuffer(texture);
|
||||||
lua_settop(L, 2);
|
lua_settop(L, 2);
|
||||||
lua_call(L, 0, 0);
|
lua_call(L, 0, 0);
|
||||||
lovrGraphicsPopCanvas();
|
lovrGraphicsPopCanvas();
|
||||||
|
|
Loading…
Reference in New Issue