mirror of https://github.com/bjornbytes/lovr.git
Start texture projections;
This commit is contained in:
parent
9e7e1a113f
commit
09fdb72d5c
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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[];
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
17
src/matrix.c
17
src/matrix.c
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue