2016-09-27 07:24:28 +00:00
|
|
|
#define _USE_MATH_DEFINES
|
2016-07-07 07:04:24 +00:00
|
|
|
#include "graphics.h"
|
2016-07-09 05:27:34 +00:00
|
|
|
#include "model.h"
|
2016-07-16 05:39:17 +00:00
|
|
|
#include "buffer.h"
|
2016-07-16 02:17:27 +00:00
|
|
|
#include "shader.h"
|
2016-08-08 01:32:37 +00:00
|
|
|
#include "../glfw.h"
|
|
|
|
#include "../util.h"
|
2016-07-16 05:39:17 +00:00
|
|
|
#include <stdlib.h>
|
2016-09-27 07:24:28 +00:00
|
|
|
#include <math.h>
|
2016-07-07 07:04:24 +00:00
|
|
|
#include <assimp/cimport.h>
|
|
|
|
#include <assimp/scene.h>
|
|
|
|
#include <assimp/postprocess.h>
|
2016-09-14 00:02:23 +00:00
|
|
|
#include "../headset/headset.h"
|
|
|
|
|
2016-09-27 06:48:09 +00:00
|
|
|
static GraphicsState state;
|
2016-07-07 07:04:24 +00:00
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
void lovrGraphicsInit() {
|
2016-09-27 06:48:09 +00:00
|
|
|
vec_init(&state.transforms);
|
|
|
|
state.projection = mat4_init();
|
|
|
|
state.lastTransform = mat4_init();
|
|
|
|
state.lastProjection = mat4_init();
|
2016-09-29 02:34:48 +00:00
|
|
|
state.defaultShader = lovrGraphicsNewShader(lovrDefaultVertexShader, lovrDefaultFragmentShader);
|
2016-10-03 18:39:23 +00:00
|
|
|
state.lastColor = 0;
|
2016-09-29 07:00:02 +00:00
|
|
|
glGenBuffers(1, &state.shapeBuffer);
|
2016-09-30 06:18:51 +00:00
|
|
|
glGenBuffers(1, &state.shapeIndexBuffer);
|
2016-09-29 07:00:02 +00:00
|
|
|
glGenVertexArrays(1, &state.shapeArray);
|
|
|
|
vec_init(&state.shapeData);
|
2016-09-30 06:18:51 +00:00
|
|
|
vec_init(&state.shapeIndices);
|
2016-09-28 03:20:08 +00:00
|
|
|
lovrGraphicsReset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsReset() {
|
|
|
|
int i;
|
|
|
|
mat4 matrix;
|
|
|
|
|
|
|
|
vec_foreach(&state.transforms, matrix, i) {
|
|
|
|
mat4_deinit(matrix);
|
|
|
|
}
|
|
|
|
|
|
|
|
vec_clear(&state.transforms);
|
|
|
|
vec_push(&state.transforms, mat4_init());
|
|
|
|
|
|
|
|
memset(state.lastTransform, 0, 16);
|
|
|
|
memset(state.lastProjection, 0, 16);
|
|
|
|
|
2016-09-29 03:11:58 +00:00
|
|
|
lovrGraphicsSetProjection(.1f, 100.f, 67 * M_PI / 180); // TODO customize via lovr.conf
|
2016-09-28 02:56:36 +00:00
|
|
|
lovrGraphicsSetShader(state.defaultShader);
|
2016-09-29 03:11:58 +00:00
|
|
|
lovrGraphicsSetBackgroundColor(0, 0, 0, 0);
|
|
|
|
lovrGraphicsSetColor(255, 255, 255, 255);
|
2016-09-28 04:32:57 +00:00
|
|
|
lovrGraphicsSetColorMask(1, 1, 1, 1);
|
2016-09-29 04:47:36 +00:00
|
|
|
lovrGraphicsSetScissorEnabled(0);
|
2016-10-01 20:48:31 +00:00
|
|
|
lovrGraphicsSetLineWidth(1);
|
2016-08-10 06:28:17 +00:00
|
|
|
}
|
2016-07-07 07:04:24 +00:00
|
|
|
|
2016-09-17 03:11:11 +00:00
|
|
|
void lovrGraphicsClear(int color, int depth) {
|
|
|
|
int bits = 0;
|
|
|
|
|
|
|
|
if (color) {
|
|
|
|
bits |= GL_COLOR_BUFFER_BIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (depth) {
|
|
|
|
bits |= GL_DEPTH_BUFFER_BIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
glClear(bits);
|
2016-07-07 07:04:24 +00:00
|
|
|
}
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
void lovrGraphicsPresent() {
|
2016-07-07 07:04:24 +00:00
|
|
|
glfwSwapBuffers(window);
|
|
|
|
}
|
|
|
|
|
2016-09-24 03:58:56 +00:00
|
|
|
void lovrGraphicsPrepare() {
|
|
|
|
Shader* shader = lovrGraphicsGetShader();
|
|
|
|
|
|
|
|
if (!shader) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-27 06:48:09 +00:00
|
|
|
mat4 transform = vec_last(&state.transforms);
|
|
|
|
mat4 lastTransform = state.lastTransform;
|
2016-09-24 03:58:56 +00:00
|
|
|
|
2016-09-24 05:11:56 +00:00
|
|
|
if (memcmp(transform, lastTransform, 16 * sizeof(float))) {
|
|
|
|
int uniformId = lovrShaderGetUniformId(shader, "lovrTransform");
|
|
|
|
lovrShaderSendFloatMat4(shader, uniformId, transform);
|
|
|
|
memcpy(lastTransform, transform, 16 * sizeof(float));
|
2016-09-24 03:58:56 +00:00
|
|
|
}
|
|
|
|
|
2016-09-27 06:48:09 +00:00
|
|
|
mat4 projection = state.projection;
|
|
|
|
mat4 lastProjection = state.lastProjection;
|
2016-09-24 05:11:56 +00:00
|
|
|
|
|
|
|
if (memcmp(projection, lastProjection, 16 * sizeof(float))) {
|
|
|
|
int uniformId = lovrShaderGetUniformId(shader, "lovrProjection");
|
|
|
|
lovrShaderSendFloatMat4(shader, uniformId, projection);
|
|
|
|
memcpy(lastProjection, projection, 16 * sizeof(float));
|
|
|
|
}
|
2016-09-29 03:11:58 +00:00
|
|
|
|
|
|
|
if (state.lastColor != state.color) {
|
|
|
|
int uniformId = lovrShaderGetUniformId(shader, "lovrColor");
|
|
|
|
float color[4] = {
|
|
|
|
LOVR_COLOR_R(state.color) / 255.f,
|
|
|
|
LOVR_COLOR_G(state.color) / 255.f,
|
|
|
|
LOVR_COLOR_B(state.color) / 255.f,
|
|
|
|
LOVR_COLOR_A(state.color) / 255.f
|
|
|
|
};
|
|
|
|
lovrShaderSendFloatVec4(shader, uniformId, color);
|
|
|
|
state.lastColor = state.color;
|
|
|
|
}
|
2016-09-24 03:58:56 +00:00
|
|
|
}
|
|
|
|
|
2016-09-28 04:37:46 +00:00
|
|
|
void lovrGraphicsGetBackgroundColor(float* r, float* g, float* b, float* a) {
|
2016-07-28 02:48:59 +00:00
|
|
|
GLfloat clearColor[4];
|
|
|
|
glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
|
2016-08-10 06:28:17 +00:00
|
|
|
*r = clearColor[0];
|
|
|
|
*g = clearColor[1];
|
|
|
|
*b = clearColor[2];
|
|
|
|
*a = clearColor[3];
|
2016-07-28 02:48:59 +00:00
|
|
|
}
|
|
|
|
|
2016-09-28 04:37:46 +00:00
|
|
|
void lovrGraphicsSetBackgroundColor(float r, float g, float b, float a) {
|
2016-08-08 20:51:22 +00:00
|
|
|
glClearColor(r / 255, g / 255, b / 255, a / 255);
|
2016-07-28 02:48:59 +00:00
|
|
|
}
|
|
|
|
|
2016-09-29 03:11:58 +00:00
|
|
|
void lovrGraphicsGetColor(unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) {
|
|
|
|
*r = LOVR_COLOR_R(state.color);
|
|
|
|
*g = LOVR_COLOR_G(state.color);
|
|
|
|
*b = LOVR_COLOR_B(state.color);
|
|
|
|
*a = LOVR_COLOR_A(state.color);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsSetColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
|
|
|
|
state.color = LOVR_COLOR(r, g, b, a);
|
|
|
|
}
|
|
|
|
|
2016-10-03 18:41:31 +00:00
|
|
|
void lovrGraphicsGetColorMask(char* r, char* g, char* b, char* a) {
|
|
|
|
char mask = state.colorMask;
|
2016-09-28 04:32:57 +00:00
|
|
|
*r = mask & 0x1;
|
|
|
|
*g = mask & 0x2;
|
|
|
|
*b = mask & 0x4;
|
|
|
|
*a = mask & 0x8;
|
|
|
|
}
|
|
|
|
|
2016-10-03 18:41:31 +00:00
|
|
|
void lovrGraphicsSetColorMask(char r, char g, char b, char a) {
|
2016-09-28 04:32:57 +00:00
|
|
|
state.colorMask = ((r & 1) << 0) | ((g & 1) << 1) | ((b & 1) << 2) | ((a & 1) << 3);
|
|
|
|
glColorMask(r, g, b, a);
|
|
|
|
}
|
|
|
|
|
2016-09-29 04:47:36 +00:00
|
|
|
char lovrGraphicsIsScissorEnabled() {
|
|
|
|
return state.isScissorEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsSetScissorEnabled(char isEnabled) {
|
|
|
|
state.isScissorEnabled = isEnabled;
|
|
|
|
if (isEnabled) {
|
|
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
} else {
|
|
|
|
glDisable(GL_SCISSOR_TEST);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsGetScissor(int* x, int* y, int* width, int* height) {
|
|
|
|
*x = state.scissor.x;
|
|
|
|
*y = state.scissor.x;
|
|
|
|
*width = state.scissor.width;
|
|
|
|
*height = state.scissor.height;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsSetScissor(int x, int y, int width, int height) {
|
|
|
|
int windowWidth, windowHeight;
|
2016-09-29 05:09:57 +00:00
|
|
|
glfwGetFramebufferSize(window, &windowWidth, &windowHeight);
|
2016-09-29 04:47:36 +00:00
|
|
|
state.scissor.x = x;
|
|
|
|
state.scissor.x = y;
|
|
|
|
state.scissor.width = width;
|
|
|
|
state.scissor.height = height;
|
|
|
|
glScissor(x, windowHeight - y, width, height);
|
|
|
|
}
|
|
|
|
|
2016-09-14 00:02:23 +00:00
|
|
|
Shader* lovrGraphicsGetShader() {
|
2016-09-27 06:48:09 +00:00
|
|
|
return state.activeShader;
|
2016-09-14 00:02:23 +00:00
|
|
|
}
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
void lovrGraphicsSetShader(Shader* shader) {
|
2016-09-28 02:56:36 +00:00
|
|
|
if (!shader) {
|
|
|
|
shader = state.defaultShader;
|
|
|
|
}
|
|
|
|
|
2016-09-27 06:48:09 +00:00
|
|
|
state.activeShader = shader;
|
2016-08-03 04:24:18 +00:00
|
|
|
glUseProgram(shader->id);
|
2016-07-16 02:17:27 +00:00
|
|
|
}
|
|
|
|
|
2016-09-27 06:48:09 +00:00
|
|
|
void lovrGraphicsSetProjection(float near, float far, float fov) {
|
|
|
|
int width, height;
|
|
|
|
glfwGetWindowSize(window, &width, &height);
|
|
|
|
mat4_setProjection(state.projection, near, far, fov, (float) width / height);
|
2016-09-24 05:11:56 +00:00
|
|
|
}
|
|
|
|
|
2016-09-27 07:24:28 +00:00
|
|
|
void lovrGraphicsSetProjectionRaw(mat4 projection) {
|
|
|
|
memcpy(state.projection, projection, 16 * sizeof(float));
|
|
|
|
}
|
|
|
|
|
2016-10-01 20:48:31 +00:00
|
|
|
float lovrGraphicsGetLineWidth() {
|
|
|
|
return state.lineWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsSetLineWidth(float width) {
|
|
|
|
state.lineWidth = width;
|
|
|
|
glLineWidth(width);
|
|
|
|
}
|
|
|
|
|
2016-09-21 07:55:53 +00:00
|
|
|
int lovrGraphicsPush() {
|
2016-09-27 06:48:09 +00:00
|
|
|
vec_mat4_t* transforms = &state.transforms;
|
2016-09-21 22:26:05 +00:00
|
|
|
if (transforms->length >= 64) { return 1; }
|
|
|
|
vec_push(transforms, mat4_copy(vec_last(transforms)));
|
2016-09-21 07:55:53 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lovrGraphicsPop() {
|
2016-09-27 06:48:09 +00:00
|
|
|
vec_mat4_t* transforms = &state.transforms;
|
2016-09-21 22:26:05 +00:00
|
|
|
if (transforms->length <= 1) { return 1; }
|
2016-09-21 07:55:53 +00:00
|
|
|
mat4_deinit(vec_pop(transforms));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-21 22:26:05 +00:00
|
|
|
void lovrGraphicsOrigin() {
|
2016-09-27 06:48:09 +00:00
|
|
|
vec_mat4_t* transforms = &state.transforms;
|
2016-09-21 22:26:05 +00:00
|
|
|
mat4_setIdentity(vec_last(transforms));
|
|
|
|
}
|
|
|
|
|
2016-09-23 04:53:17 +00:00
|
|
|
void lovrGraphicsTranslate(float x, float y, float z) {
|
2016-09-27 06:48:09 +00:00
|
|
|
mat4_translate(vec_last(&state.transforms), x, y, z);
|
2016-09-23 04:53:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsRotate(float w, float x, float y, float z) {
|
2016-09-27 06:48:09 +00:00
|
|
|
mat4_rotate(vec_last(&state.transforms), w, x, y, z);
|
2016-09-23 04:53:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsScale(float x, float y, float z) {
|
2016-09-27 06:48:09 +00:00
|
|
|
mat4_scale(vec_last(&state.transforms), x, y, z);
|
2016-09-23 04:53:17 +00:00
|
|
|
}
|
|
|
|
|
2016-09-29 07:21:38 +00:00
|
|
|
void lovrGraphicsTransform(mat4 transform) {
|
|
|
|
mat4_multiply(vec_last(&state.transforms), transform);
|
|
|
|
}
|
|
|
|
|
2016-09-29 05:10:03 +00:00
|
|
|
void lovrGraphicsGetDimensions(int* width, int* height) {
|
|
|
|
glfwGetFramebufferSize(window, width, height);
|
|
|
|
}
|
|
|
|
|
2016-09-30 06:18:51 +00:00
|
|
|
void lovrGraphicsSetShapeData(float* vertexData, int vertexLength, unsigned int* indexData, int indexLength) {
|
2016-09-29 07:00:02 +00:00
|
|
|
vec_clear(&state.shapeData);
|
2016-09-30 06:18:51 +00:00
|
|
|
vec_pusharr(&state.shapeData, vertexData, vertexLength);
|
2016-09-29 07:00:02 +00:00
|
|
|
glBindVertexArray(state.shapeArray);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, state.shapeBuffer);
|
2016-09-30 06:18:51 +00:00
|
|
|
glBufferData(GL_ARRAY_BUFFER, vertexLength * sizeof(float), vertexData, GL_STREAM_DRAW);
|
2016-09-29 07:00:02 +00:00
|
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
|
2016-09-30 06:18:51 +00:00
|
|
|
|
|
|
|
vec_clear(&state.shapeIndices);
|
|
|
|
if (indexData) {
|
|
|
|
vec_pusharr(&state.shapeIndices, indexData, indexLength);
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state.shapeIndexBuffer);
|
|
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, state.shapeIndices.length * sizeof(unsigned int), state.shapeIndices.data, GL_STREAM_DRAW);
|
|
|
|
}
|
2016-09-29 07:00:02 +00:00
|
|
|
}
|
|
|
|
|
2016-10-01 19:10:38 +00:00
|
|
|
void lovrGraphicsDrawShape(GLenum mode) {
|
2016-09-30 06:18:51 +00:00
|
|
|
int usingIbo = state.shapeIndices.length > 0;
|
2016-09-29 07:00:02 +00:00
|
|
|
lovrGraphicsPrepare();
|
|
|
|
glBindVertexArray(state.shapeArray);
|
|
|
|
glEnableVertexAttribArray(0);
|
2016-09-30 06:18:51 +00:00
|
|
|
|
|
|
|
if (usingIbo) {
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state.shapeIndexBuffer);
|
|
|
|
glDrawElements(mode, state.shapeIndices.length, GL_UNSIGNED_INT, NULL);
|
|
|
|
} else {
|
|
|
|
glDrawArrays(mode, 0, state.shapeData.length / 3);
|
|
|
|
}
|
2016-09-30 02:39:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void lovrGraphicsLine(float* points, int count) {
|
2016-09-30 06:18:51 +00:00
|
|
|
lovrGraphicsSetShapeData(points, count, NULL, 0);
|
2016-10-01 19:10:38 +00:00
|
|
|
lovrGraphicsDrawShape(GL_LINE_STRIP);
|
2016-09-29 07:00:02 +00:00
|
|
|
}
|
|
|
|
|
2016-10-01 20:39:38 +00:00
|
|
|
void lovrGraphicsCube(DrawMode mode, float x, float y, float z, float size, float angle, float axisX, float axisY, float axisZ) {
|
2016-10-01 19:53:15 +00:00
|
|
|
float points[] = {
|
|
|
|
// Front
|
|
|
|
-.5, .5, -.5,
|
|
|
|
.5, .5, -.5,
|
|
|
|
.5, -.5, -.5,
|
|
|
|
-.5, -.5, -.5,
|
|
|
|
|
|
|
|
// Back
|
|
|
|
-.5, .5, .5,
|
|
|
|
.5, .5, .5,
|
|
|
|
.5, -.5, .5,
|
|
|
|
-.5, -.5, .5
|
|
|
|
};
|
|
|
|
|
2016-10-01 20:39:38 +00:00
|
|
|
float cos2 = cos(angle / 2);
|
|
|
|
float sin2 = sin(angle / 2);
|
|
|
|
float rw = cos2;
|
|
|
|
float rx = sin2 * axisX;
|
|
|
|
float ry = sin2 * axisY;
|
|
|
|
float rz = sin2 * axisZ;
|
|
|
|
|
2016-10-01 19:53:15 +00:00
|
|
|
float transform[16];
|
|
|
|
mat4_setTranslation(transform, x, y, z);
|
|
|
|
mat4_scale(transform, size, size, size);
|
2016-10-01 20:39:38 +00:00
|
|
|
mat4_rotate(transform, rw, rx, ry, rz);
|
2016-10-01 19:53:15 +00:00
|
|
|
lovrGraphicsPush();
|
|
|
|
lovrGraphicsTransform(transform);
|
2016-10-01 19:10:38 +00:00
|
|
|
|
2016-10-01 19:53:15 +00:00
|
|
|
if (mode == DRAW_MODE_LINE) {
|
2016-10-01 19:10:38 +00:00
|
|
|
unsigned int indices[] = {
|
2016-10-01 19:53:15 +00:00
|
|
|
0, 1, 1, 2, 2, 3, 3, 0, // Front
|
|
|
|
4, 5, 5, 6, 6, 7, 7, 4, // Back
|
2016-10-01 19:10:38 +00:00
|
|
|
0, 4, 1, 5, 2, 6, 3, 7 // Connections
|
|
|
|
};
|
|
|
|
|
|
|
|
lovrGraphicsSetShapeData(points, 24, indices, 24);
|
|
|
|
lovrGraphicsDrawShape(GL_LINES);
|
|
|
|
} else {
|
2016-10-01 19:53:15 +00:00
|
|
|
unsigned int indices[] = {
|
|
|
|
3, 2, 0, 1, // Front
|
|
|
|
1, 2, 5, 6, // Right
|
|
|
|
6, 7, 5, 4, // Back
|
|
|
|
4, 7, 0, 3, // Left
|
|
|
|
3, 7, 2, 6, // Bottom
|
|
|
|
6, 0,
|
|
|
|
0, 1, 4, 5 // Top
|
|
|
|
};
|
|
|
|
|
|
|
|
lovrGraphicsSetShapeData(points, 24, indices, 26);
|
|
|
|
lovrGraphicsDrawShape(GL_TRIANGLE_STRIP);
|
2016-10-01 19:10:38 +00:00
|
|
|
}
|
2016-10-01 19:53:15 +00:00
|
|
|
|
|
|
|
lovrGraphicsPop();
|
2016-09-30 06:18:51 +00:00
|
|
|
}
|
|
|
|
|
2016-09-17 22:38:13 +00:00
|
|
|
Buffer* lovrGraphicsNewBuffer(int size, BufferDrawMode drawMode, BufferUsage usage) {
|
2016-08-08 20:23:40 +00:00
|
|
|
Buffer* buffer = malloc(sizeof(Buffer));
|
2016-07-16 05:39:17 +00:00
|
|
|
|
2016-09-17 22:38:13 +00:00
|
|
|
buffer->drawMode = drawMode;
|
|
|
|
buffer->usage = usage;
|
2016-08-08 21:40:18 +00:00
|
|
|
buffer->size = size;
|
|
|
|
buffer->data = malloc(buffer->size * 3 * sizeof(GLfloat));
|
2016-09-18 00:52:52 +00:00
|
|
|
buffer->vao = 0;
|
|
|
|
buffer->vbo = 0;
|
|
|
|
buffer->ibo = 0;
|
|
|
|
buffer->isRangeEnabled = 0;
|
2016-08-09 01:27:35 +00:00
|
|
|
buffer->rangeStart = 0;
|
|
|
|
buffer->rangeCount = buffer->size;
|
2016-07-16 05:39:17 +00:00
|
|
|
|
2016-07-27 06:17:55 +00:00
|
|
|
glGenBuffers(1, &buffer->vbo);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, buffer->vbo);
|
2016-09-17 22:38:13 +00:00
|
|
|
glBufferData(GL_ARRAY_BUFFER, buffer->size * 3 * sizeof(GLfloat), buffer->data, buffer->usage);
|
2016-07-27 06:17:55 +00:00
|
|
|
|
|
|
|
glGenVertexArrays(1, &buffer->vao);
|
|
|
|
|
2016-09-18 00:52:52 +00:00
|
|
|
vec_init(&buffer->map);
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
return buffer;
|
2016-07-16 05:39:17 +00:00
|
|
|
}
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
Model* lovrGraphicsNewModel(const char* path) {
|
|
|
|
const struct aiScene* scene = aiImportFile(path, aiProcessPreset_TargetRealtime_MaxQuality);
|
2016-07-16 02:17:27 +00:00
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
if (scene) {
|
|
|
|
return scene->mMeshes[0];
|
2016-07-16 02:17:27 +00:00
|
|
|
}
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
return NULL;
|
2016-07-16 02:17:27 +00:00
|
|
|
}
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
Shader* lovrGraphicsNewShader(const char* vertexSource, const char* fragmentSource) {
|
2016-08-28 20:36:54 +00:00
|
|
|
char fullVertexSource[1024];
|
|
|
|
snprintf(fullVertexSource, sizeof(fullVertexSource), "%s\n%s", lovrShaderVertexPrefix, vertexSource);
|
|
|
|
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, fullVertexSource);
|
|
|
|
|
|
|
|
char fullFragmentSource[1024];
|
|
|
|
snprintf(fullFragmentSource, sizeof(fullFragmentSource), "%s\n%s", lovrShaderFragmentPrefix, fragmentSource);
|
|
|
|
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fullFragmentSource);
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
GLuint id = linkShaders(vertexShader, fragmentShader);
|
|
|
|
Shader* shader = (Shader*) malloc(sizeof(Shader));
|
|
|
|
shader->id = id;
|
|
|
|
return shader;
|
2016-08-01 00:21:04 +00:00
|
|
|
}
|