mirror of https://gitlab.com/nakst/essence
opengl test obj parsing and lighting
This commit is contained in:
parent
923e4b72d7
commit
a50f4df623
|
@ -4,7 +4,7 @@ icon=icon_applications_development
|
||||||
permission_posix_subsystem=1
|
permission_posix_subsystem=1
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
custom_compile_command=cp root/Applications/POSIX/bin/bochs root/Applications/Bochs.esx
|
custom_compile_command=cp root/Applications/POSIX/bin/bochs bin/Bochs
|
||||||
require=root/Applications/POSIX/bin/bochs
|
require=root/Applications/POSIX/bin/bochs
|
||||||
|
|
||||||
[@file_type]
|
[@file_type]
|
||||||
|
|
264
apps/gl_test.c
264
apps/gl_test.c
|
@ -10,7 +10,10 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#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 IMAGE_WIDTH (700)
|
#define IMAGE_WIDTH (700)
|
||||||
#define IMAGE_HEIGHT (600)
|
#define IMAGE_HEIGHT (600)
|
||||||
|
@ -42,6 +45,7 @@ static void (*glShaderSource)(GLuint shader, GLsizei count, const GLchar *const
|
||||||
static void (*glUniform1f)(GLint location, GLfloat v0);
|
static void (*glUniform1f)(GLint location, GLfloat v0);
|
||||||
static void (*glUniform1i)(GLint location, GLint v0);
|
static void (*glUniform1i)(GLint location, GLint v0);
|
||||||
static void (*glUniform4f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
|
static void (*glUniform4f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
|
||||||
|
static void (*glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||||
static void (*glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
static void (*glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||||
static void (*glUseProgram)(GLuint program);
|
static void (*glUseProgram)(GLuint program);
|
||||||
static void (*glValidateProgram)(GLuint program);
|
static void (*glValidateProgram)(GLuint program);
|
||||||
|
@ -65,14 +69,71 @@ static void (*glVertexAttribPointer)(GLuint index, GLint size, GLenum type, GLbo
|
||||||
#define GL_BGRA 0x80E1
|
#define GL_BGRA 0x80E1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MODERN_GL
|
uint32_t framesDrawn;
|
||||||
|
double lastTime;
|
||||||
float timeMs;
|
float timeMs;
|
||||||
|
|
||||||
void RenderLegacy() {
|
int shaderTransform, shaderNormalTransform;
|
||||||
|
size_t triangleCount, vertexCount;
|
||||||
|
|
||||||
|
void Transform(float *left, float *right, float *output) {
|
||||||
|
float result[16];
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
float s = left[0 + i * 4] * right[j + 0 * 4]
|
||||||
|
+ left[1 + i * 4] * right[j + 1 * 4]
|
||||||
|
+ left[2 + i * 4] * right[j + 2 * 4]
|
||||||
|
+ left[3 + i * 4] * right[j + 3 * 4];
|
||||||
|
result[i * 4 + j] = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(output, result, sizeof(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrepareNormalTransform(float *_modelTransform, float *_normalTransform) {
|
||||||
|
float modelTransform[4][4];
|
||||||
|
float normalTransform[3][3];
|
||||||
|
float determinant = 0;
|
||||||
|
|
||||||
|
memcpy(modelTransform, _modelTransform, 4 * 4 * sizeof(float));
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < 3; i++) {
|
||||||
|
determinant += modelTransform[0][i] * (modelTransform[1][(i + 1) % 3] * modelTransform[2][(i + 2) % 3]
|
||||||
|
- modelTransform[1][(i + 2) % 3] * modelTransform[2][(i + 1) % 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < 3; i++) {
|
||||||
|
for (uintptr_t j = 0; j < 3; j++) {
|
||||||
|
normalTransform[i][j] = ((modelTransform[(i + 1) % 3][(j + 1) % 3] * modelTransform[(i + 2) % 3][(j + 2) % 3])
|
||||||
|
- (modelTransform[(i + 1) % 3][(j + 2) % 3] * modelTransform[(i + 2) % 3][(j + 1) % 3])) / determinant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(_normalTransform, normalTransform, 3 * 3 * sizeof(float));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Render() {
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
#ifdef MODERN_GL
|
||||||
|
float m = timeMs / 1000.0f;
|
||||||
|
float transform[16] = { 1, 0, 0, 0, /**/ 0, 1, 0, 0, /**/ 0, 0, 1, 0, /**/ 0, 0, 0, 1 };
|
||||||
|
float normalTransform[9];
|
||||||
|
float rotation[16] = { cosf(m), 0, sinf(m), 0, /**/ 0, 1, 0, 0, /**/ -sinf(m), 0, cosf(m), 0, /**/ 0, 0, 0, 1 };
|
||||||
|
float rotation2[16] = { 1, 0, 0, 0, /**/ 0, cosf(0.3f), sinf(0.3f), 0, /**/ 0, -sinf(0.3f), cosf(0.3f), 0, /**/ 0, 0, 0, 1 };
|
||||||
|
float final[16] = { 0.2f, 0, 0, 0, /**/ 0, -0.2f, 0, 0, /**/ 0, 0, 0.2f, 0, /**/ 0, 0.15f, 0.5f, 1 };
|
||||||
|
Transform(rotation2, transform, transform);
|
||||||
|
Transform(rotation, transform, transform);
|
||||||
|
PrepareNormalTransform(transform, normalTransform);
|
||||||
|
glUniformMatrix3fv(shaderNormalTransform, 1, GL_FALSE, normalTransform);
|
||||||
|
Transform(final, transform, transform);
|
||||||
|
glUniformMatrix4fv(shaderTransform, 1, GL_FALSE, transform);
|
||||||
|
glDrawElements(GL_TRIANGLES, 3 * triangleCount, GL_UNSIGNED_INT, 0);
|
||||||
|
#else
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glRotatef(fmodf(timeMs * 0.1f, 360.0f), 1, 0, 1);
|
glRotatef(fmodf(timeMs * 0.1f, 360.0f), 1, 0, 0);
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
glColor4f(1, 0, 0, 1);
|
glColor4f(1, 0, 0, 1);
|
||||||
glVertex2f(-0.5f, -0.5f);
|
glVertex2f(-0.5f, -0.5f);
|
||||||
|
@ -81,24 +142,42 @@ void RenderLegacy() {
|
||||||
glColor4f(0, 0, 1, 1);
|
glColor4f(0, 0, 1, 1);
|
||||||
glVertex2f(0.5f, -0.5f);
|
glVertex2f(0.5f, -0.5f);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
#endif
|
||||||
glFinish();
|
glFinish();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ESSENCE_WINDOW
|
#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) {
|
||||||
#ifndef MODERN_GL
|
#ifdef LIVE_UPDATE
|
||||||
RenderLegacy();
|
Render();
|
||||||
#endif
|
#endif
|
||||||
EsRectangle bounds = EsRectangleCenter(EsPainterBoundsInset(message->painter), ES_RECT_2S(IMAGE_WIDTH, IMAGE_HEIGHT));
|
EsRectangle bounds = EsPainterBoundsInset(message->painter);
|
||||||
EsDrawBitmap(message->painter, bounds, buffer, IMAGE_WIDTH * 4, ES_DRAW_BITMAP_OPAQUE);
|
EsRectangle imageBounds = EsRectangleCenter(bounds, ES_RECT_2S(IMAGE_WIDTH, IMAGE_HEIGHT));
|
||||||
|
EsDrawBitmap(message->painter, imageBounds, buffer, IMAGE_WIDTH * 4, ES_DRAW_BITMAP_OPAQUE);
|
||||||
|
EsDrawBlock(message->painter, ES_RECT_4(bounds.l, imageBounds.l, bounds.t, bounds.b), 0xFF000000);
|
||||||
|
EsDrawBlock(message->painter, ES_RECT_4(imageBounds.r, bounds.r, bounds.t, bounds.b), 0xFF000000);
|
||||||
|
EsDrawBlock(message->painter, ES_RECT_4(imageBounds.l, imageBounds.r, bounds.t, imageBounds.t), 0xFF000000);
|
||||||
|
EsDrawBlock(message->painter, ES_RECT_4(imageBounds.l, imageBounds.r, imageBounds.b, bounds.b), 0xFF000000);
|
||||||
|
framesDrawn++;
|
||||||
} else if (message->type == ES_MSG_ANIMATE) {
|
} else if (message->type == ES_MSG_ANIMATE) {
|
||||||
|
double currentTime = EsTimeStampMs();
|
||||||
|
|
||||||
|
if (currentTime - lastTime > 1000.0) {
|
||||||
|
EsPrint("%d fps\n", framesDrawn);
|
||||||
|
lastTime = currentTime;
|
||||||
|
framesDrawn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
message->animate.complete = false;
|
message->animate.complete = false;
|
||||||
timeMs += message->animate.deltaMs;
|
timeMs += message->animate.deltaMs;
|
||||||
EsElementRepaint(element, NULL);
|
|
||||||
|
int width, height;
|
||||||
|
EsElementGetSize(element, &width, &height);
|
||||||
|
EsRectangle imageBounds = EsRectangleCenter(ES_RECT_2S(width, height), ES_RECT_2S(IMAGE_WIDTH, IMAGE_HEIGHT));
|
||||||
|
EsElementRepaint(element, &imageBounds);
|
||||||
return ES_HANDLED;
|
return ES_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +186,9 @@ int CanvasCallback(EsElement *element, EsMessage *message) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
|
||||||
#ifndef MODERN_GL
|
#ifndef MODERN_GL
|
||||||
OSMesaContext context = OSMesaCreateContextExt(OSMESA_RGBA, 16, 0, 0, NULL);
|
OSMesaContext context = OSMesaCreateContextExt(OSMESA_RGBA, 16, 0, 0, NULL);
|
||||||
buffer = (uint32_t *) malloc(IMAGE_WIDTH * IMAGE_HEIGHT * 4);
|
buffer = (uint32_t *) malloc(IMAGE_WIDTH * IMAGE_HEIGHT * 4);
|
||||||
|
@ -151,6 +233,7 @@ int main(int argc, char **argv) {
|
||||||
LOADEXT(glUniform1f);
|
LOADEXT(glUniform1f);
|
||||||
LOADEXT(glUniform1i);
|
LOADEXT(glUniform1i);
|
||||||
LOADEXT(glUniform4f);
|
LOADEXT(glUniform4f);
|
||||||
|
LOADEXT(glUniformMatrix3fv);
|
||||||
LOADEXT(glUniformMatrix4fv);
|
LOADEXT(glUniformMatrix4fv);
|
||||||
LOADEXT(glUseProgram);
|
LOADEXT(glUseProgram);
|
||||||
LOADEXT(glValidateProgram);
|
LOADEXT(glValidateProgram);
|
||||||
|
@ -162,31 +245,139 @@ 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);
|
||||||
|
|
||||||
int squareVBO, squareIBO;
|
#if 0
|
||||||
float squareVBOArray[] = { -1, -1, 0.5f, /**/ -1, 1, 0.5f, /**/ 1, 1, 0.5f, /**/ 1, -1, 0.5f };
|
triangleCount = 2, vertexCount = 4;
|
||||||
unsigned squareIBOArray[] = { 0, 1, 2, 0, 2, 3 };
|
uint32_t modelIBOArray[] = { 0, 1, 2, 0, 2, 3 };
|
||||||
glGenBuffers(1, &squareVBO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, squareVBO);
|
float modelVBOArray[] = {
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(squareVBOArray), squareVBOArray, GL_STATIC_DRAW);
|
-1, -1, 0.5f, 0, 0, 0,
|
||||||
glGenBuffers(1, &squareIBO);
|
-1, 1, 0.5f, 0, 0, 0,
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, squareIBO);
|
1, 1, 0.5f, 0, 0, 0,
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(squareIBOArray), squareIBOArray, GL_STATIC_DRAW);
|
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);
|
||||||
|
EsAssert(i1 < vertexCount);
|
||||||
|
EsAssert(i2 < vertexCount);
|
||||||
|
modelIBOArray[3 * triangleIndex + 0] = i0;
|
||||||
|
modelIBOArray[3 * triangleIndex + 1] = i1;
|
||||||
|
modelIBOArray[3 * triangleIndex + 2] = i2;
|
||||||
|
triangleIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EsPrint("%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);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, modelVBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float) * vertexCount, modelVBOArray, GL_STATIC_DRAW);
|
||||||
|
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"
|
||||||
"layout(location = 0) in vec3 Position;\n"
|
"layout(location = 0) in vec3 Position;\n"
|
||||||
|
"layout(location = 1) in vec3 Normal;\n"
|
||||||
"uniform mat4 transform;\n"
|
"uniform mat4 transform;\n"
|
||||||
"out vec2 TexCoord0;\n"
|
"uniform mat3 normalTransform;\n"
|
||||||
|
"out vec3 Normal0;\n"
|
||||||
"void main() { \n"
|
"void main() { \n"
|
||||||
" gl_Position = transform * vec4(Position, 1.0);\n"
|
" gl_Position = transform * vec4(Position, 1.0);\n"
|
||||||
|
" Normal0 = normalTransform * Normal;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
const char *fragmentShaderSource =
|
const char *fragmentShaderSource =
|
||||||
"#version 330\n"
|
"#version 330\n"
|
||||||
"layout(location = 0) out vec4 FragColor;\n"
|
"layout(location = 0) out vec4 FragColor;\n"
|
||||||
"in vec2 TexCoord0;\n"
|
"in vec3 Normal0;\n"
|
||||||
"uniform vec4 blendColor;\n"
|
|
||||||
"void main() { \n"
|
"void main() { \n"
|
||||||
" FragColor = blendColor;\n"
|
" vec3 n = normalize(Normal0);\n"
|
||||||
|
" vec3 lightDirection = vec3(0, -0.707, 0.707);\n"
|
||||||
|
" float lightFactor = max(0, -dot(n, lightDirection));\n"
|
||||||
|
" // FragColor = vec4(n.xyz, 1);\n" // Visualize normals.
|
||||||
|
" // FragColor = vec4(vec3(gl_FragCoord.z), 1);\n" // Visualize Z coordinates.
|
||||||
|
" FragColor = vec4(vec3(lightFactor), 1);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
const char *shaderSources[] = { vertexShaderSource, fragmentShaderSource };
|
const char *shaderSources[] = { vertexShaderSource, fragmentShaderSource };
|
||||||
|
@ -212,8 +403,8 @@ int main(int argc, char **argv) {
|
||||||
glLinkProgram(shader);
|
glLinkProgram(shader);
|
||||||
glValidateProgram(shader);
|
glValidateProgram(shader);
|
||||||
|
|
||||||
int shaderBlendColor = glGetUniformLocation(shader, "blendColor");
|
shaderTransform = glGetUniformLocation(shader, "transform");
|
||||||
int shaderTransform = glGetUniformLocation(shader, "transform");
|
shaderNormalTransform = glGetUniformLocation(shader, "normalTransform");
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
@ -223,18 +414,17 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, squareVBO);
|
glBindBuffer(GL_ARRAY_BUFFER, modelVBO);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, squareIBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelIBO);
|
||||||
glVertexAttribPointer(0 /* Position */, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (const GLvoid *) 0);
|
glVertexAttribPointer(0 /* Position */, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const GLvoid *) (0 * sizeof(float)));
|
||||||
|
glVertexAttribPointer(1 /* Normal */, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const GLvoid *) (3 * sizeof(float)));
|
||||||
glUseProgram(shader);
|
glUseProgram(shader);
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glEnable(GL_DEPTH_TEST);
|
||||||
float transform[] = { 0.5f, 0, 0, 0, /**/ 0, 0.5f, 0, 0, /**/ 0, 0, 1, 0, /**/ 0, 0, 0, 1 };
|
glDepthFunc(GL_LESS);
|
||||||
glUniformMatrix4fv(shaderTransform, 1, GL_FALSE, transform);
|
glEnable(GL_CULL_FACE);
|
||||||
glUniform4f(shaderBlendColor, 1, 0, 1, 1);
|
glCullFace(GL_BACK);
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
||||||
|
|
||||||
glFinish();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ESSENCE_WINDOW
|
#ifndef ESSENCE_WINDOW
|
||||||
|
@ -259,8 +449,10 @@ int main(int argc, char **argv) {
|
||||||
EsWindowSetTitle(instance->window, "GL Test", -1);
|
EsWindowSetTitle(instance->window, "GL Test", -1);
|
||||||
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;
|
||||||
#ifndef MODERN_GL
|
#ifdef LIVE_UPDATE
|
||||||
EsElementStartAnimating(canvas);
|
EsElementStartAnimating(canvas);
|
||||||
|
#else
|
||||||
|
Render();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
[general]
|
[general]
|
||||||
name=GL Test
|
name=GL Test
|
||||||
permission_posix_subsystem=1
|
permission_posix_subsystem=1
|
||||||
|
permission_all_files=1
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
custom_compile_command=x86_64-essence-gcc -o "root/Applications/GL Test.esx" apps/gl_test.c -lOSMesa -lstdc++ -lz -g -D ESSENCE_WINDOW
|
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
|
require=root/Applications/POSIX/lib/libOSMesa.a
|
||||||
|
|
|
@ -41,8 +41,6 @@
|
||||||
struct EnumString { const char *cName; int value; };
|
struct EnumString { const char *cName; int value; };
|
||||||
#include <bin/enum_strings_array.h>
|
#include <bin/enum_strings_array.h>
|
||||||
|
|
||||||
#define ANIMATION_TIME_SCALE (1)
|
|
||||||
|
|
||||||
#define DESKTOP_MSG_SET_TITLE (1)
|
#define DESKTOP_MSG_SET_TITLE (1)
|
||||||
#define DESKTOP_MSG_SET_ICON (2)
|
#define DESKTOP_MSG_SET_ICON (2)
|
||||||
#define DESKTOP_MSG_REQUEST_SAVE (3)
|
#define DESKTOP_MSG_REQUEST_SAVE (3)
|
||||||
|
|
|
@ -1477,7 +1477,7 @@ void _ThemeAnimationBuildAddProperties(ThemeAnimation *animation, UIStyle *style
|
||||||
// Prioritise before enter sequence durations.
|
// Prioritise before enter sequence durations.
|
||||||
|
|
||||||
if (!animation->properties[point].beforeEnter || beforeEnter) {
|
if (!animation->properties[point].beforeEnter || beforeEnter) {
|
||||||
animation->properties[point].duration = sequenceHeader->duration * ANIMATION_TIME_SCALE;
|
animation->properties[point].duration = sequenceHeader->duration * api.global->animationTimeMultiplier;
|
||||||
animation->properties[point].beforeEnter = beforeEnter;
|
animation->properties[point].beforeEnter = beforeEnter;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1489,7 +1489,7 @@ void _ThemeAnimationBuildAddProperties(ThemeAnimation *animation, UIStyle *style
|
||||||
ThemeAnimatingProperty property = {};
|
ThemeAnimatingProperty property = {};
|
||||||
property.offset = key;
|
property.offset = key;
|
||||||
property.type = themeOverride->type;
|
property.type = themeOverride->type;
|
||||||
property.duration = sequenceHeader->duration * ANIMATION_TIME_SCALE;
|
property.duration = sequenceHeader->duration * api.global->animationTimeMultiplier;
|
||||||
property.beforeEnter = beforeEnter;
|
property.beforeEnter = beforeEnter;
|
||||||
|
|
||||||
if (themeOverride->type == THEME_OVERRIDE_I8) {
|
if (themeOverride->type == THEME_OVERRIDE_I8) {
|
||||||
|
|
|
@ -608,7 +608,7 @@ void BuildApplication(Application *application) {
|
||||||
// TODO.
|
// TODO.
|
||||||
#else
|
#else
|
||||||
application->error = system(application->customCompileCommand);
|
application->error = system(application->customCompileCommand);
|
||||||
ExecuteForApp(application, toolchainStrip, "--strip-all", executable);
|
ExecuteForApp(application, toolchainStrip, "-o", executable, "--strip-all", symbolFile);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
for (uintptr_t i = 0; i < arrlenu(application->sources); i++) {
|
for (uintptr_t i = 0; i < arrlenu(application->sources); i++) {
|
||||||
|
|
Loading…
Reference in New Issue