mirror of https://github.com/bjornbytes/lovr.git
Basic framebuffers;
This commit is contained in:
parent
2a8d40abd6
commit
1ad0ac557b
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue