mirror of https://github.com/mode777/rayjs.git
Use raylib drawing function for baking
This commit is contained in:
parent
03a6079549
commit
75b8f12e9b
|
@ -3,9 +3,11 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
#include <rlgl.h>
|
#include <rlgl.h>
|
||||||
|
#include <raymath.h>
|
||||||
#include <external/glad.h>
|
#include <external/glad.h>
|
||||||
#define LIGHTMAPPER_IMPLEMENTATION
|
#define LIGHTMAPPER_IMPLEMENTATION
|
||||||
#define LM_DEBUG_INTERPOLATION
|
#define LM_DEBUG_INTERPOLATION
|
||||||
|
@ -27,7 +29,7 @@ typedef struct
|
||||||
GLint u_lightmap;
|
GLint u_lightmap;
|
||||||
GLint u_mvp;
|
GLint u_mvp;
|
||||||
Texture raylib_texture;
|
Texture raylib_texture;
|
||||||
GLuint lightmap;
|
//GLuint lightmap;
|
||||||
int w, h;
|
int w, h;
|
||||||
Model raylib_model;
|
Model raylib_model;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
|
@ -37,23 +39,36 @@ static int initScene(scene_t *scene);
|
||||||
static void drawScene(scene_t *scene, float *view, float *projection);
|
static void drawScene(scene_t *scene, float *view, float *projection);
|
||||||
static void destroyScene(scene_t *scene);
|
static void destroyScene(scene_t *scene);
|
||||||
|
|
||||||
|
static void convertArrayToStruct(float *array, struct Matrix *matrix) {
|
||||||
|
matrix->m0 = array[0];
|
||||||
|
matrix->m1 = array[1];
|
||||||
|
matrix->m2 = array[2];
|
||||||
|
matrix->m3 = array[3];
|
||||||
|
matrix->m4 = array[4];
|
||||||
|
matrix->m5 = array[5];
|
||||||
|
matrix->m6 = array[6];
|
||||||
|
matrix->m7 = array[7];
|
||||||
|
matrix->m8 = array[8];
|
||||||
|
matrix->m9 = array[9];
|
||||||
|
matrix->m10 = array[10];
|
||||||
|
matrix->m11 = array[11];
|
||||||
|
matrix->m12 = array[12];
|
||||||
|
matrix->m13 = array[13];
|
||||||
|
matrix->m14 = array[14];
|
||||||
|
matrix->m15 = array[15];
|
||||||
|
}
|
||||||
|
|
||||||
static int bake(scene_t *scene)
|
static int bake(scene_t *scene)
|
||||||
{
|
{
|
||||||
lm_context *ctx = lmCreate(
|
lm_context *ctx = lmCreate(
|
||||||
64, // hemisphere resolution (power of two, max=512)
|
64, // hemisphere resolution (power of two, max=512)
|
||||||
0.001f, 100.0f, // zNear, zFar of hemisphere cameras
|
0.001f, 100.0f, // zNear, zFar of hemisphere cameras
|
||||||
1.0f, 1.0f, 1.0f, // background color (white for ambient occlusion)
|
0.1f, 0.15f, 0.5f, // background color (white for ambient occlusion)
|
||||||
2, 0.01f, // lightmap interpolation threshold (small differences are interpolated rather than sampled)
|
2, 0.01f, // lightmap interpolation threshold (small differences are interpolated rather than sampled)
|
||||||
// check debug_interpolation.tga for an overview of sampled (red) vs interpolated (green) pixels.
|
// check debug_interpolation.tga for an overview of sampled (red) vs interpolated (green) pixels.
|
||||||
0.0f); // modifier for camera-to-surface distance for hemisphere rendering.
|
0.0f); // modifier for camera-to-surface distance for hemisphere rendering.
|
||||||
// tweak this to trade-off between interpolated normals quality and other artifacts (see declaration).
|
// tweak this to trade-off between interpolated normals quality and other artifacts (see declaration).
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error: Could not initialize lightmapper.\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int w = scene->w, h = scene->h;
|
int w = scene->w, h = scene->h;
|
||||||
float *data = calloc(w * h * 4, sizeof(float));
|
float *data = calloc(w * h * 4, sizeof(float));
|
||||||
lmSetTargetLightmap(ctx, data, w, h, 4);
|
lmSetTargetLightmap(ctx, data, w, h, 4);
|
||||||
|
@ -69,18 +84,29 @@ static int bake(scene_t *scene)
|
||||||
int vp[4];
|
int vp[4];
|
||||||
float view[16], projection[16];
|
float view[16], projection[16];
|
||||||
double lastUpdateTime = 0.0;
|
double lastUpdateTime = 0.0;
|
||||||
|
|
||||||
rlEnableDepthTest();
|
rlEnableDepthTest();
|
||||||
rlDisableColorBlend();
|
rlDisableColorBlend();
|
||||||
|
Shader oldShader = scene->raylib_model.materials[0].shader;
|
||||||
|
scene->raylib_model.materials[0].shader = scene->raylib_shader;
|
||||||
|
scene->raylib_model.materials[0].maps[0].texture = scene->raylib_texture;
|
||||||
|
|
||||||
while (lmBegin(ctx, vp, view, projection))
|
while (lmBegin(ctx, vp, view, projection))
|
||||||
{
|
{
|
||||||
// render to lightmapper framebuffer
|
// render to lightmapper framebuffer
|
||||||
rlViewport(vp[0], vp[1], vp[2], vp[3]);
|
rlViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
|
|
||||||
|
Matrix matView, matProj;
|
||||||
|
convertArrayToStruct(view, &matView);
|
||||||
|
convertArrayToStruct(projection, &matProj);
|
||||||
|
rlSetMatrixModelview(matView);
|
||||||
|
rlSetMatrixProjection(matProj);
|
||||||
|
|
||||||
drawScene(scene, view, projection);
|
DrawModel(scene->raylib_model, (Vector3){ 0,0,0 }, 1, WHITE);
|
||||||
|
|
||||||
// display progress every second (printf is expensive)
|
// display progress every second (printf is expensive)
|
||||||
double time = GetTime();
|
double time = GetTime();
|
||||||
if (time - lastUpdateTime > 1.0)
|
if (time - lastUpdateTime > 0.05)
|
||||||
{
|
{
|
||||||
lastUpdateTime = time;
|
lastUpdateTime = time;
|
||||||
printf("\r%6.2f%%", lmProgress(ctx) * 100.0f);
|
printf("\r%6.2f%%", lmProgress(ctx) * 100.0f);
|
||||||
|
@ -91,8 +117,7 @@ static int bake(scene_t *scene)
|
||||||
}
|
}
|
||||||
rlDisableDepthTest();
|
rlDisableDepthTest();
|
||||||
rlEnableColorBlend();
|
rlEnableColorBlend();
|
||||||
|
scene->raylib_model.materials[0].shader = oldShader;
|
||||||
//printf("\rFinished baking %d triangles.\n", scene->indexCount / 3);
|
|
||||||
|
|
||||||
lmDestroy(ctx);
|
lmDestroy(ctx);
|
||||||
|
|
||||||
|
@ -118,10 +143,9 @@ static int bake(scene_t *scene)
|
||||||
ExportImage(im,"result.png");
|
ExportImage(im,"result.png");
|
||||||
|
|
||||||
// upload result
|
// upload result
|
||||||
rlUnloadTexture(scene->lightmap);
|
UnloadTexture(scene->raylib_texture);
|
||||||
scene->lightmap = rlLoadTexture(tempub, w, h, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
|
|
||||||
Texture texture;
|
Texture texture;
|
||||||
texture.id = scene->lightmap;
|
texture.id = rlLoadTexture(tempub, w, h, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
|
||||||
texture.width = w;
|
texture.width = w;
|
||||||
texture.height = h;
|
texture.height = h;
|
||||||
texture.mipmaps = 1;
|
texture.mipmaps = 1;
|
||||||
|
@ -139,36 +163,6 @@ static int bake(scene_t *scene)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int first = 1;
|
|
||||||
|
|
||||||
static void mainLoop(scene_t *scene)
|
|
||||||
{
|
|
||||||
if (first){
|
|
||||||
bake(scene);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int w = GetScreenWidth() * GetWindowScaleDPI().x;
|
|
||||||
int h = GetScreenHeight() * GetWindowScaleDPI().y;
|
|
||||||
|
|
||||||
rlViewport(0, 0, w, h);
|
|
||||||
|
|
||||||
// camera for glfw window
|
|
||||||
float view[16], projection[16];
|
|
||||||
//fpsCameraViewMatrix(view);
|
|
||||||
//perspectiveMatrix(projection, 45.0f, (float)w / (float)h, 0.01f, 100.0f);
|
|
||||||
|
|
||||||
BeginDrawing();
|
|
||||||
BeginMode3D(scene->camera);
|
|
||||||
ClearBackground(BLUE);
|
|
||||||
rlEnableDepthTest();
|
|
||||||
//drawScene(scene, view, projection);
|
|
||||||
DrawModel(scene->raylib_model, (Vector3) {0.0f,0.0f,0.0f}, 1, WHITE);
|
|
||||||
rlDisableDepthTest();
|
|
||||||
EndMode3D();
|
|
||||||
EndDrawing();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI | FLAG_VSYNC_HINT);
|
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI | FLAG_VSYNC_HINT);
|
||||||
|
@ -176,22 +170,22 @@ int main(int argc, char* argv[])
|
||||||
InitWindow(1024,768,"Test");
|
InitWindow(1024,768,"Test");
|
||||||
|
|
||||||
scene_t scene = {0};
|
scene_t scene = {0};
|
||||||
if (!initScene(&scene))
|
initScene(&scene);
|
||||||
{
|
bake(&scene);
|
||||||
fprintf(stderr, "Could not initialize scene.\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Ambient Occlusion Baking Example.\n");
|
|
||||||
printf("Use your mouse and the W, A, S, D, E, Q keys to navigate.\n");
|
|
||||||
printf("Press SPACE to start baking one light bounce!\n");
|
|
||||||
printf("This will take a few seconds and bake a lightmap illuminated by:\n");
|
|
||||||
printf("1. The mesh itself (initially black)\n");
|
|
||||||
printf("2. A white sky (1.0f, 1.0f, 1.0f)\n");
|
|
||||||
|
|
||||||
while (!WindowShouldClose())
|
while (!WindowShouldClose())
|
||||||
{
|
{
|
||||||
mainLoop(&scene);
|
int w = GetScreenWidth() * GetWindowScaleDPI().x;
|
||||||
|
int h = GetScreenHeight() * GetWindowScaleDPI().y;
|
||||||
|
|
||||||
|
rlViewport(0, 0, w, h);
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
BeginMode3D(scene.camera);
|
||||||
|
ClearBackground(BLUE);
|
||||||
|
DrawModel(scene.raylib_model, (Vector3) {0.0f,0.0f,0.0f}, 1, WHITE);
|
||||||
|
EndMode3D();
|
||||||
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyScene(&scene);
|
destroyScene(&scene);
|
||||||
|
@ -211,7 +205,7 @@ static int initScene(scene_t *scene)
|
||||||
|
|
||||||
scene->w = 512;
|
scene->w = 512;
|
||||||
scene->h = 512;
|
scene->h = 512;
|
||||||
scene->lightmap = LoadTextureFromImage(GenImageColor(1,1,BLACK)).id;
|
scene->raylib_texture = LoadTextureFromImage(GenImageColor(1,1,BLACK));
|
||||||
|
|
||||||
// load shader
|
// load shader
|
||||||
const char *vp =
|
const char *vp =
|
||||||
|
@ -238,50 +232,22 @@ static int initScene(scene_t *scene)
|
||||||
"o_color = vec4(texture(texture0, v_texcoord).rgb, gl_FrontFacing ? 1.0 : 0.0);\n"
|
"o_color = vec4(texture(texture0, v_texcoord).rgb, gl_FrontFacing ? 1.0 : 0.0);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
//scene->program = rlLoadShaderCode(vp, fp);
|
|
||||||
scene->raylib_shader = LoadShaderFromMemory(vp, fp);
|
scene->raylib_shader = LoadShaderFromMemory(vp, fp);
|
||||||
|
|
||||||
scene->u_lightmap = rlGetLocationUniform(scene->raylib_shader.id, "texture0");
|
scene->u_lightmap = rlGetLocationUniform(scene->raylib_shader.id, "texture0");
|
||||||
scene->u_mvp = rlGetLocationUniform(scene->raylib_shader.id, "mvp");
|
scene->u_mvp = rlGetLocationUniform(scene->raylib_shader.id, "mvp");
|
||||||
|
|
||||||
//scene->raylib_model.materials[0].shader = scene->raylib_shader;
|
|
||||||
|
|
||||||
Camera camera = { 0 };
|
Camera camera = { 0 };
|
||||||
camera.position = (Vector3){ 1.0f, 0.5f, 1.0f }; // Camera position
|
camera.position = (Vector3){ 1.0f, 0.5f, 1.0f }; // Camera position
|
||||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
camera.target = (Vector3){ 0.0f, 0.35f, 0.0f }; // Camera looking at point
|
||||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||||
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
|
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
|
||||||
|
|
||||||
scene->camera = camera;
|
scene->camera = camera;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void multiplyMatrices(float *out, float *a, float *b)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < 4; y++)
|
|
||||||
for (int x = 0; x < 4; x++)
|
|
||||||
out[y * 4 + x] = a[x] * b[y * 4] + a[4 + x] * b[y * 4 + 1] + a[8 + x] * b[y * 4 + 2] + a[12 + x] * b[y * 4 + 3];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawScene(scene_t *scene, float *view, float *projection)
|
|
||||||
{
|
|
||||||
Mesh m = scene->raylib_model.meshes[0];
|
|
||||||
|
|
||||||
rlEnableShader(scene->raylib_shader.id);
|
|
||||||
float mvp[16];
|
|
||||||
multiplyMatrices(mvp, projection, view);
|
|
||||||
glUniformMatrix4fv(scene->u_mvp, 1, GL_FALSE, mvp);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, scene->lightmap);
|
|
||||||
|
|
||||||
//glBindVertexArray(scene->vao);
|
|
||||||
//glDrawElements(GL_TRIANGLES, scene->indexCount, GL_UNSIGNED_SHORT, 0);
|
|
||||||
glBindVertexArray(m.vaoId);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, m.vertexCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroyScene(scene_t *scene)
|
static void destroyScene(scene_t *scene)
|
||||||
{
|
{
|
||||||
UnloadModel(scene->raylib_model);
|
UnloadModel(scene->raylib_model);
|
||||||
|
|
Loading…
Reference in New Issue