Add default texture;

This commit is contained in:
bjorn 2016-11-26 18:58:58 -08:00
parent 8252be04ed
commit 9b0712bb66
12 changed files with 103 additions and 23 deletions

View File

@ -68,6 +68,7 @@ void lovrBufferDestroy(const Ref* ref) {
void lovrBufferDraw(Buffer* buffer) {
int usingIbo = buffer->map.length > 0;
lovrGraphicsSetTexture(buffer->texture);
lovrGraphicsPrepare();
glBindVertexArray(buffer->vao);
@ -101,13 +102,6 @@ void lovrBufferDraw(Buffer* buffer) {
}
}
// Set texture
if (buffer->texture) {
lovrTextureBind(buffer->texture);
} else {
glBindTexture(GL_TEXTURE_2D, 0);
}
// Determine range of vertices to be rendered and whether we're using an IBO or not
int start, count;
if (buffer->isRangeEnabled) {

View File

@ -17,23 +17,37 @@ void lovrGraphicsInit() {
state.projection = mat4_init();
state.defaultShader = lovrShaderCreate(lovrDefaultVertexShader, lovrDefaultFragmentShader);
state.skyboxShader = lovrShaderCreate(lovrSkyboxVertexShader, lovrSkyboxFragmentShader);
int uniformId = lovrShaderGetUniformId(state.skyboxShader, "cube");
lovrShaderSendInt(state.skyboxShader, uniformId, 1);
glGenBuffers(1, &state.shapeBuffer);
glGenBuffers(1, &state.shapeIndexBuffer);
glGenVertexArrays(1, &state.shapeArray);
vec_init(&state.shapeData);
vec_init(&state.shapeIndices);
state.depthTest = -1;
// Create default texture
TextureData* defaultTextureData = malloc(sizeof(TextureData));
defaultTextureData->width = 1;
defaultTextureData->height = 1;
uint8_t* data = malloc(4 * sizeof(uint8_t));
data[0] = data[1] = data[2] = data[3] = 0xff;
defaultTextureData->data = data;
state.defaultTexture = lovrTextureCreate(defaultTextureData);
state.lastTexture = NULL;
glActiveTexture(GL_TEXTURE0);
lovrGraphicsReset();
}
void lovrGraphicsDestroy() {
lovrGraphicsSetShader(NULL);
glUseProgram(0);
lovrRelease(&state.defaultShader->ref);
vec_deinit(&state.transforms);
mat4_deinit(state.projection);
lovrRelease(&state.defaultShader->ref);
lovrRelease(&state.skyboxShader->ref);
lovrRelease(&state.defaultTexture->ref);
glDeleteBuffers(1, &state.shapeBuffer);
glDeleteBuffers(1, &state.shapeIndexBuffer);
glDeleteVertexArrays(1, &state.shapeArray);
@ -54,6 +68,7 @@ void lovrGraphicsReset() {
lovrGraphicsSetProjection(.1f, 100.f, 67 * M_PI / 180); // TODO customize via lovr.conf
lovrGraphicsSetShader(state.defaultShader);
lovrGraphicsSetTexture(state.defaultTexture);
lovrGraphicsSetBackgroundColor(0, 0, 0, 0);
lovrGraphicsSetColor(255, 255, 255, 255);
lovrGraphicsSetColorMask(1, 1, 1, 1);
@ -87,6 +102,16 @@ void lovrGraphicsPresent() {
void lovrGraphicsPrepare() {
Shader* shader = lovrGraphicsGetShader();
lovrShaderBind(shader, vec_last(&state.transforms), state.projection, state.color, 0);
Texture* texture = lovrGraphicsGetTexture();
if (texture) {
if (texture != state.lastTexture) {
lovrTextureBind(texture);
state.lastTexture = texture;
}
} else {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
// State
@ -173,11 +198,29 @@ void lovrGraphicsSetShader(Shader* shader) {
}
state.activeShader = shader;
lovrRetain(&state.activeShader->ref);
}
}
Texture* lovrGraphicsGetTexture() {
return state.activeTexture;
}
void lovrGraphicsSetTexture(Texture* texture) {
if (!texture) {
texture = state.defaultTexture;
}
if (texture != state.activeTexture) {
if (state.activeTexture) {
lovrRelease(&state.activeTexture->ref);
}
state.activeTexture = texture;
lovrRetain(&state.activeTexture->ref);
}
}
void lovrGraphicsSetProjection(float near, float far, float fov) {
int width, height;
glfwGetWindowSize(window, &width, &height);
@ -603,7 +646,7 @@ void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float a
};
glDepthMask(GL_FALSE);
glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->texture);
lovrGraphicsSetShapeData(cube, 156, NULL, 0);
@ -612,6 +655,7 @@ void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float a
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glDepthMask(GL_TRUE);
glActiveTexture(GL_TEXTURE0);
lovrGraphicsSetShader(lastShader);
lovrRelease(&lastShader->ref);
lovrGraphicsPop();

View File

@ -2,6 +2,7 @@
#include "graphics/model.h"
#include "graphics/shader.h"
#include "graphics/skybox.h"
#include "graphics/texture.h"
#include "matrix.h"
#ifndef LOVR_GRAPHICS_TYPES
@ -38,6 +39,9 @@ typedef struct {
Shader* activeShader;
Shader* defaultShader;
Shader* skyboxShader;
Texture* activeTexture;
Texture* lastTexture;
Texture* defaultTexture;
vec_mat4_t transforms;
mat4 projection;
unsigned int color;
@ -80,6 +84,8 @@ void lovrGraphicsGetScissor(int* x, int* y, int* width, int* height);
void lovrGraphicsSetScissor(int x, int y, int width, int height);
Shader* lovrGraphicsGetShader();
void lovrGraphicsSetShader(Shader* shader);
Texture* lovrGraphicsGetTexture();
void lovrGraphicsSetTexture(Texture* texture);
void lovrGraphicsSetProjection(float near, float far, float fov);
void lovrGraphicsSetProjectionRaw(mat4 projection);
float lovrGraphicsGetLineWidth();

View File

@ -151,11 +151,6 @@ void lovrModelDataDestroy(ModelData* modelData) {
void lovrModelDraw(Model* model, float x, float y, float z, float size, float angle, float ax, float ay, float az) {
lovrGraphicsPush();
lovrGraphicsTransform(x, y, z, size, size, size, angle, ax, ay, az);
if (model->texture) {
lovrTextureBind(model->texture);
} else {
glBindTexture(GL_TEXTURE_2D, 0);
}
lovrBufferDraw(model->buffer);
lovrGraphicsPop();
}

View File

@ -6,26 +6,30 @@ const char* lovrShaderVertexPrefix = ""
"#version 150 \n"
"uniform mat4 lovrTransform; \n"
"uniform mat4 lovrProjection; \n"
"in vec3 lovrPosition;"
"in vec3 lovrNormal;"
"in vec2 lovrTexCoord;"
"in vec3 lovrPosition; \n"
"in vec3 lovrNormal; \n"
"in vec2 lovrTexCoord; \n"
"out vec2 texCoord; \n"
"";
const char* lovrShaderFragmentPrefix = ""
"#version 150 \n"
"uniform vec4 lovrColor; \n"
"out vec4 lovrFragColor;"
"uniform sampler2D lovrTexture; \n"
"in vec2 texCoord; \n"
"out vec4 lovrFragColor; \n"
"";
const char* lovrShaderVertexSuffix = ""
"void main() { \n"
" texCoord = lovrTexCoord; \n"
" gl_Position = position(lovrProjection, lovrTransform, vec4(lovrPosition, 1.0)); \n"
"}"
"";
const char* lovrShaderFragmentSuffix = ""
"void main() { \n"
" lovrFragColor = color(lovrColor); \n"
" lovrFragColor = color(lovrColor, lovrTexture, texCoord); \n"
"}"
"";
@ -36,8 +40,8 @@ const char* lovrDefaultVertexShader = ""
"";
const char* lovrDefaultFragmentShader = ""
"vec4 color(vec4 graphicsColor) { \n"
" return graphicsColor; \n"
"vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { \n"
" return graphicsColor * texture(image, uv); \n"
"}"
"";
@ -52,7 +56,7 @@ const char* lovrSkyboxVertexShader = ""
const char* lovrSkyboxFragmentShader = ""
"in vec3 texturePosition; \n"
"uniform samplerCube cube; \n"
"vec4 color(vec4 graphicsColor) { \n"
"vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { \n"
" return graphicsColor * texture(cube, texturePosition); \n"
"}"
"";
@ -228,6 +232,10 @@ int lovrShaderGetUniformType(Shader* shader, const char* name, GLenum* type, int
return 0;
}
void lovrShaderSendInt(Shader* shader, int id, int value) {
glUniform1i(id, value);
}
void lovrShaderSendFloat(Shader* shader, int id, float value) {
glUniform1f(id, value);
}

View File

@ -48,6 +48,7 @@ void lovrShaderBind(Shader* shader, mat4 transform, mat4 projection, unsigned in
int lovrShaderGetAttributeId(Shader* shader, const char* name);
int lovrShaderGetUniformId(Shader* shader, const char* name);
int lovrShaderGetUniformType(Shader* shader, const char* name, GLenum* type, int* count);
void lovrShaderSendInt(Shader* shader, int id, int value);
void lovrShaderSendFloat(Shader* shader, int id, float value);
void lovrShaderSendFloatVec2(Shader* shader, int id, float* vector);
void lovrShaderSendFloatVec3(Shader* shader, int id, float* vector);

View File

@ -28,6 +28,9 @@ ModelData* lovrModelDataFromFile(void* data, int size) {
ModelData* modelData = malloc(sizeof(ModelData));
if (!modelData) return NULL;
modelData->hasNormals = 0;
modelData->hasTexCoords = 0;
unsigned int flags = aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_OptimizeGraph | aiProcess_FlipUVs;
const struct aiScene* scene = aiImportFileFromMemory(data, size, flags, NULL);

View File

@ -3,6 +3,7 @@
const luaL_Reg lovrTimer[] = {
{ "getDelta", l_lovrTimerGetDelta },
{ "getFPS", l_lovrTimerGetFPS },
{ "getTime", l_lovrTimerGetTime },
{ "step", l_lovrTimerStep },
{ "sleep", l_lovrTimerSleep },
@ -21,6 +22,11 @@ int l_lovrTimerGetDelta(lua_State* L) {
return 1;
}
int l_lovrTimerGetFPS(lua_State* L) {
lua_pushnumber(L, lovrTimerGetFPS());
return 1;
}
int l_lovrTimerGetTime(lua_State* L) {
lua_pushnumber(L, lovrTimerGetTime());
return 1;

View File

@ -5,6 +5,7 @@
extern const luaL_Reg lovrTimer[];
int l_lovrTimerInit(lua_State* L);
int l_lovrTimerGetDelta(lua_State* L);
int l_lovrTimerGetFPS(lua_State* L);
int l_lovrTimerGetTime(lua_State* L);
int l_lovrTimerStep(lua_State* L);
int l_lovrTimerSleep(lua_State* L);

View File

@ -21,6 +21,10 @@ int l_lovrShaderSend(lua_State* L) {
float data[16];
switch (type) {
case GL_INT:
lovrShaderSendInt(shader, id, luaL_checkinteger(L, 3));
break;
case GL_FLOAT:
lovrShaderSendFloat(shader, id, luaL_checknumber(L, 3));
break;

View File

@ -5,6 +5,9 @@
static TimerState timerState;
void lovrTimerInit() {
timerState.frames = 0;
timerState.lastFpsUpdate = 0;
timerState.fps = 0;
lovrTimerStep();
}
@ -20,9 +23,20 @@ double lovrTimerStep() {
timerState.lastTime = timerState.time;
timerState.time = glfwGetTime();
timerState.dt = timerState.time - timerState.lastTime;
timerState.frames++;
double fpsTimer = timerState.time - timerState.lastFpsUpdate;
if (fpsTimer > 1) {
timerState.fps = (int) timerState.frames / fpsTimer + .5;
timerState.lastFpsUpdate = timerState.time;
timerState.frames = 0;
}
return timerState.dt;
}
int lovrTimerGetFPS() {
return timerState.fps;
}
void lovrTimerSleep(double seconds) {
lovrSleep(seconds);
}

View File

@ -3,6 +3,9 @@ typedef struct {
double lastTime;
double time;
double dt;
int frames;
int fps;
double lastFpsUpdate;
} TimerState;
#endif
@ -10,4 +13,5 @@ void lovrTimerInit();
double lovrTimerGetDelta();
double lovrTimerGetTime();
double lovrTimerStep();
int lovrTimerGetFPS();
void lovrTimerSleep(double seconds);