Basic framebuffers;

This commit is contained in:
bjorn 2017-01-08 22:51:43 -08:00
parent 2a8d40abd6
commit 1ad0ac557b
10 changed files with 81 additions and 15 deletions

View File

@ -22,7 +22,7 @@ void lovrGraphicsInit() {
state.skyboxShader = lovrShaderCreate(lovrSkyboxVertexShader, lovrSkyboxFragmentShader);
int uniformId = lovrShaderGetUniformId(state.skyboxShader, "cube");
lovrShaderSendInt(state.skyboxShader, uniformId, 1);
state.defaultTexture = lovrTextureCreate(lovrTextureDataGetEmpty(1, 1, 0xff));
state.defaultTexture = lovrTextureCreate(lovrTextureDataGetBlank(1, 1, 0xff), 0);
glGenBuffers(1, &state.shapeBuffer);
glGenBuffers(1, &state.shapeIndexBuffer);
glGenVertexArrays(1, &state.shapeArray);

View File

@ -2,7 +2,7 @@
#include "util.h"
#include <stdlib.h>
Texture* lovrTextureCreate(TextureData* textureData) {
Texture* lovrTextureCreate(TextureData* textureData, int hasFramebuffer) {
Texture* texture = lovrAlloc(sizeof(Texture), lovrTextureDestroy);
if (!texture) return NULL;
@ -16,12 +16,24 @@ Texture* lovrTextureCreate(TextureData* textureData) {
lovrTextureSetWrap(texture, WRAP_REPEAT, WRAP_REPEAT);
}
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;
}
return texture;
}
void lovrTextureDestroy(const Ref* ref) {
Texture* texture = containerof(ref, Texture);
lovrTextureDataDestroy(texture->textureData);
if (texture->fbo) {
glDeleteFramebuffers(1, &texture->fbo);
}
glDeleteTextures(1, &texture->id);
free(texture);
}
@ -48,6 +60,20 @@ void lovrTextureGetFilter(Texture* texture, FilterMode* min, FilterMode* mag) {
*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) {
texture->filterMin = min;
texture->filterMag = mag;

View File

@ -6,6 +6,8 @@ struct Buffer;
#ifndef LOVR_TEXTURE_TYPES
#define LOVR_TEXTURE_TYPES
typedef void (*textureRenderCallback)(void*);
typedef struct {
void* data;
int width;
@ -29,6 +31,7 @@ typedef struct {
Ref ref;
TextureData* textureData;
GLuint id;
GLuint fbo;
int width;
int height;
FilterMode filterMin;
@ -39,13 +42,14 @@ typedef struct {
#endif
Texture* lovrTextureCreate(TextureData* textureData);
Texture* lovrTextureCreate(TextureData* textureData, int hasFramebuffer);
void lovrTextureDestroy(const Ref* ref);
void lovrTextureDataDestroy(TextureData* textureData);
void lovrTextureBind(Texture* texture);
void lovrTextureRefresh(Texture* texture);
int lovrTextureGetHeight(Texture* texture);
int lovrTextureGetWidth(Texture* texture);
void lovrTextureRenderTo(Texture* texture, textureRenderCallback callback, void* userdata);
void lovrTextureGetFilter(Texture* texture, FilterMode* min, FilterMode* mag);
void lovrTextureSetFilter(Texture* texture, FilterMode min, FilterMode mag);
void lovrTextureGetWrap(Texture* texture, WrapMode* horizontal, WrapMode* vertical);

View File

@ -2,7 +2,7 @@
#include "util.h"
#include <stdlib.h>
TextureData* lovrTextureDataGetEmpty(int width, int height, uint8_t value) {
TextureData* lovrTextureDataGetBlank(int width, int height, uint8_t value) {
TextureData* textureData = malloc(sizeof(TextureData));
if (!textureData) return NULL;
@ -19,6 +19,18 @@ TextureData* lovrTextureDataGetEmpty(int width, int height, uint8_t value) {
return textureData;
}
TextureData* lovrTextureDataGetEmpty(int width, int height) {
TextureData* textureData = malloc(sizeof(TextureData));
if (!textureData) return NULL;
textureData->data = NULL;
textureData->width = width;
textureData->height = height;
textureData->channels = 4;
return textureData;
}
TextureData* lovrTextureDataFromFile(void* data, int size) {
TextureData* textureData = malloc(sizeof(TextureData));
if (!textureData) return NULL;

View File

@ -2,6 +2,7 @@
#include "openvr.h"
#include <stdint.h>
TextureData* lovrTextureDataGetEmpty(int width, int height, uint8_t value);
TextureData* lovrTextureDataGetBlank(int width, int height, uint8_t value);
TextureData* lovrTextureDataGetEmpty(int width, int height);
TextureData* lovrTextureDataFromFile(void* data, int size);
TextureData* lovrTextureDataFromOpenVRModel(OpenVRModel* vrModel);

View File

@ -3,7 +3,7 @@
#include <lualib.h>
#define LOVR_VERSION_MAJOR 0
#define LOVR_VERSION_MINOR 1
#define LOVR_VERSION_MINOR 2
#define LOVR_VERSION_PATCH 0
void lovrInit(lua_State* L, int argc, char** argv);

View File

@ -641,17 +641,25 @@ int l_lovrGraphicsNewSkybox(lua_State* L) {
int l_lovrGraphicsNewTexture(lua_State* L) {
Texture* texture;
const char* path = luaL_checkstring(L, 1);
int size;
void* data = lovrFilesystemRead(path, &size);
if (!data) {
return luaL_error(L, "Could not load texture file '%s'", path);
if (lua_type(L, 1) == LUA_TSTRING) {
const char* path = luaL_checkstring(L, 1);
int size;
void* data = lovrFilesystemRead(path, &size);
if (!data) {
return luaL_error(L, "Could not load texture file '%s'", path);
}
TextureData* textureData = lovrTextureDataFromFile(data, size);
texture = lovrTextureCreate(textureData, 0);
free(data);
} else {
int width = luaL_checknumber(L, 1);
int height = luaL_checknumber(L, 2);
TextureData* textureData = lovrTextureDataGetEmpty(width, height);
texture = lovrTextureCreate(textureData, 1);
}
TextureData* textureData = lovrTextureDataFromFile(data, size);
texture = lovrTextureCreate(textureData);
free(data);
luax_pushtype(L, Texture, texture);
return 1;

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);
Texture* texture = lovrTextureCreate(textureData, 0);
lovrModelSetTexture(model, texture);
luax_pushtype(L, Model, model);
} else {

View File

@ -9,11 +9,18 @@ const luaL_Reg lovrTexture[] = {
{ "getHeight", l_lovrTextureGetHeight },
{ "getWidth", l_lovrTextureGetWidth },
{ "getWrap", l_lovrTextureGetWrap },
{ "renderTo", l_lovrTextureRenderTo },
{ "setFilter", l_lovrTextureSetFilter },
{ "setWrap", l_lovrTextureSetWrap },
{ 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) {
Texture* texture = luax_checktype(L, 1, Texture);
lovrTextureBind(texture);
@ -57,6 +64,13 @@ int l_lovrTextureGetWrap(lua_State* L) {
return 2;
}
int l_lovrTextureRenderTo(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
lua_settop(L, 2);
lovrTextureRenderTo(texture, renderHelper, L);
return 0;
}
int l_lovrTextureSetFilter(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
FilterMode* min = (FilterMode*) luax_checkenum(L, 2, &FilterModes, "filter mode");

View File

@ -10,5 +10,6 @@ int l_lovrTextureGetHeight(lua_State* L);
int l_lovrTextureGetFilter(lua_State* L);
int l_lovrTextureGetWidth(lua_State* L);
int l_lovrTextureGetWrap(lua_State* L);
int l_lovrTextureRenderTo(lua_State* L);
int l_lovrTextureSetFilter(lua_State* L);
int l_lovrTextureSetWrap(lua_State* L);