Start texture projections;

This commit is contained in:
bjorn 2017-01-11 23:38:28 -08:00
parent 9e7e1a113f
commit 09fdb72d5c
8 changed files with 83 additions and 30 deletions

View File

@ -25,7 +25,7 @@ void lovrGraphicsInit() {
state.skyboxShader = lovrShaderCreate(lovrSkyboxVertexShader, lovrSkyboxFragmentShader);
int uniformId = lovrShaderGetUniformId(state.skyboxShader, "cube");
lovrShaderSendInt(state.skyboxShader, uniformId, 1);
state.defaultTexture = lovrTextureCreate(lovrTextureDataGetBlank(1, 1, 0xff), 0);
state.defaultTexture = lovrTextureCreate(lovrTextureDataGetBlank(1, 1, 0xff));
glGenBuffers(1, &state.shapeBuffer);
glGenBuffers(1, &state.shapeIndexBuffer);
glGenVertexArrays(1, &state.shapeArray);
@ -199,7 +199,7 @@ 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_setPerspective(state.canvases[state.canvas]->projection, near, far, fov, (float) width / height);
}
void lovrGraphicsSetProjectionRaw(mat4 projection) {

View File

@ -3,28 +3,43 @@
#include "util.h"
#include <stdlib.h>
Texture* lovrTextureCreate(TextureData* textureData, int hasFramebuffer) {
Texture* lovrTextureCreate(TextureData* textureData) {
Texture* texture = lovrAlloc(sizeof(Texture), lovrTextureDestroy);
if (!texture) return NULL;
int w = textureData->width;
int h = textureData->height;
texture->textureData = textureData;
glGenTextures(1, &texture->id);
lovrTextureBind(texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData->data);
lovrTextureSetFilter(texture, FILTER_LINEAR, FILTER_LINEAR);
lovrTextureSetWrap(texture, WRAP_REPEAT, WRAP_REPEAT);
if (textureData) {
lovrTextureBind(texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureData->width, textureData->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData->data);
lovrTextureSetFilter(texture, FILTER_LINEAR, FILTER_LINEAR);
lovrTextureSetWrap(texture, WRAP_REPEAT, WRAP_REPEAT);
texture->framebuffer = 0;
texture->renderbuffer = 0;
return texture;
}
Texture* lovrTextureCreateWithFramebuffer(TextureData* textureData, TextureProjection projection) {
Texture* texture = lovrTextureCreate(textureData);
if (!texture) return NULL;
texture->projection = projection;
glGenFramebuffers(1, &texture->framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, texture->framebuffer);
if (projection == PROJECTION_PERSPECTIVE) {
glGenRenderbuffers(1, &texture->renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, texture->renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, textureData->width, textureData->height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texture->renderbuffer);
}
if (hasFramebuffer) {
glGenFramebuffers(1, &texture->fbo);
glBindFramebuffer(GL_FRAMEBUFFER, texture->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->id, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
} else {
texture->fbo = 0;
}
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->id, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return texture;
}
@ -32,8 +47,8 @@ Texture* lovrTextureCreate(TextureData* textureData, int hasFramebuffer) {
void lovrTextureDestroy(const Ref* ref) {
Texture* texture = containerof(ref, Texture);
lovrTextureDataDestroy(texture->textureData);
if (texture->fbo) {
glDeleteFramebuffers(1, &texture->fbo);
if (texture->framebuffer) {
glDeleteFramebuffers(1, &texture->framebuffer);
}
glDeleteTextures(1, &texture->id);
free(texture);
@ -49,14 +64,22 @@ void lovrTextureBind(Texture* texture) {
}
void lovrTextureBindFramebuffer(Texture* texture) {
if (!texture->fbo) {
if (!texture->framebuffer) {
error("Texture cannot be used as a canvas");
}
lovrGraphicsBindFramebuffer(texture->fbo);
lovrGraphicsSetViewport(0, 0, texture->textureData->width, texture->textureData->height);
if (0) {
// lovrGraphicsSetProjection(); // TODO ortho
int w = texture->textureData->width;
int h = texture->textureData->height;
lovrGraphicsBindFramebuffer(texture->framebuffer);
lovrGraphicsSetViewport(0, 0, w, h);
if (texture->projection == PROJECTION_ORTHOGRAPHIC) {
float projection[16];
mat4_setOrthographic(projection, 0, w, 0, h, -1, 1);
lovrGraphicsSetProjectionRaw(projection);
} else if (texture->projection == PROJECTION_PERSPECTIVE) {
// lovrGraphicsSetProjection(); // TODO perspective
}
}

View File

@ -25,11 +25,18 @@ typedef enum {
WRAP_CLAMP_ZERO = GL_CLAMP_TO_BORDER
} WrapMode;
typedef enum {
PROJECTION_ORTHOGRAPHIC,
PROJECTION_PERSPECTIVE
} TextureProjection;
typedef struct {
Ref ref;
TextureData* textureData;
GLuint id;
GLuint fbo;
GLuint framebuffer;
GLuint renderbuffer;
TextureProjection projection;
FilterMode filterMin;
FilterMode filterMag;
WrapMode wrapHorizontal;
@ -38,7 +45,8 @@ typedef struct {
#endif
Texture* lovrTextureCreate(TextureData* textureData, int hasFramebuffer);
Texture* lovrTextureCreate(TextureData* textureData);
Texture* lovrTextureCreateWithFramebuffer(TextureData* textureData, TextureProjection projection);
void lovrTextureDestroy(const Ref* ref);
void lovrTextureDataDestroy(TextureData* textureData);
void lovrTextureBind(Texture* texture);

View File

@ -143,6 +143,10 @@ int l_lovrGraphicsInit(lua_State* L) {
map_set(&WrapModes, "mirroredrepeat", WRAP_MIRRORED_REPEAT);
map_set(&WrapModes, "clampzero", WRAP_CLAMP_ZERO);
map_init(&TextureProjections);
map_set(&TextureProjections, "2d", PROJECTION_ORTHOGRAPHIC);
map_set(&TextureProjections, "3d", PROJECTION_PERSPECTIVE);
lovrGraphicsInit();
return 1;
}
@ -650,13 +654,14 @@ int l_lovrGraphicsNewTexture(lua_State* L) {
return luaL_error(L, "Could not load texture file '%s'", path);
}
TextureData* textureData = lovrTextureDataFromFile(data, size);
texture = lovrTextureCreate(textureData, 0);
texture = lovrTextureCreate(textureData);
free(data);
} else {
int width = luaL_checknumber(L, 1);
int height = luaL_checknumber(L, 2);
TextureProjection* projection = luax_optenum(L, 3, "2d", &TextureProjections, "projection");
TextureData* textureData = lovrTextureDataGetEmpty(width, height);
texture = lovrTextureCreate(textureData, 1);
texture = lovrTextureCreateWithFramebuffer(textureData, *projection);
}
luax_pushtype(L, Texture, texture);

View File

@ -11,6 +11,7 @@ map_int_t PolygonWindings;
map_int_t CompareModes;
map_int_t FilterModes;
map_int_t WrapModes;
map_int_t TextureProjections;
extern const luaL_Reg lovrGraphics[];

View File

@ -72,7 +72,7 @@ int l_lovrControllerNewModel(lua_State* L) {
ModelData* modelData = lovrModelDataFromOpenVRModel(rawData);
TextureData* textureData = lovrTextureDataFromOpenVRModel(rawData);
Model* model = lovrModelCreate(modelData);
Texture* texture = lovrTextureCreate(textureData, 0);
Texture* texture = lovrTextureCreate(textureData);
lovrModelSetTexture(model, texture);
luax_pushtype(L, Model, model);
} else {

View File

@ -120,7 +120,22 @@ mat4 mat4_setScale(mat4 matrix, float x, float y, float z) {
return matrix;
}
mat4 mat4_setProjection(mat4 matrix, float near, float far, float fov, float aspect) {
mat4 mat4_setOrthographic(mat4 matrix, float left, float right, float top, float bottom, float near, float far) {
float rl = right - left;
float tb = top - bottom;
float fn = far - near;
mat4_setIdentity(matrix);
matrix[0] = 2 / rl;
matrix[5] = 2 / tb;
matrix[10] = -2 / fn;
matrix[12] = -(left + right) / rl;
matrix[13] = -(top + bottom) / tb;
matrix[14] = -(far + near) / fn;
matrix[15] = 1;
return matrix;
}
mat4 mat4_setPerspective(mat4 matrix, float near, float far, float fov, float aspect) {
float range = tan(fov * .5f) * near;
float sx = (2.0f * near) / (range * aspect + range * aspect);
float sy = near / range;

View File

@ -15,7 +15,8 @@ mat4 mat4_setIdentity(mat4 matrix);
mat4 mat4_setTranslation(mat4 matrix, float x, float y, float z);
mat4 mat4_setRotation(mat4 matrix, float angle, float ax, float ay, float az);
mat4 mat4_setScale(mat4 matrix, float x, float y, float z);
mat4 mat4_setProjection(mat4 matrix, float near, float far, float fov, float aspect);
mat4 mat4_setOrthographic(mat4 matrix, float left, float right, float top, float bottom, float near, float far);
mat4 mat4_setPerspective(mat4 matrix, float near, float far, float fov, float aspect);
void mat4_getRotation(mat4 matrix, float* w, float* x, float* y, float* z);
mat4 mat4_translate(mat4 matrix, float x, float y, float z);
mat4 mat4_rotate(mat4 matrix, float angle, float ax, float ay, float az);