mirror of https://gitlab.com/nakst/essence
cleanup gl test
This commit is contained in:
parent
5bd78070c3
commit
22185bfe22
|
@ -1,8 +0,0 @@
|
||||||
[general]
|
|
||||||
name=GL Test
|
|
||||||
permission_posix_subsystem=1
|
|
||||||
permission_all_files=1
|
|
||||||
|
|
||||||
[build]
|
|
||||||
custom_compile_command=x86_64-essence-gcc -o "bin/GL Test" apps/gl_test.c -lOSMesa -lstdc++ -lz -g -D ESSENCE_WINDOW -Wall -Wextra
|
|
||||||
require=root/Applications/POSIX/lib/libOSMesa.a
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <GL/osmesa.h>
|
#include <GL/osmesa.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
@ -11,7 +12,6 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define MODERN_GL
|
#define MODERN_GL
|
||||||
#define LIVE_UPDATE
|
|
||||||
|
|
||||||
#define CHECK_ERRORS() do { GLenum error; while ((error = glGetError()) != GL_NO_ERROR) { EsPrint("Error on line %d: %d\n", __LINE__, error); } } while (0)
|
#define CHECK_ERRORS() do { GLenum error; while ((error = glGetError()) != GL_NO_ERROR) { EsPrint("Error on line %d: %d\n", __LINE__, error); } } while (0)
|
||||||
|
|
||||||
|
@ -19,6 +19,9 @@
|
||||||
#define IMAGE_HEIGHT (600)
|
#define IMAGE_HEIGHT (600)
|
||||||
uint32_t *buffer;
|
uint32_t *buffer;
|
||||||
|
|
||||||
|
uint32_t modelVBO, modelIBO;
|
||||||
|
bool loadedModel;
|
||||||
|
|
||||||
#ifdef MODERN_GL
|
#ifdef MODERN_GL
|
||||||
static GLenum (*glCheckFramebufferStatus)(GLenum target);
|
static GLenum (*glCheckFramebufferStatus)(GLenum target);
|
||||||
static GLint (*glGetUniformLocation)(GLuint program, const GLchar *name);
|
static GLint (*glGetUniformLocation)(GLuint program, const GLchar *name);
|
||||||
|
@ -115,6 +118,10 @@ void PrepareNormalTransform(float *_modelTransform, float *_normalTransform) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Render() {
|
void Render() {
|
||||||
|
if (!loadedModel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
#ifdef MODERN_GL
|
#ifdef MODERN_GL
|
||||||
|
@ -146,14 +153,11 @@ void Render() {
|
||||||
glFinish();
|
glFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESSENCE_WINDOW
|
|
||||||
#include <essence.h>
|
#include <essence.h>
|
||||||
|
|
||||||
int CanvasCallback(EsElement *element, EsMessage *message) {
|
int CanvasCallback(EsElement *element, EsMessage *message) {
|
||||||
if (message->type == ES_MSG_PAINT_BACKGROUND) {
|
if (message->type == ES_MSG_PAINT_BACKGROUND) {
|
||||||
#ifdef LIVE_UPDATE
|
|
||||||
Render();
|
Render();
|
||||||
#endif
|
|
||||||
EsRectangle bounds = EsPainterBoundsInset(message->painter);
|
EsRectangle bounds = EsPainterBoundsInset(message->painter);
|
||||||
EsRectangle imageBounds = EsRectangleCenter(bounds, ES_RECT_2S(IMAGE_WIDTH, IMAGE_HEIGHT));
|
EsRectangle imageBounds = EsRectangleCenter(bounds, ES_RECT_2S(IMAGE_WIDTH, IMAGE_HEIGHT));
|
||||||
EsDrawBitmap(message->painter, imageBounds, buffer, IMAGE_WIDTH * 4, ES_DRAW_BITMAP_OPAQUE);
|
EsDrawBitmap(message->painter, imageBounds, buffer, IMAGE_WIDTH * 4, ES_DRAW_BITMAP_OPAQUE);
|
||||||
|
@ -182,7 +186,105 @@ int CanvasCallback(EsElement *element, EsMessage *message) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
bool LoadModel(char *model, size_t modelBytes) {
|
||||||
|
triangleCount = 0, vertexCount = 0;
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < modelBytes; i++) {
|
||||||
|
if (!i || model[i - 1] == '\n') {
|
||||||
|
if (model[i] == 'f' && model[i + 1] == ' ') {
|
||||||
|
triangleCount++;
|
||||||
|
} else if (model[i] == 'v' && model[i + 1] == ' ') {
|
||||||
|
vertexCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float *modelVBOArray = (float *) EsHeapAllocate(6 * sizeof(float) * vertexCount, true, NULL);
|
||||||
|
uint32_t *modelIBOArray = (uint32_t *) EsHeapAllocate(3 * sizeof(uint32_t) * triangleCount, true, NULL);
|
||||||
|
uintptr_t triangleIndex = 0, vertexIndex = 0;
|
||||||
|
|
||||||
|
float minimumX = ES_INFINITY, maximumX = -ES_INFINITY;
|
||||||
|
float minimumY = ES_INFINITY, maximumY = -ES_INFINITY;
|
||||||
|
float minimumZ = ES_INFINITY, maximumZ = -ES_INFINITY;
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < modelBytes; i++) {
|
||||||
|
if (!i || model[i - 1] == '\n') {
|
||||||
|
if (model[i] == 'v' && model[i + 1] == ' ') {
|
||||||
|
char *position = model + i + 2;
|
||||||
|
modelVBOArray[6 * vertexIndex + 0] = strtod(position, &position);
|
||||||
|
modelVBOArray[6 * vertexIndex + 1] = strtod(position, &position);
|
||||||
|
modelVBOArray[6 * vertexIndex + 2] = strtod(position, &position);
|
||||||
|
minimumX = modelVBOArray[6 * vertexIndex + 0] < minimumX ? modelVBOArray[6 * vertexIndex + 0] : minimumX;
|
||||||
|
minimumY = modelVBOArray[6 * vertexIndex + 1] < minimumY ? modelVBOArray[6 * vertexIndex + 1] : minimumY;
|
||||||
|
minimumZ = modelVBOArray[6 * vertexIndex + 2] < minimumZ ? modelVBOArray[6 * vertexIndex + 2] : minimumZ;
|
||||||
|
maximumX = modelVBOArray[6 * vertexIndex + 0] > maximumX ? modelVBOArray[6 * vertexIndex + 0] : maximumX;
|
||||||
|
maximumY = modelVBOArray[6 * vertexIndex + 1] > maximumY ? modelVBOArray[6 * vertexIndex + 1] : maximumY;
|
||||||
|
maximumZ = modelVBOArray[6 * vertexIndex + 2] > maximumZ ? modelVBOArray[6 * vertexIndex + 2] : maximumZ;
|
||||||
|
vertexIndex++;
|
||||||
|
} else if (model[i] == 'f' && model[i + 1] == ' ') {
|
||||||
|
char *position = model + i + 2;
|
||||||
|
uint32_t i0 = strtoul(position, &position, 10) - 1;
|
||||||
|
uint32_t i1 = strtoul(position, &position, 10) - 1;
|
||||||
|
uint32_t i2 = strtoul(position, &position, 10) - 1;
|
||||||
|
if (i0 >= vertexCount) return false;
|
||||||
|
if (i1 >= vertexCount) return false;
|
||||||
|
if (i2 >= vertexCount) return false;
|
||||||
|
modelIBOArray[3 * triangleIndex + 0] = i0;
|
||||||
|
modelIBOArray[3 * triangleIndex + 1] = i1;
|
||||||
|
modelIBOArray[3 * triangleIndex + 2] = i2;
|
||||||
|
triangleIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EsPrint("Model bounds: %F -> %F, %F -> %F, %F -> %F\n", minimumX, maximumX, minimumY, maximumY, minimumZ, maximumZ);
|
||||||
|
EsAssert(vertexIndex == vertexCount);
|
||||||
|
EsAssert(triangleIndex == triangleCount);
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < triangleCount; i++) {
|
||||||
|
// Calculate the normals as a weighted average of the face normals,
|
||||||
|
// where the weight is the surface area of the face.
|
||||||
|
|
||||||
|
float d1x = modelVBOArray[6 * modelIBOArray[3 * i + 1] + 0] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 0];
|
||||||
|
float d1y = modelVBOArray[6 * modelIBOArray[3 * i + 1] + 1] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 1];
|
||||||
|
float d1z = modelVBOArray[6 * modelIBOArray[3 * i + 1] + 2] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 2];
|
||||||
|
float d2x = modelVBOArray[6 * modelIBOArray[3 * i + 2] + 0] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 0];
|
||||||
|
float d2y = modelVBOArray[6 * modelIBOArray[3 * i + 2] + 1] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 1];
|
||||||
|
float d2z = modelVBOArray[6 * modelIBOArray[3 * i + 2] + 2] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 2];
|
||||||
|
float nx = d1y * d2z - d1z * d2y;
|
||||||
|
float ny = d1z * d2x - d1x * d2z;
|
||||||
|
float nz = d1x * d2y - d1y * d2x;
|
||||||
|
|
||||||
|
for (uintptr_t j = 0; j < 3; j++) {
|
||||||
|
modelVBOArray[6 * modelIBOArray[3 * i + j] + 3] += nx;
|
||||||
|
modelVBOArray[6 * modelIBOArray[3 * i + j] + 4] += ny;
|
||||||
|
modelVBOArray[6 * modelIBOArray[3 * i + j] + 5] += nz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < vertexCount; i++) {
|
||||||
|
// Normalize the normals.
|
||||||
|
|
||||||
|
float x = modelVBOArray[6 * i + 3];
|
||||||
|
float y = modelVBOArray[6 * i + 4];
|
||||||
|
float z = modelVBOArray[6 * i + 5];
|
||||||
|
float d = sqrtf(x * x + y * y + z * z);
|
||||||
|
modelVBOArray[6 * i + 3] /= d;
|
||||||
|
modelVBOArray[6 * i + 4] /= d;
|
||||||
|
modelVBOArray[6 * i + 5] /= d;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, modelVBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float) * vertexCount, modelVBOArray, GL_STATIC_DRAW);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelIBO);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(uint32_t) * triangleCount, modelIBOArray, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
EsHeapFree(modelVBOArray, 0, NULL);
|
||||||
|
EsHeapFree(modelIBOArray, 0, NULL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
(void) argc;
|
(void) argc;
|
||||||
|
@ -244,116 +346,8 @@ int main(int argc, char **argv) {
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
#if 0
|
|
||||||
triangleCount = 2, vertexCount = 4;
|
|
||||||
uint32_t modelIBOArray[] = { 0, 1, 2, 0, 2, 3 };
|
|
||||||
|
|
||||||
float modelVBOArray[] = {
|
|
||||||
-1, -1, 0.5f, 0, 0, 0,
|
|
||||||
-1, 1, 0.5f, 0, 0, 0,
|
|
||||||
1, 1, 0.5f, 0, 0, 0,
|
|
||||||
1, -1, 0.5f, 0, 0, 0,
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
// TODO Loading files properly.
|
|
||||||
size_t modelBytes;
|
|
||||||
char *model = (char *) EsFileReadAll(EsLiteral("0:/teapot.obj"), &modelBytes, NULL);
|
|
||||||
|
|
||||||
triangleCount = 0, vertexCount = 0;
|
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < modelBytes; i++) {
|
|
||||||
if (!i || model[i - 1] == '\n') {
|
|
||||||
if (model[i] == 'f' && model[i + 1] == ' ') {
|
|
||||||
triangleCount++;
|
|
||||||
} else if (model[i] == 'v' && model[i + 1] == ' ') {
|
|
||||||
vertexCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float *modelVBOArray = (float *) EsHeapAllocate(6 * sizeof(float) * vertexCount, true, NULL);
|
|
||||||
uint32_t *modelIBOArray = (uint32_t *) EsHeapAllocate(3 * sizeof(uint32_t) * triangleCount, true, NULL);
|
|
||||||
uintptr_t triangleIndex = 0, vertexIndex = 0;
|
|
||||||
|
|
||||||
float minimumX = ES_INFINITY, maximumX = -ES_INFINITY;
|
|
||||||
float minimumY = ES_INFINITY, maximumY = -ES_INFINITY;
|
|
||||||
float minimumZ = ES_INFINITY, maximumZ = -ES_INFINITY;
|
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < modelBytes; i++) {
|
|
||||||
if (!i || model[i - 1] == '\n') {
|
|
||||||
if (model[i] == 'v' && model[i + 1] == ' ') {
|
|
||||||
char *position = model + i + 2;
|
|
||||||
modelVBOArray[6 * vertexIndex + 0] = strtod(position, &position);
|
|
||||||
modelVBOArray[6 * vertexIndex + 1] = strtod(position, &position);
|
|
||||||
modelVBOArray[6 * vertexIndex + 2] = strtod(position, &position);
|
|
||||||
minimumX = modelVBOArray[6 * vertexIndex + 0] < minimumX ? modelVBOArray[6 * vertexIndex + 0] : minimumX;
|
|
||||||
minimumY = modelVBOArray[6 * vertexIndex + 1] < minimumY ? modelVBOArray[6 * vertexIndex + 1] : minimumY;
|
|
||||||
minimumZ = modelVBOArray[6 * vertexIndex + 2] < minimumZ ? modelVBOArray[6 * vertexIndex + 2] : minimumZ;
|
|
||||||
maximumX = modelVBOArray[6 * vertexIndex + 0] > maximumX ? modelVBOArray[6 * vertexIndex + 0] : maximumX;
|
|
||||||
maximumY = modelVBOArray[6 * vertexIndex + 1] > maximumY ? modelVBOArray[6 * vertexIndex + 1] : maximumY;
|
|
||||||
maximumZ = modelVBOArray[6 * vertexIndex + 2] > maximumZ ? modelVBOArray[6 * vertexIndex + 2] : maximumZ;
|
|
||||||
vertexIndex++;
|
|
||||||
} else if (model[i] == 'f' && model[i + 1] == ' ') {
|
|
||||||
char *position = model + i + 2;
|
|
||||||
uint32_t i0 = strtoul(position, &position, 10) - 1;
|
|
||||||
uint32_t i1 = strtoul(position, &position, 10) - 1;
|
|
||||||
uint32_t i2 = strtoul(position, &position, 10) - 1;
|
|
||||||
EsAssert(i0 < vertexCount); // TODO Error reporting.
|
|
||||||
EsAssert(i1 < vertexCount);
|
|
||||||
EsAssert(i2 < vertexCount);
|
|
||||||
modelIBOArray[3 * triangleIndex + 0] = i0;
|
|
||||||
modelIBOArray[3 * triangleIndex + 1] = i1;
|
|
||||||
modelIBOArray[3 * triangleIndex + 2] = i2;
|
|
||||||
triangleIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EsPrint("Model bounds: %F -> %F, %F -> %F, %F -> %F\n", minimumX, maximumX, minimumY, maximumY, minimumZ, maximumZ);
|
|
||||||
EsAssert(vertexIndex == vertexCount);
|
|
||||||
EsAssert(triangleIndex == triangleCount);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < triangleCount; i++) {
|
|
||||||
// Calculate the normals as a weighted average of the face normals,
|
|
||||||
// where the weight is the surface area of the face.
|
|
||||||
|
|
||||||
float d1x = modelVBOArray[6 * modelIBOArray[3 * i + 1] + 0] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 0];
|
|
||||||
float d1y = modelVBOArray[6 * modelIBOArray[3 * i + 1] + 1] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 1];
|
|
||||||
float d1z = modelVBOArray[6 * modelIBOArray[3 * i + 1] + 2] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 2];
|
|
||||||
float d2x = modelVBOArray[6 * modelIBOArray[3 * i + 2] + 0] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 0];
|
|
||||||
float d2y = modelVBOArray[6 * modelIBOArray[3 * i + 2] + 1] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 1];
|
|
||||||
float d2z = modelVBOArray[6 * modelIBOArray[3 * i + 2] + 2] - modelVBOArray[6 * modelIBOArray[3 * i + 0] + 2];
|
|
||||||
float nx = d1y * d2z - d1z * d2y;
|
|
||||||
float ny = d1z * d2x - d1x * d2z;
|
|
||||||
float nz = d1x * d2y - d1y * d2x;
|
|
||||||
|
|
||||||
for (uintptr_t j = 0; j < 3; j++) {
|
|
||||||
modelVBOArray[6 * modelIBOArray[3 * i + j] + 3] += nx;
|
|
||||||
modelVBOArray[6 * modelIBOArray[3 * i + j] + 4] += ny;
|
|
||||||
modelVBOArray[6 * modelIBOArray[3 * i + j] + 5] += nz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < vertexCount; i++) {
|
|
||||||
// Normalize the normals.
|
|
||||||
|
|
||||||
float x = modelVBOArray[6 * i + 3];
|
|
||||||
float y = modelVBOArray[6 * i + 4];
|
|
||||||
float z = modelVBOArray[6 * i + 5];
|
|
||||||
float d = sqrtf(x * x + y * y + z * z);
|
|
||||||
modelVBOArray[6 * i + 3] /= d;
|
|
||||||
modelVBOArray[6 * i + 4] /= d;
|
|
||||||
modelVBOArray[6 * i + 5] /= d;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t modelVBO, modelIBO;
|
|
||||||
glGenBuffers(1, &modelVBO);
|
glGenBuffers(1, &modelVBO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, modelVBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float) * vertexCount, modelVBOArray, GL_STATIC_DRAW);
|
|
||||||
glGenBuffers(1, &modelIBO);
|
glGenBuffers(1, &modelIBO);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelIBO);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(uint32_t) * triangleCount, modelIBOArray, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
const char *vertexShaderSource =
|
const char *vertexShaderSource =
|
||||||
"#version 330\n"
|
"#version 330\n"
|
||||||
|
@ -390,14 +384,14 @@ int main(int argc, char **argv) {
|
||||||
glCompileShader(vertexShader);
|
glCompileShader(vertexShader);
|
||||||
glGetShaderInfoLog(vertexShader, sizeof(shaderInfoLog), NULL, shaderInfoLog);
|
glGetShaderInfoLog(vertexShader, sizeof(shaderInfoLog), NULL, shaderInfoLog);
|
||||||
glAttachShader(shader, vertexShader);
|
glAttachShader(shader, vertexShader);
|
||||||
printf("Vertex shader log: '%s'\n", shaderInfoLog);
|
EsPrint("Vertex shader log: '%z'\n", shaderInfoLog);
|
||||||
|
|
||||||
unsigned fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
unsigned fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
glShaderSource(fragmentShader, 1, shaderSources + 1, shaderSourceLengths + 1);
|
glShaderSource(fragmentShader, 1, shaderSources + 1, shaderSourceLengths + 1);
|
||||||
glCompileShader(fragmentShader);
|
glCompileShader(fragmentShader);
|
||||||
glGetShaderInfoLog(fragmentShader, sizeof(shaderInfoLog), NULL, shaderInfoLog);
|
glGetShaderInfoLog(fragmentShader, sizeof(shaderInfoLog), NULL, shaderInfoLog);
|
||||||
glAttachShader(shader, fragmentShader);
|
glAttachShader(shader, fragmentShader);
|
||||||
printf("Fragment shader log: '%s'\n", shaderInfoLog);
|
EsPrint("Fragment shader log: '%z'\n", shaderInfoLog);
|
||||||
|
|
||||||
glLinkProgram(shader);
|
glLinkProgram(shader);
|
||||||
glValidateProgram(shader);
|
glValidateProgram(shader);
|
||||||
|
@ -423,39 +417,25 @@ int main(int argc, char **argv) {
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ESSENCE_WINDOW
|
|
||||||
FILE *out = fopen("test.ppm", "wb");
|
|
||||||
fprintf(out, "P6\n%d %d\n255\n", IMAGE_WIDTH, IMAGE_HEIGHT);
|
|
||||||
|
|
||||||
for (int j = 0; j < IMAGE_HEIGHT; j++) {
|
|
||||||
for (int i = 0; i < IMAGE_WIDTH; i++) {
|
|
||||||
fwrite(buffer + j * IMAGE_WIDTH + i, 1, 3, out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(out);
|
|
||||||
OSMesaDestroyContext(context);
|
|
||||||
free(buffer);
|
|
||||||
#else
|
|
||||||
while (true) {
|
while (true) {
|
||||||
EsMessage *message = EsMessageReceive();
|
EsMessage *message = EsMessageReceive();
|
||||||
|
|
||||||
if (message->type == ES_MSG_INSTANCE_CREATE) {
|
if (message->type == ES_MSG_INSTANCE_CREATE) {
|
||||||
EsInstance *instance = EsInstanceCreate(message, "GL Test", -1);
|
EsInstance *instance = EsInstanceCreate(message, "Object Viewer", -1);
|
||||||
EsWindowSetTitle(instance->window, "GL Test", -1);
|
EsWindowSetIcon(instance->window, ES_ICON_MODEL);
|
||||||
EsElement *canvas = EsCustomElementCreate(instance->window, ES_CELL_FILL, 0);
|
EsElement *canvas = EsCustomElementCreate(instance->window, ES_CELL_FILL, 0);
|
||||||
canvas->messageUser = (EsUICallback) CanvasCallback;
|
canvas->messageUser = (EsUICallback) CanvasCallback;
|
||||||
#ifdef LIVE_UPDATE
|
|
||||||
EsElementStartAnimating(canvas);
|
EsElementStartAnimating(canvas);
|
||||||
#else
|
} else if (message->type == ES_MSG_INSTANCE_OPEN) {
|
||||||
Render();
|
size_t modelBytes;
|
||||||
#endif
|
void *model = EsFileStoreReadAll(message->instanceOpen.file, &modelBytes);
|
||||||
|
EsInstanceOpenComplete(message, LoadModel(model, modelBytes), NULL, 0);
|
||||||
|
EsHeapFree(model, 0, NULL);
|
||||||
|
loadedModel = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
[general]
|
||||||
|
name=Object Viewer
|
||||||
|
permission_posix_subsystem=1
|
||||||
|
icon=icon_model
|
||||||
|
|
||||||
|
[build]
|
||||||
|
link_flags=-lOSMesa -lstdc++ -lz
|
||||||
|
with_cstdlib=1
|
||||||
|
source=ports/mesa/obj_viewer.c
|
||||||
|
|
||||||
|
[@handler]
|
||||||
|
extension=obj
|
||||||
|
action=open
|
||||||
|
|
||||||
|
[@file_type]
|
||||||
|
extension=obj
|
||||||
|
name=3D model
|
||||||
|
icon=icon_model
|
|
@ -162,10 +162,10 @@ void OutputStartOfBuildINI(FILE *f, bool forceDebugBuildOff) {
|
||||||
"convert_svg=bin/render_svg\n"
|
"convert_svg=bin/render_svg\n"
|
||||||
"linker_scripts=util/\n"
|
"linker_scripts=util/\n"
|
||||||
"crt_objects=bin/\n"
|
"crt_objects=bin/\n"
|
||||||
"\n[general]\nsystem_build=1\nminimal_rebuild=1\ncolored_output=%d\nthread_count=%d\nskip_header_generation=1\ncommon_compile_flags=",
|
"\n[general]\nsystem_build=1\nminimal_rebuild=1\ncolored_output=%d\nthread_count=%d\nskip_header_generation=1\nverbose=%d\ncommon_compile_flags=",
|
||||||
compilerPath, getenv("TMPDIR") ?: "",
|
compilerPath, getenv("TMPDIR") ?: "",
|
||||||
compilerPath, compilerPath, compilerPath, compilerPath, compilerPath, compilerPath,
|
compilerPath, compilerPath, compilerPath, compilerPath, compilerPath, compilerPath,
|
||||||
buffer, coloredOutput, (int) sysconf(_SC_NPROCESSORS_CONF));
|
buffer, coloredOutput, (int) sysconf(_SC_NPROCESSORS_CONF), IsOptionEnabled("BuildCore.Verbose"));
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
|
for (uintptr_t i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
|
||||||
Option *option = &options[i];
|
Option *option = &options[i];
|
||||||
|
|
|
@ -306,6 +306,7 @@ Option options[] = {
|
||||||
{ "Emulator.SecondaryDriveMB", OPTION_TYPE_STRING, { .s = NULL } },
|
{ "Emulator.SecondaryDriveMB", OPTION_TYPE_STRING, { .s = NULL } },
|
||||||
{ "Emulator.VBoxEFI", OPTION_TYPE_BOOL, { .b = false } },
|
{ "Emulator.VBoxEFI", OPTION_TYPE_BOOL, { .b = false } },
|
||||||
{ "Emulator.QemuEFI", OPTION_TYPE_BOOL, { .b = false } },
|
{ "Emulator.QemuEFI", OPTION_TYPE_BOOL, { .b = false } },
|
||||||
|
{ "BuildCore.Verbose", OPTION_TYPE_BOOL, { .b = false } },
|
||||||
{ "General.first_application", OPTION_TYPE_STRING, { .s = NULL } },
|
{ "General.first_application", OPTION_TYPE_STRING, { .s = NULL } },
|
||||||
{ "General.wallpaper", OPTION_TYPE_STRING, { .s = NULL } },
|
{ "General.wallpaper", OPTION_TYPE_STRING, { .s = NULL } },
|
||||||
{ "General.installation_state", OPTION_TYPE_STRING, { .s = "0" } },
|
{ "General.installation_state", OPTION_TYPE_STRING, { .s = "0" } },
|
||||||
|
|
|
@ -139,8 +139,9 @@ File FileOpen(const char *path, char mode) {
|
||||||
|
|
||||||
// Toolchain flags:
|
// Toolchain flags:
|
||||||
|
|
||||||
char commonCompileFlags[4096] = " -Wall -Wextra -Wno-missing-field-initializers -Wno-frame-address "
|
const char *commonCompileFlagsFreestanding = " -ffreestanding -fno-exceptions ";
|
||||||
"-Wno-unused-function -Wno-format-truncation -ffreestanding -fno-exceptions -g -I. ";
|
char commonCompileFlags[4096] = " -Wall -Wextra -Wno-missing-field-initializers -Wno-frame-address -Wno-unused-function -Wno-format-truncation -g -I. ";
|
||||||
|
char commonCompileFlagsWithCStdLib[4096];
|
||||||
char cCompileFlags[4096] = "";
|
char cCompileFlags[4096] = "";
|
||||||
char cppCompileFlags[4096] = " -std=c++14 -Wno-pmf-conversions -Wno-invalid-offsetof -fno-rtti ";
|
char cppCompileFlags[4096] = " -std=c++14 -Wno-pmf-conversions -Wno-invalid-offsetof -fno-rtti ";
|
||||||
char kernelCompileFlags[4096] = " -mno-red-zone -mcmodel=kernel -fno-omit-frame-pointer ";
|
char kernelCompileFlags[4096] = " -mno-red-zone -mcmodel=kernel -fno-omit-frame-pointer ";
|
||||||
|
@ -523,7 +524,7 @@ typedef struct Application {
|
||||||
FileType *fileTypes;
|
FileType *fileTypes;
|
||||||
Handler *handlers;
|
Handler *handlers;
|
||||||
|
|
||||||
bool install, builtin;
|
bool install, builtin, withCStdLib;
|
||||||
|
|
||||||
const char **sources;
|
const char **sources;
|
||||||
const char *compileFlags;
|
const char *compileFlags;
|
||||||
|
@ -619,21 +620,26 @@ void BuildApplication(Application *application) {
|
||||||
snprintf(objectFile, sizeof(objectFile), "bin/%s_%d.o", application->name, (int) i);
|
snprintf(objectFile, sizeof(objectFile), "bin/%s_%d.o", application->name, (int) i);
|
||||||
objectFilesPosition += sprintf(objectFiles + objectFilesPosition, "\"%s\" ", objectFile);
|
objectFilesPosition += sprintf(objectFiles + objectFilesPosition, "\"%s\" ", objectFile);
|
||||||
|
|
||||||
if (sourceBytes > 2 && source[sourceBytes - 1] == 'c' && source[sourceBytes - 2] == '.') {
|
bool isC = sourceBytes > 2 && source[sourceBytes - 1] == 'c' && source[sourceBytes - 2] == '.';
|
||||||
ExecuteForApp(application, toolchainCC, "-MD", "-o", objectFile, "-c", source,
|
const char *cstdlibFlags = application->withCStdLib ? commonCompileFlagsWithCStdLib : commonCompileFlags;
|
||||||
ArgString(cCompileFlags), ArgString(commonCompileFlags), ArgString(application->compileFlags));
|
const char *languageFlags = isC ? cCompileFlags : cppCompileFlags;
|
||||||
} else {
|
const char *compiler = isC ? toolchainCC : toolchainCXX;
|
||||||
ExecuteForApp(application, toolchainCXX, "-MD", "-o", objectFile, "-c", source,
|
|
||||||
ArgString(cppCompileFlags), ArgString(commonCompileFlags), ArgString(application->compileFlags));
|
ExecuteForApp(application, compiler, "-MD", "-o", objectFile, "-c", source,
|
||||||
}
|
ArgString(languageFlags), ArgString(application->compileFlags), ArgString(cstdlibFlags));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(objectFilesPosition < sizeof(objectFiles));
|
assert(objectFilesPosition < sizeof(objectFiles));
|
||||||
objectFiles[objectFilesPosition] = 0;
|
objectFiles[objectFilesPosition] = 0;
|
||||||
|
|
||||||
ExecuteForApp(application, toolchainCC, "-o", symbolFile,
|
if (application->withCStdLib) {
|
||||||
"-Wl,--start-group", ArgString(application->linkFlags), crti, crtbegin, ArgString(objectFiles), crtend, crtn, "-Wl,--end-group",
|
ExecuteForApp(application, toolchainCC, "-o", symbolFile, ArgString(objectFiles), ArgString(application->linkFlags));
|
||||||
ArgString(applicationLinkFlags), "-T", linkerScript);
|
} else {
|
||||||
|
ExecuteForApp(application, toolchainCC, "-o", symbolFile,
|
||||||
|
"-Wl,--start-group", ArgString(application->linkFlags), crti, crtbegin, ArgString(objectFiles), crtend, crtn, "-Wl,--end-group",
|
||||||
|
ArgString(applicationLinkFlags), "-T", linkerScript);
|
||||||
|
}
|
||||||
|
|
||||||
ExecuteForApp(application, toolchainStrip, "-o", strippedFile, "--strip-all", symbolFile);
|
ExecuteForApp(application, toolchainStrip, "-o", strippedFile, "--strip-all", symbolFile);
|
||||||
|
|
||||||
ADD_BUNDLE_INPUT(strippedFile, "$Executables/x86_64", 0x1000);
|
ADD_BUNDLE_INPUT(strippedFile, "$Executables/x86_64", 0x1000);
|
||||||
|
@ -708,6 +714,7 @@ void ParseApplicationManifest(const char *manifestPath) {
|
||||||
INI_READ_STRING_PTR(compile_flags, application.compileFlags);
|
INI_READ_STRING_PTR(compile_flags, application.compileFlags);
|
||||||
INI_READ_STRING_PTR(link_flags, application.linkFlags);
|
INI_READ_STRING_PTR(link_flags, application.linkFlags);
|
||||||
INI_READ_STRING_PTR(custom_compile_command, application.customCompileCommand);
|
INI_READ_STRING_PTR(custom_compile_command, application.customCompileCommand);
|
||||||
|
INI_READ_BOOL(with_cstdlib, application.withCStdLib);
|
||||||
INI_READ_STRING_PTR(require, require);
|
INI_READ_STRING_PTR(require, require);
|
||||||
} else if (0 == strcmp(s.section, "general")) {
|
} else if (0 == strcmp(s.section, "general")) {
|
||||||
INI_READ_STRING_PTR(name, application.name);
|
INI_READ_STRING_PTR(name, application.name);
|
||||||
|
@ -1398,6 +1405,9 @@ int main(int argc, char **argv) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strcpy(commonCompileFlagsWithCStdLib, commonCompileFlags);
|
||||||
|
strcat(commonCompileFlags, commonCompileFlagsFreestanding);
|
||||||
|
|
||||||
buildStartTimeStamp = time(NULL);
|
buildStartTimeStamp = time(NULL);
|
||||||
sh_new_strdup(applicationDependencies);
|
sh_new_strdup(applicationDependencies);
|
||||||
|
|
||||||
|
@ -1508,27 +1518,34 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
// Build all these applications.
|
// Build all these applications.
|
||||||
|
|
||||||
|
bool skip = false;
|
||||||
|
|
||||||
#ifdef PARALLEL_BUILD
|
#ifdef PARALLEL_BUILD
|
||||||
if (useColoredOutput) StartSpinner();
|
if (!verbose) {
|
||||||
pthread_t *threads = (pthread_t *) malloc(sizeof(pthread_t) * threadCount);
|
if (useColoredOutput) StartSpinner();
|
||||||
|
pthread_t *threads = (pthread_t *) malloc(sizeof(pthread_t) * threadCount);
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < threadCount; i++) {
|
for (uintptr_t i = 0; i < threadCount; i++) {
|
||||||
pthread_create(threads + i, NULL, BuildApplicationThread, NULL);
|
pthread_create(threads + i, NULL, BuildApplicationThread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < threadCount; i++) {
|
for (uintptr_t i = 0; i < threadCount; i++) {
|
||||||
pthread_join(threads[i], NULL);
|
pthread_join(threads[i], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useColoredOutput) StopSpinner();
|
if (useColoredOutput) StopSpinner();
|
||||||
#else
|
skip = true;
|
||||||
for (uintptr_t i = 0; i < arrlenu(applications); i++) {
|
|
||||||
Log("[%d/%d] Compiling %s...\n", i + 1, arrlenu(applications), applications[i].name);
|
|
||||||
if (applications[i].skipped) continue;
|
|
||||||
applications[i].buildCallback(&applications[i]);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!skip) {
|
||||||
|
for (uintptr_t i = 0; i < arrlenu(applications); i++) {
|
||||||
|
Log("[%d/%d] Compiling %s...\n", (int) i + 1, (int) arrlenu(applications), applications[i].name);
|
||||||
|
if (applications[i].skipped) continue;
|
||||||
|
applications[i].buildCallback(&applications[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Output information about the built applications,
|
// Output information about the built applications,
|
||||||
// and parse the dependency files for successfully built ones.
|
// and parse the dependency files for successfully built ones.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue