mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-22 23:18:01 +03:00
Merge pull request #52 from kichikuou/3d
Initial implementation of ReignEngine HLL
This commit is contained in:
+3
-1
@@ -17,9 +17,11 @@
|
||||
#ifndef SYSTEM4_PLUGIN_H
|
||||
#define SYSTEM4_PLUGIN_H
|
||||
|
||||
struct sact_sprite;
|
||||
|
||||
struct draw_plugin {
|
||||
const char *name;
|
||||
void (*update)(struct draw_plugin *);
|
||||
void (*update)(struct sact_sprite *);
|
||||
};
|
||||
|
||||
#endif /* SYSTEM4_PLUGIN_H */
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/* Copyright (C) 2022 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM4_REIGN_H
|
||||
#define SYSTEM4_REIGN_H
|
||||
|
||||
#define RE_MAX_INSTANCES 32
|
||||
|
||||
#include <cglm/types.h>
|
||||
|
||||
#include "plugin.h"
|
||||
|
||||
struct RE_options {
|
||||
int anti_aliasing;
|
||||
int wait_vsync;
|
||||
};
|
||||
extern struct RE_options RE_options;
|
||||
|
||||
struct RE_camera {
|
||||
vec3 pos;
|
||||
float pitch, roll, yaw; // in degrees
|
||||
};
|
||||
|
||||
struct RE_plugin {
|
||||
struct draw_plugin plugin;
|
||||
int sprite;
|
||||
struct RE_instance *instances[RE_MAX_INSTANCES];
|
||||
struct archive *aar;
|
||||
struct RE_renderer *renderer;
|
||||
struct RE_camera camera;
|
||||
mat4 proj_transform;
|
||||
|
||||
// Settings.
|
||||
int render_mode;
|
||||
int shadow_mode;
|
||||
int bump_mode;
|
||||
int bloom_mode;
|
||||
int glare_mode;
|
||||
int fog_mode;
|
||||
int specular_mode;
|
||||
int light_map_mode;
|
||||
int soft_fog_edge_mode;
|
||||
int ssao_mode;
|
||||
int vertex_blend_mode;
|
||||
int shader_precision_mode;
|
||||
int texture_filter_mode;
|
||||
bool use_power2_texture;
|
||||
int shadow_map_resolution_level;
|
||||
int texture_resolution_level;
|
||||
float global_ambient_r;
|
||||
float global_ambient_g;
|
||||
float global_ambient_b;
|
||||
float post_effect_filter_y;
|
||||
float post_effect_filter_cb;
|
||||
float post_effect_filter_cr;
|
||||
};
|
||||
|
||||
struct RE_instance {
|
||||
struct RE_plugin *plugin;
|
||||
struct model *model;
|
||||
int type;
|
||||
vec3 pos;
|
||||
float pitch, roll, yaw; // in degrees
|
||||
vec3 vec;
|
||||
vec3 scale;
|
||||
bool draw;
|
||||
bool local_transform_needs_update;
|
||||
mat4 local_transform;
|
||||
};
|
||||
|
||||
struct RE_plugin *RE_plugin_new(void);
|
||||
void RE_plugin_free(struct RE_plugin *plugin);
|
||||
bool RE_plugin_bind(struct RE_plugin *plugin, int sprite);
|
||||
bool RE_plugin_unbind(struct RE_plugin *plugin);
|
||||
bool RE_set_projection(struct RE_plugin *plugin, float width, float height, float near, float far, float deg);
|
||||
int RE_create_instance(struct RE_plugin *plugin);
|
||||
bool RE_release_instance(struct RE_plugin *plugin, int instance);
|
||||
|
||||
bool RE_instance_load(struct RE_instance *instance, const char *name);
|
||||
|
||||
void RE_render(struct sact_sprite *sp);
|
||||
void RE_debug_print(struct RE_plugin *p);
|
||||
|
||||
#endif /* SYSTEM4_REIGN_H */
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Copyright (C) 2022 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 tex_coord;
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
// TODO: Implement lighting.
|
||||
frag_color = texture(tex, tex_coord);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/* Copyright (C) 2022 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
uniform mat4 local_transform;
|
||||
uniform mat4 view_transform;
|
||||
uniform mat4 proj_transform;
|
||||
|
||||
in vec3 vertex_pos;
|
||||
in vec3 vertex_normal;
|
||||
in vec2 vertex_uv;
|
||||
out vec2 tex_coord;
|
||||
|
||||
void main() {
|
||||
gl_Position = proj_transform * view_transform * local_transform * vec4(vertex_pos, 1.0);
|
||||
tex_coord = vertex_uv;
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/* Copyright (C) 2022 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM4_3D_3D_INTERNAL_H
|
||||
#define SYSTEM4_3D_3D_INTERNAL_H
|
||||
|
||||
#include <cglm/types.h>
|
||||
|
||||
#include "system4/archive.h"
|
||||
|
||||
#include "gfx/gl.h"
|
||||
#include "gfx/gfx.h"
|
||||
|
||||
struct model {
|
||||
char *name;
|
||||
int nr_meshes;
|
||||
struct mesh *meshes;
|
||||
int nr_materials;
|
||||
struct material *materials;
|
||||
};
|
||||
|
||||
struct mesh {
|
||||
GLuint vao;
|
||||
GLuint attr_buffer;
|
||||
int nr_vertices;
|
||||
int material;
|
||||
};
|
||||
|
||||
struct material {
|
||||
GLuint color_map;
|
||||
bool opaque;
|
||||
};
|
||||
|
||||
struct RE_renderer {
|
||||
struct shader shader;
|
||||
GLuint depth_buffer;
|
||||
|
||||
// Uniform variable locations
|
||||
GLint local_transform;
|
||||
GLint proj_transform;
|
||||
|
||||
// Attribute variable locations
|
||||
GLint vertex_normal;
|
||||
GLint vertex_uv;
|
||||
};
|
||||
|
||||
// model.c
|
||||
|
||||
struct model *model_load(struct archive *aar, const char *path, struct RE_renderer *renderer);
|
||||
void model_free(struct model *model);
|
||||
|
||||
// renderer.c
|
||||
|
||||
struct RE_renderer *RE_renderer_new(struct texture *texture);
|
||||
void RE_renderer_free(struct RE_renderer *r);
|
||||
|
||||
// parser.c
|
||||
|
||||
struct pol {
|
||||
int32_t version;
|
||||
uint32_t nr_materials;
|
||||
struct pol_material_group *materials;
|
||||
uint32_t nr_meshes;
|
||||
struct pol_mesh **meshes;
|
||||
uint32_t nr_bones;
|
||||
struct pol_bone *bones;
|
||||
};
|
||||
|
||||
enum pol_texture_type {
|
||||
COLOR_MAP = 1,
|
||||
MAX_TEXTURE_TYPE
|
||||
};
|
||||
|
||||
struct pol_material {
|
||||
char *name;
|
||||
char *textures[MAX_TEXTURE_TYPE];
|
||||
};
|
||||
|
||||
struct pol_material_group {
|
||||
struct pol_material m;
|
||||
uint32_t nr_children;
|
||||
struct pol_material *children;
|
||||
};
|
||||
|
||||
struct pol_mesh {
|
||||
char *name;
|
||||
uint32_t material;
|
||||
uint32_t nr_vertices;
|
||||
struct pol_vertex *vertices;
|
||||
uint32_t nr_uvs;
|
||||
vec2 *uvs;
|
||||
uint32_t nr_triangles;
|
||||
struct pol_triangle *triangles;
|
||||
};
|
||||
|
||||
struct pol_vertex {
|
||||
vec3 pos;
|
||||
uint32_t nr_weights;
|
||||
struct pol_bone_weight *weights;
|
||||
};
|
||||
|
||||
struct pol_bone_weight {
|
||||
uint32_t bone;
|
||||
float weight;
|
||||
};
|
||||
|
||||
struct pol_triangle {
|
||||
uint32_t vert_index[3];
|
||||
uint32_t uv_index[3];
|
||||
vec3 normals[3];
|
||||
uint32_t material; // index in the material group
|
||||
};
|
||||
|
||||
struct pol_bone {
|
||||
char *name;
|
||||
uint32_t id;
|
||||
int32_t parent;
|
||||
vec3 pos;
|
||||
versor rotq;
|
||||
};
|
||||
|
||||
struct pol *pol_parse(uint8_t *data, size_t size);
|
||||
void pol_free(struct pol *pol);
|
||||
|
||||
#endif /* SYSTEM4_3D_3D_INTERNAL_H */
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
/* Copyright (C) 2022 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cglm/cglm.h>
|
||||
|
||||
#include "system4.h"
|
||||
#include "system4/aar.h"
|
||||
#include "system4/cg.h"
|
||||
|
||||
#include "3d_internal.h"
|
||||
#include "reign.h"
|
||||
|
||||
struct vertex {
|
||||
GLfloat pos[3];
|
||||
GLfloat normal[3];
|
||||
GLfloat uv[2];
|
||||
};
|
||||
|
||||
static bool init_material(struct material *material, const struct pol_material *m, struct archive *aar, const char *path)
|
||||
{
|
||||
if (!m->textures[COLOR_MAP]) {
|
||||
WARNING("No color texture");
|
||||
return false;
|
||||
}
|
||||
char *texture_path = xmalloc(strlen(path) + strlen(m->textures[COLOR_MAP]) + 2);
|
||||
sprintf(texture_path, "%s\\%s", path, m->textures[COLOR_MAP]);
|
||||
struct archive_data *dfile = archive_get_by_name(aar, texture_path);
|
||||
if (!dfile) {
|
||||
WARNING("cannot load texture %s", texture_path);
|
||||
free(texture_path);
|
||||
return false;
|
||||
}
|
||||
struct cg *cg = cg_load_data(dfile);
|
||||
archive_free_data(dfile);
|
||||
if (!cg) {
|
||||
WARNING("cg_load_data failed: %s", texture_path);
|
||||
free(texture_path);
|
||||
return false;
|
||||
}
|
||||
free(texture_path);
|
||||
|
||||
glGenTextures(1, &material->color_map);
|
||||
glBindTexture(GL_TEXTURE_2D, material->color_map);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cg->metrics.w, cg->metrics.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, cg->pixels);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
material->opaque = !cg->metrics.has_alpha;
|
||||
|
||||
cg_free(cg);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void destroy_material(struct material *material)
|
||||
{
|
||||
if (material->color_map)
|
||||
glDeleteTextures(1, &material->color_map);
|
||||
}
|
||||
|
||||
static void add_mesh(struct model *model, struct pol_mesh *m, int material_index, int material, struct RE_renderer *r)
|
||||
{
|
||||
struct vertex *buf = xmalloc(m->nr_triangles * 3 * sizeof(struct vertex));
|
||||
int v = 0;
|
||||
for (uint32_t i = 0; i < m->nr_triangles; i++) {
|
||||
struct pol_triangle *t = &m->triangles[i];
|
||||
if (material_index >= 0 && t->material != (uint32_t)material_index)
|
||||
continue;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
glm_vec3_copy(m->vertices[t->vert_index[j]].pos, buf[v].pos);
|
||||
glm_vec3_copy(t->normals[j], buf[v].normal);
|
||||
glm_vec2_copy(m->uvs[t->uv_index[j]], buf[v].uv);
|
||||
v++;
|
||||
}
|
||||
}
|
||||
if (v == 0) {
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
model->meshes = xrealloc_array(model->meshes, model->nr_meshes, model->nr_meshes + 1, sizeof(struct mesh));
|
||||
struct mesh *mesh = &model->meshes[model->nr_meshes++];
|
||||
mesh->material = material;
|
||||
mesh->nr_vertices = v;
|
||||
|
||||
glGenVertexArrays(1, &mesh->vao);
|
||||
glBindVertexArray(mesh->vao);
|
||||
glGenBuffers(1, &mesh->attr_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->attr_buffer);
|
||||
|
||||
glEnableVertexAttribArray(r->shader.vertex);
|
||||
glVertexAttribPointer(r->shader.vertex, 3, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (const void *)0);
|
||||
glEnableVertexAttribArray(r->vertex_normal);
|
||||
glVertexAttribPointer(r->vertex_normal, 3, GL_FLOAT, GL_TRUE, sizeof(struct vertex), (const void *)offsetof(struct vertex, normal));
|
||||
glEnableVertexAttribArray(r->vertex_uv);
|
||||
glVertexAttribPointer(r->vertex_uv, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (const void *)offsetof(struct vertex, uv));
|
||||
glBufferData(GL_ARRAY_BUFFER, mesh->nr_vertices * sizeof(struct vertex), buf, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void destroy_mesh(struct mesh *mesh)
|
||||
{
|
||||
glDeleteVertexArrays(1, &mesh->vao);
|
||||
glDeleteBuffers(1, &mesh->attr_buffer);
|
||||
}
|
||||
|
||||
struct model *model_load(struct archive *aar, const char *path, struct RE_renderer *r)
|
||||
{
|
||||
if (path[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
const char *basename = strrchr(path, '\\');
|
||||
basename = basename ? basename + 1 : path;
|
||||
char *polname = xmalloc(strlen(path) + strlen(basename) + 6);
|
||||
sprintf(polname, "%s\\%s.POL", path, basename);
|
||||
|
||||
struct archive_data *dfile = archive_get_by_name(aar, polname);
|
||||
if (!dfile) {
|
||||
WARNING("%s: not found", polname);
|
||||
free(polname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct pol *pol = pol_parse(dfile->data, dfile->size);
|
||||
archive_free_data(dfile);
|
||||
if (!pol) {
|
||||
WARNING("%s: parse error", polname);
|
||||
free(polname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct model *model = xcalloc(1, sizeof(struct model));
|
||||
model->name = polname;
|
||||
|
||||
// Materials
|
||||
int *material_offsets = xmalloc(pol->nr_materials * sizeof(int));
|
||||
for (uint32_t i = 0; i < pol->nr_materials; i++) {
|
||||
material_offsets[i] = model->nr_materials;
|
||||
if (pol->materials[i].nr_children)
|
||||
model->nr_materials += pol->materials[i].nr_children;
|
||||
else
|
||||
model->nr_materials++;
|
||||
}
|
||||
model->materials = xcalloc(model->nr_materials, sizeof(struct material));
|
||||
for (uint32_t i = 0; i < pol->nr_materials; i++) {
|
||||
if (pol->materials[i].nr_children == 0) {
|
||||
init_material(&model->materials[material_offsets[i]],
|
||||
&pol->materials[i].m, aar, path);
|
||||
continue;
|
||||
}
|
||||
for (uint32_t j = 0; j < pol->materials[i].nr_children; j++) {
|
||||
init_material(&model->materials[material_offsets[i] + j],
|
||||
&pol->materials[i].children[j], aar, path);
|
||||
}
|
||||
}
|
||||
|
||||
// Meshes
|
||||
for (uint32_t i = 0; i < pol->nr_meshes; i++) {
|
||||
if (!pol->meshes[i])
|
||||
continue;
|
||||
struct pol_material_group *mg = &pol->materials[pol->meshes[i]->material];
|
||||
int m_off = material_offsets[pol->meshes[i]->material];
|
||||
if (mg->nr_children == 0) {
|
||||
add_mesh(model, pol->meshes[i], -1, m_off, r);
|
||||
continue;
|
||||
}
|
||||
for (uint32_t j = 0; j < mg->nr_children; j++) {
|
||||
add_mesh(model, pol->meshes[i], j, m_off + j, r);
|
||||
}
|
||||
}
|
||||
|
||||
free(material_offsets);
|
||||
pol_free(pol);
|
||||
return model;
|
||||
}
|
||||
|
||||
void model_free(struct model *model)
|
||||
{
|
||||
for (int i = 0; i < model->nr_meshes; i++)
|
||||
destroy_mesh(&model->meshes[i]);
|
||||
free(model->meshes);
|
||||
|
||||
for (int i = 0; i < model->nr_materials; i++)
|
||||
destroy_material(&model->materials[i]);
|
||||
free(model->materials);
|
||||
|
||||
free(model->name);
|
||||
free(model);
|
||||
}
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
/* Copyright (C) 2022 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cglm/cglm.h>
|
||||
|
||||
#include "system4.h"
|
||||
#include "system4/buffer.h"
|
||||
|
||||
#include "3d_internal.h"
|
||||
|
||||
#define METERS_PER_INCH 0.0254
|
||||
|
||||
static char *read_cstring(struct buffer *r)
|
||||
{
|
||||
char *s = strdup(buffer_strdata(r));
|
||||
buffer_skip(r, strlen(s) + 1);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void read_position(struct buffer *r, vec3 v)
|
||||
{
|
||||
// left->right handed system
|
||||
v[0] = buffer_read_float(r) * METERS_PER_INCH;
|
||||
v[1] = buffer_read_float(r) * METERS_PER_INCH;
|
||||
v[2] = -buffer_read_float(r) * METERS_PER_INCH;
|
||||
}
|
||||
|
||||
static void read_direction(struct buffer *r, vec3 v)
|
||||
{
|
||||
// left->right handed system
|
||||
v[0] = buffer_read_float(r);
|
||||
v[1] = buffer_read_float(r);
|
||||
v[2] = -buffer_read_float(r);
|
||||
}
|
||||
|
||||
static void read_quaternion(struct buffer *r, versor q)
|
||||
{
|
||||
// left->right handed system
|
||||
float w = buffer_read_float(r);
|
||||
float x = -buffer_read_float(r);
|
||||
float y = -buffer_read_float(r);
|
||||
float z = buffer_read_float(r);
|
||||
glm_quat_init(q, x, y, z, w);
|
||||
}
|
||||
|
||||
static void parse_material(struct buffer *r, struct pol_material *m)
|
||||
{
|
||||
m->name = read_cstring(r);
|
||||
|
||||
int nr_textures = buffer_read_int32(r);
|
||||
for (int i = 0; i < nr_textures; i++) {
|
||||
char *filename = read_cstring(r);
|
||||
int type = buffer_read_int32(r);
|
||||
if ((unsigned)type < MAX_TEXTURE_TYPE) {
|
||||
m->textures[type] = filename;
|
||||
} else {
|
||||
WARNING("invalid texture type %d", type);
|
||||
free(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void destroy_material(struct pol_material *m)
|
||||
{
|
||||
free(m->name);
|
||||
for (int i = 0; i < MAX_TEXTURE_TYPE; i++)
|
||||
free(m->textures[i]);
|
||||
}
|
||||
|
||||
static void parse_material_group(struct buffer *r, struct pol_material_group *mg)
|
||||
{
|
||||
parse_material(r, &mg->m);
|
||||
|
||||
mg->nr_children = buffer_read_int32(r);
|
||||
if (mg->nr_children > 0) {
|
||||
mg->children = xcalloc(mg->nr_children, sizeof(struct pol_material));
|
||||
for (uint32_t i = 0; i < mg->nr_children; i++) {
|
||||
parse_material(r, &mg->children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void destroy_material_group(struct pol_material_group *mg)
|
||||
{
|
||||
destroy_material(&mg->m);
|
||||
if (mg->children) {
|
||||
for (uint32_t i = 0; i < mg->nr_children; i++)
|
||||
destroy_material(&mg->children[i]);
|
||||
free(mg->children);
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_vertex(struct buffer *r, int pol_version, struct pol_vertex *v)
|
||||
{
|
||||
read_position(r, v->pos);
|
||||
v->nr_weights = pol_version == 1 ? buffer_read_int32(r) : buffer_read_u16(r);
|
||||
if (v->nr_weights) {
|
||||
v->weights = xcalloc(v->nr_weights, sizeof(struct pol_bone_weight));
|
||||
for (uint32_t i = 0; i < v->nr_weights; i++) {
|
||||
v->weights[i].bone = pol_version == 1 ? buffer_read_int32(r) : buffer_read_u16(r);
|
||||
v->weights[i].weight = buffer_read_float(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void destroy_vertex(struct pol_vertex *v)
|
||||
{
|
||||
if (v->weights)
|
||||
free(v->weights);
|
||||
}
|
||||
|
||||
static void parse_triangle(struct buffer *r, int unknowns_length, struct pol_triangle *t)
|
||||
{
|
||||
t->vert_index[0] = buffer_read_int32(r);
|
||||
t->vert_index[1] = buffer_read_int32(r);
|
||||
t->vert_index[2] = buffer_read_int32(r);
|
||||
t->uv_index[0] = buffer_read_int32(r);
|
||||
t->uv_index[1] = buffer_read_int32(r);
|
||||
t->uv_index[2] = buffer_read_int32(r);
|
||||
|
||||
buffer_skip(r, unknowns_length);
|
||||
|
||||
read_direction(r, t->normals[0]);
|
||||
read_direction(r, t->normals[1]);
|
||||
read_direction(r, t->normals[2]);
|
||||
t->material = buffer_read_int32(r);
|
||||
}
|
||||
|
||||
static struct pol_mesh *parse_mesh(struct buffer *r, int pol_version)
|
||||
{
|
||||
int type = buffer_read_int32(r);
|
||||
if (type != 0) {
|
||||
if (type != -1)
|
||||
WARNING("unknown mesh type: %d", type);
|
||||
return NULL;
|
||||
}
|
||||
struct pol_mesh *mesh = xcalloc(1, sizeof(struct pol_mesh));
|
||||
mesh->name = read_cstring(r);
|
||||
mesh->material = buffer_read_int32(r);
|
||||
|
||||
mesh->nr_vertices = buffer_read_int32(r);
|
||||
mesh->vertices = xcalloc(mesh->nr_vertices, sizeof(struct pol_vertex));
|
||||
for (uint32_t i = 0; i < mesh->nr_vertices; i++) {
|
||||
parse_vertex(r, pol_version, &mesh->vertices[i]);
|
||||
}
|
||||
|
||||
mesh->nr_uvs = buffer_read_int32(r);
|
||||
mesh->uvs = xcalloc(mesh->nr_uvs, sizeof(vec2));
|
||||
for (uint32_t i = 0; i < mesh->nr_uvs; i++) {
|
||||
mesh->uvs[i][0] = buffer_read_float(r);
|
||||
mesh->uvs[i][1] = buffer_read_float(r);
|
||||
}
|
||||
|
||||
int triangle_unknowns_length = 12;
|
||||
|
||||
int nr_unknown_f64s = buffer_read_int32(r);
|
||||
if (nr_unknown_f64s) {
|
||||
buffer_skip(r, nr_unknown_f64s * 8);
|
||||
triangle_unknowns_length += 12;
|
||||
}
|
||||
|
||||
if (pol_version == 1) {
|
||||
int nr_unknown_vecs = buffer_read_int32(r);
|
||||
buffer_skip(r, nr_unknown_vecs * 12);
|
||||
} else {
|
||||
int nr_unknown_ints = buffer_read_int32(r);
|
||||
buffer_skip(r, nr_unknown_ints * 4);
|
||||
int nr_unknown_bytes = buffer_read_int32(r);
|
||||
if (nr_unknown_bytes) {
|
||||
buffer_skip(r, nr_unknown_bytes);
|
||||
triangle_unknowns_length += 12;
|
||||
}
|
||||
}
|
||||
|
||||
mesh->nr_triangles = buffer_read_int32(r);
|
||||
mesh->triangles = xcalloc(mesh->nr_triangles, sizeof(struct pol_triangle));
|
||||
for (uint32_t i = 0; i < mesh->nr_triangles; i++) {
|
||||
parse_triangle(r, triangle_unknowns_length, &mesh->triangles[i]);
|
||||
}
|
||||
|
||||
if (pol_version == 1) {
|
||||
if (buffer_read_int32(r) != 1)
|
||||
WARNING("unexpected mesh footer");
|
||||
if (buffer_read_int32(r) != 0)
|
||||
WARNING("unexpected mesh footer");
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
static void free_mesh(struct pol_mesh *mesh)
|
||||
{
|
||||
if (!mesh)
|
||||
return;
|
||||
free(mesh->name);
|
||||
for (uint32_t i = 0; i < mesh->nr_vertices; i++)
|
||||
destroy_vertex(&mesh->vertices[i]);
|
||||
free(mesh->vertices);
|
||||
free(mesh->uvs);
|
||||
free(mesh->triangles);
|
||||
free(mesh);
|
||||
}
|
||||
|
||||
static void parse_bone(struct buffer *r, struct pol_bone *bone)
|
||||
{
|
||||
bone->name = read_cstring(r);
|
||||
bone->id = buffer_read_int32(r);
|
||||
bone->parent = buffer_read_int32(r);
|
||||
read_position(r, bone->pos);
|
||||
read_quaternion(r, bone->rotq);
|
||||
}
|
||||
|
||||
static void destroy_bone(struct pol_bone *bone)
|
||||
{
|
||||
free(bone->name);
|
||||
}
|
||||
|
||||
struct pol *pol_parse(uint8_t *data, size_t size)
|
||||
{
|
||||
struct buffer r;
|
||||
buffer_init(&r, data, size);
|
||||
if (memcmp(buffer_strdata(&r), "POL\0", 4))
|
||||
return NULL;
|
||||
buffer_skip(&r, 4);
|
||||
|
||||
struct pol *pol = xcalloc(1, sizeof(struct pol));
|
||||
pol->version = buffer_read_int32(&r);
|
||||
if (pol->version != 1 && pol->version != 2) {
|
||||
WARNING("unknown POL version: %d", pol->version);
|
||||
free(pol);
|
||||
return NULL;
|
||||
}
|
||||
pol->nr_materials = buffer_read_int32(&r);
|
||||
pol->materials = xcalloc(pol->nr_materials, sizeof(struct pol_material_group));
|
||||
for (uint32_t i = 0; i < pol->nr_materials; i++) {
|
||||
parse_material_group(&r, &pol->materials[i]);
|
||||
}
|
||||
|
||||
pol->nr_meshes = buffer_read_int32(&r);
|
||||
pol->meshes = xcalloc(pol->nr_meshes, sizeof(struct pol_mesh *));
|
||||
for (uint32_t i = 0; i < pol->nr_meshes; i++) {
|
||||
pol->meshes[i] = parse_mesh(&r, pol->version);
|
||||
}
|
||||
|
||||
pol->nr_bones = buffer_read_int32(&r);
|
||||
if (pol->nr_bones) {
|
||||
pol->bones = xcalloc(pol->nr_bones, sizeof(struct pol_bone));
|
||||
for (uint32_t i = 0; i < pol->nr_bones; i++) {
|
||||
parse_bone(&r, &pol->bones[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer_remaining(&r) != 0) {
|
||||
WARNING("extra data at end");
|
||||
}
|
||||
return pol;
|
||||
}
|
||||
|
||||
void pol_free(struct pol *pol)
|
||||
{
|
||||
for (uint32_t i = 0; i < pol->nr_materials; i++)
|
||||
destroy_material_group(&pol->materials[i]);
|
||||
free(pol->materials);
|
||||
for (uint32_t i = 0; i < pol->nr_meshes; i++)
|
||||
free_mesh(pol->meshes[i]);
|
||||
free(pol->meshes);
|
||||
for (uint32_t i = 0; i < pol->nr_bones; i++)
|
||||
destroy_bone(&pol->bones[i]);
|
||||
free(pol->bones);
|
||||
free(pol);
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/* Copyright (C) 2022 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cglm/cglm.h>
|
||||
|
||||
#include "system4.h"
|
||||
#include "system4/aar.h"
|
||||
|
||||
#include "3d_internal.h"
|
||||
#include "reign.h"
|
||||
#include "sact.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
static struct RE_instance *create_instance(struct RE_plugin *plugin)
|
||||
{
|
||||
struct RE_instance *instance = xcalloc(1, sizeof(struct RE_instance));
|
||||
instance->plugin = plugin;
|
||||
instance->scale[0] = 1.0;
|
||||
instance->scale[1] = 1.0;
|
||||
instance->scale[2] = 1.0;
|
||||
glm_mat4_identity(instance->local_transform);
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void free_instance(struct RE_instance *instance)
|
||||
{
|
||||
if (instance->model)
|
||||
model_free(instance->model);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
struct RE_plugin *RE_plugin_new(void)
|
||||
{
|
||||
char *aar_path = gamedir_path("Data/ReignData.red");
|
||||
int error = ARCHIVE_SUCCESS;
|
||||
struct archive *aar = (struct archive *)aar_open(aar_path, ARCHIVE_MMAP, &error);
|
||||
if (error == ARCHIVE_FILE_ERROR) {
|
||||
WARNING("aar_open(\"%s\"): %s", display_utf0(aar_path), strerror(errno));
|
||||
} else if (error == ARCHIVE_BAD_ARCHIVE_ERROR) {
|
||||
WARNING("aar_open(\"%s\"): invalid AAR archive", display_utf0(aar_path));
|
||||
}
|
||||
free(aar_path);
|
||||
if (!aar)
|
||||
return NULL;
|
||||
|
||||
struct RE_plugin *plugin = xcalloc(1, sizeof(struct RE_plugin));
|
||||
plugin->plugin.name = "ReignEngine";
|
||||
plugin->plugin.update = RE_render;
|
||||
plugin->aar = aar;
|
||||
return plugin;
|
||||
}
|
||||
|
||||
void RE_plugin_free(struct RE_plugin *plugin)
|
||||
{
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++) {
|
||||
if (plugin->instances[i])
|
||||
free_instance(plugin->instances[i]);
|
||||
}
|
||||
archive_free(plugin->aar);
|
||||
if (plugin->renderer)
|
||||
RE_renderer_free(plugin->renderer);
|
||||
free(plugin);
|
||||
}
|
||||
|
||||
bool RE_plugin_bind(struct RE_plugin *plugin, int sprite)
|
||||
{
|
||||
struct sact_sprite *sp = sact_try_get_sprite(sprite);
|
||||
if (!sp)
|
||||
return false;
|
||||
plugin->renderer = RE_renderer_new(sprite_get_texture(sp));
|
||||
plugin->sprite = sprite;
|
||||
sprite_bind_plugin(sp, &plugin->plugin);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RE_plugin_unbind(struct RE_plugin *plugin)
|
||||
{
|
||||
if (!plugin || !plugin->renderer)
|
||||
return false;
|
||||
struct sact_sprite *sp = sact_try_get_sprite(plugin->sprite);
|
||||
if (sp)
|
||||
sprite_bind_plugin(sp, NULL);
|
||||
RE_renderer_free(plugin->renderer);
|
||||
plugin->renderer = NULL;
|
||||
plugin->sprite = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RE_set_projection(struct RE_plugin *plugin, float width, float height, float near, float far, float deg)
|
||||
{
|
||||
if (!plugin)
|
||||
return false;
|
||||
glm_perspective(glm_rad(deg), width / height, near, far, plugin->proj_transform);
|
||||
return true;
|
||||
}
|
||||
|
||||
int RE_create_instance(struct RE_plugin *plugin)
|
||||
{
|
||||
if (!plugin)
|
||||
return -1;
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++) {
|
||||
if (!plugin->instances[i]) {
|
||||
plugin->instances[i] = create_instance(plugin);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
WARNING("too many instances");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool RE_release_instance(struct RE_plugin *plugin, int instance)
|
||||
{
|
||||
if (!plugin || !plugin->instances[instance])
|
||||
return false;
|
||||
free_instance(plugin->instances[instance]);
|
||||
plugin->instances[instance] = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RE_instance_load(struct RE_instance *instance, const char *name)
|
||||
{
|
||||
if (!instance)
|
||||
return false;
|
||||
if (instance->model)
|
||||
model_free(instance->model);
|
||||
instance->model = model_load(instance->plugin->aar, name, instance->plugin->renderer);
|
||||
return !!instance->model;
|
||||
}
|
||||
|
||||
void RE_debug_print(struct RE_plugin *p)
|
||||
{
|
||||
printf("camera = { x: %f, y: %f, z: %f, pitch: %f, roll: %f, yaw: %f }",
|
||||
p->camera.pos[0], p->camera.pos[1], p->camera.pos[2],
|
||||
p->camera.pitch, p->camera.roll, p->camera.yaw);
|
||||
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++) {
|
||||
struct RE_instance *inst = p->instances[i];
|
||||
if (!inst || !inst->model)
|
||||
continue;
|
||||
printf("[%d] = {", i);
|
||||
printf(" name: \"%s\",", inst->model->name);
|
||||
printf(" type: %d,", inst->type);
|
||||
printf(" draw: %d,", inst->draw);
|
||||
printf(" pos: { x: %f, y: %f, z: %f },", inst->pos[0], inst->pos[1], inst->pos[2]);
|
||||
printf(" vec: { x: %f, y: %f, z: %f },", inst->vec[0], inst->vec[1], inst->vec[2]);
|
||||
printf(" scale: { x: %f, y: %f, z: %f },", inst->scale[0], inst->scale[1], inst->scale[2]);
|
||||
printf("}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/* Copyright (C) 2022 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cglm/cglm.h>
|
||||
|
||||
#include "system4.h"
|
||||
|
||||
#include "3d_internal.h"
|
||||
#include "reign.h"
|
||||
#include "sact.h"
|
||||
|
||||
struct RE_renderer *RE_renderer_new(struct texture *texture)
|
||||
{
|
||||
struct RE_renderer *r = xcalloc(1, sizeof(struct RE_renderer));
|
||||
|
||||
gfx_load_shader(&r->shader, "shaders/reign.v.glsl", "shaders/reign.f.glsl");
|
||||
r->local_transform = glGetUniformLocation(r->shader.program, "local_transform");
|
||||
r->proj_transform = glGetUniformLocation(r->shader.program, "proj_transform");
|
||||
r->vertex_normal = glGetAttribLocation(r->shader.program, "vertex_normal");
|
||||
r->vertex_uv = glGetAttribLocation(r->shader.program, "vertex_uv");
|
||||
|
||||
glGenRenderbuffers(1, &r->depth_buffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, r->depth_buffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, texture->w, texture->h);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void RE_renderer_free(struct RE_renderer *r)
|
||||
{
|
||||
glDeleteProgram(r->shader.program);
|
||||
glDeleteRenderbuffers(1, &r->depth_buffer);
|
||||
free(r);
|
||||
}
|
||||
|
||||
static void calc_view_matrix(struct RE_camera *camera, mat4 out)
|
||||
{
|
||||
vec3 front = { 0.0, 0.0, -1.0 };
|
||||
vec3 euler = {
|
||||
glm_rad(camera->pitch),
|
||||
glm_rad(camera->yaw),
|
||||
glm_rad(camera->roll)
|
||||
};
|
||||
mat4 rot;
|
||||
glm_euler(euler, rot);
|
||||
glm_mat4_mulv3(rot, front, 0.0, front);
|
||||
vec3 up = {0.0, 1.0, 0.0};
|
||||
glm_look(camera->pos, front, up, out);
|
||||
}
|
||||
|
||||
static void update_local_transform(struct RE_instance *inst)
|
||||
{
|
||||
vec3 euler = {
|
||||
glm_rad(inst->pitch),
|
||||
glm_rad(inst->yaw),
|
||||
glm_rad(inst->roll)
|
||||
};
|
||||
mat4 rot;
|
||||
glm_euler(euler, rot);
|
||||
|
||||
glm_translate_make(inst->local_transform, inst->pos);
|
||||
glm_mat4_mul(inst->local_transform, rot, inst->local_transform);
|
||||
glm_scale(inst->local_transform, inst->scale);
|
||||
|
||||
inst->local_transform_needs_update = false;
|
||||
}
|
||||
|
||||
static void render_instance(struct RE_instance *inst, struct RE_renderer *r, mat4 view_transform, mat4 proj_transform)
|
||||
{
|
||||
if (!inst->draw || !inst->model)
|
||||
return;
|
||||
|
||||
if (inst->local_transform_needs_update)
|
||||
update_local_transform(inst);
|
||||
|
||||
glUseProgram(r->shader.program);
|
||||
glUniformMatrix4fv(r->shader.view_transform, 1, GL_FALSE, view_transform[0]);
|
||||
glUniformMatrix4fv(r->proj_transform, 1, GL_FALSE, proj_transform[0]);
|
||||
glUniformMatrix4fv(r->local_transform, 1, GL_FALSE, inst->local_transform[0]);
|
||||
|
||||
struct model *model = inst->model;
|
||||
for (int i = 0; i < model->nr_meshes; i++) {
|
||||
struct mesh *mesh = &model->meshes[i];
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, model->materials[mesh->material].color_map);
|
||||
glUniform1i(r->shader.texture, 0);
|
||||
|
||||
glBindVertexArray(mesh->vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, mesh->nr_vertices);
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void RE_render(struct sact_sprite *sp)
|
||||
{
|
||||
struct RE_plugin *plugin = (struct RE_plugin *)sp->plugin;
|
||||
struct RE_renderer *r = plugin->renderer;
|
||||
if (!r)
|
||||
return;
|
||||
sprite_dirty(sp);
|
||||
struct texture *texture = sprite_get_texture(sp);
|
||||
|
||||
GLuint fbo = gfx_set_framebuffer(GL_DRAW_FRAMEBUFFER, texture, 0, 0, texture->w, texture->h);
|
||||
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, r->depth_buffer);
|
||||
if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
ERROR("Incomplete framebuffer");
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
mat4 view_transform;
|
||||
calc_view_matrix(&plugin->camera, view_transform);
|
||||
|
||||
// Tweak the projection transform so that the rendering result is vertically
|
||||
// flipped. If we render the scene normally, the resulting image will be
|
||||
// bottom-up (the first pixel is at the bottom-left), but we want a top-down
|
||||
// image (the first pixel is at the top-left). This changes the coordinate
|
||||
// system from right-handed to left-handed, we also need to reverse the
|
||||
// winding order.
|
||||
plugin->proj_transform[1][1] *= -1;
|
||||
glFrontFace(GL_CW);
|
||||
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++) {
|
||||
if (plugin->instances[i])
|
||||
render_instance(plugin->instances[i], r, view_transform, plugin->proj_transform);
|
||||
}
|
||||
|
||||
plugin->proj_transform[1][1] *= -1;
|
||||
glFrontFace(GL_CCW);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
gfx_reset_framebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
||||
}
|
||||
@@ -45,7 +45,7 @@
|
||||
#define M_PI (3.14159265358979323846)
|
||||
#endif
|
||||
|
||||
static void dungeon_render(struct draw_plugin *plugin);
|
||||
static void dungeon_render(struct sact_sprite *sp);
|
||||
|
||||
struct dungeon_context *dungeon_context_create(enum draw_dungeon_version version, int surface)
|
||||
{
|
||||
@@ -257,12 +257,11 @@ static void model_view_matrix(struct camera *camera, mat4 out)
|
||||
glm_lookat(eye, camera->pos, up, out);
|
||||
}
|
||||
|
||||
static void dungeon_render(struct draw_plugin *plugin)
|
||||
static void dungeon_render(struct sact_sprite *sp)
|
||||
{
|
||||
struct dungeon_context *ctx = (struct dungeon_context *)plugin;
|
||||
struct dungeon_context *ctx = (struct dungeon_context *)sp->plugin;
|
||||
if (!ctx->loaded || !ctx->draw_enabled)
|
||||
return;
|
||||
struct sact_sprite *sp = sact_get_sprite(ctx->surface);
|
||||
sprite_dirty(sp);
|
||||
struct texture *texture = sprite_get_texture(sp);
|
||||
|
||||
|
||||
@@ -338,6 +338,7 @@ extern struct static_library lib_OutputLog;
|
||||
extern struct static_library lib_PassRegister;
|
||||
extern struct static_library lib_PlayDemo;
|
||||
extern struct static_library lib_PlayMovie;
|
||||
extern struct static_library lib_ReignEngine;
|
||||
extern struct static_library lib_SACT2;
|
||||
extern struct static_library lib_SACTDX;
|
||||
extern struct static_library lib_SengokuRanceFont;
|
||||
@@ -401,6 +402,7 @@ static struct static_library *static_libraries[] = {
|
||||
&lib_PassRegister,
|
||||
&lib_PlayDemo,
|
||||
&lib_PlayMovie,
|
||||
&lib_ReignEngine,
|
||||
&lib_SACT2,
|
||||
&lib_SACTDX,
|
||||
&lib_SengokuRanceFont,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,11 @@ xsystem4 = [version_h,
|
||||
'video.c',
|
||||
'vm.c',
|
||||
|
||||
'3d/model.c',
|
||||
'3d/parser.c',
|
||||
'3d/reign.c',
|
||||
'3d/renderer.c',
|
||||
|
||||
'dungeon/dgn.c',
|
||||
'dungeon/dtx.c',
|
||||
'dungeon/dungeon.c',
|
||||
@@ -98,6 +103,7 @@ xsystem4 = [version_h,
|
||||
'hll/PassRegister.c',
|
||||
'hll/PlayDemo.c',
|
||||
'hll/PlayMovie.c',
|
||||
'hll/ReignEngine.c',
|
||||
'hll/SACT2.c',
|
||||
'hll/SengokuRanceFont.c',
|
||||
'hll/SoundFilePlayer.c',
|
||||
|
||||
+1
-1
@@ -338,7 +338,7 @@ void sprite_call_plugins(void)
|
||||
{
|
||||
struct sact_sprite *sp;
|
||||
LIST_FOREACH(sp, &sprites_with_plugins, entry) {
|
||||
sp->plugin->update(sp->plugin);
|
||||
sp->plugin->update(sp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
Submodule subprojects/libsys4 updated: 965d89e1c1...3797afa47d
Reference in New Issue
Block a user