mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-05 13:28:04 +03:00
DrawDungeon14: Draw 3D objects in PolyObj.lin
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/* Copyright (C) 2021 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_POLYOBJ_H
|
||||
#define SYSTEM4_POLYOBJ_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <cglm/types.h>
|
||||
|
||||
struct polyobj_location {
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
struct polyobj {
|
||||
uint8_t *data;
|
||||
size_t size;
|
||||
int nr_textures;
|
||||
struct polyobj_location *textures;
|
||||
int nr_objects;
|
||||
struct polyobj_location *objects;
|
||||
};
|
||||
|
||||
struct polyobj_triangle {
|
||||
int material;
|
||||
int index[3];
|
||||
vec2 uv[3];
|
||||
};
|
||||
|
||||
struct polyobj_part {
|
||||
int nr_vertices;
|
||||
vec3 *vertices;
|
||||
int nr_triangles;
|
||||
struct polyobj_triangle *triangles;
|
||||
};
|
||||
|
||||
struct polyobj_object {
|
||||
char *name;
|
||||
int nr_materials;
|
||||
int *materials;
|
||||
int nr_parts;
|
||||
struct polyobj_part *parts;
|
||||
};
|
||||
|
||||
struct polyobj *polyobj_load(const char *path);
|
||||
void polyobj_free(struct polyobj *po);
|
||||
struct cg *polyobj_get_texture(struct polyobj *po, int index);
|
||||
struct polyobj_object *polyobj_get_object(struct polyobj *po, int index);
|
||||
void polyobj_object_free(struct polyobj_object *obj);
|
||||
|
||||
#endif /* SYSTEM4_POLYOBJ_H */
|
||||
@@ -22,9 +22,10 @@
|
||||
|
||||
struct dgn_cell;
|
||||
struct dtx;
|
||||
struct polyobj;
|
||||
struct dungeon_renderer;
|
||||
|
||||
struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version version, struct dtx *dtx, GLuint *event_textures, int nr_event_textures);
|
||||
struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version version, struct dtx *dtx, GLuint *event_textures, int nr_event_textures, struct polyobj *po);
|
||||
void dungeon_renderer_free(struct dungeon_renderer *r);
|
||||
void dungeon_renderer_render(struct dungeon_renderer *r, struct dgn_cell **cells, int nr_cells, mat4 view_transform, mat4 proj_transform);
|
||||
void dungeon_renderer_enable_event_markers(struct dungeon_renderer *r, bool enable);
|
||||
|
||||
+15
-1
@@ -31,6 +31,7 @@
|
||||
#include "dungeon/dtx.h"
|
||||
#include "dungeon/dungeon.h"
|
||||
#include "dungeon/map.h"
|
||||
#include "dungeon/polyobj.h"
|
||||
#include "dungeon/renderer.h"
|
||||
#include "dungeon/tes.h"
|
||||
#include "gfx/gfx.h"
|
||||
@@ -127,6 +128,8 @@ static GLuint *load_event_textures(int *nr_textures_out)
|
||||
|
||||
bool dungeon_load(struct dungeon_context *ctx, int num)
|
||||
{
|
||||
struct polyobj *polyobj = NULL;
|
||||
|
||||
if (ctx->loaded)
|
||||
VM_ERROR("Dungeon is already loaded");
|
||||
|
||||
@@ -185,6 +188,14 @@ bool dungeon_load(struct dungeon_context *ctx, int num)
|
||||
free(tes);
|
||||
}
|
||||
free(path);
|
||||
|
||||
char *polyobj_path = gamedir_path("Data/PolyObj.lin");
|
||||
polyobj = polyobj_load(polyobj_path);
|
||||
free(polyobj_path);
|
||||
if (!polyobj) {
|
||||
WARNING("Cannot load Data/PolyObj.lin");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ERROR("Invalid DrawDungeon version %d", ctx->version);
|
||||
}
|
||||
@@ -199,7 +210,10 @@ bool dungeon_load(struct dungeon_context *ctx, int num)
|
||||
if (!event_textures)
|
||||
return false;
|
||||
|
||||
ctx->renderer = dungeon_renderer_create(ctx->version, ctx->dtx, event_textures, nr_event_textures);
|
||||
ctx->renderer = dungeon_renderer_create(ctx->version, ctx->dtx, event_textures, nr_event_textures, polyobj);
|
||||
|
||||
if (polyobj)
|
||||
polyobj_free(polyobj);
|
||||
|
||||
dungeon_map_init(ctx);
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/* Copyright (C) 2021 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 "system4.h"
|
||||
#include "system4/buffer.h"
|
||||
#include "system4/cg.h"
|
||||
#include "system4/file.h"
|
||||
|
||||
#include "dungeon/polyobj.h"
|
||||
|
||||
struct polyobj *polyobj_load(const char *path)
|
||||
{
|
||||
size_t size;
|
||||
uint8_t *data = file_read(path, &size);
|
||||
if (!data)
|
||||
return NULL;
|
||||
struct buffer r;
|
||||
buffer_init(&r, data, size);
|
||||
if (memcmp(buffer_strdata(&r), "POL\0\0\0\0\0", 8))
|
||||
return NULL;
|
||||
buffer_skip(&r, 8);
|
||||
|
||||
struct polyobj *po = xcalloc(1, sizeof(struct polyobj));
|
||||
po->data = data;
|
||||
po->size = size;
|
||||
po->nr_textures = buffer_read_int32(&r);
|
||||
po->textures = xcalloc(po->nr_textures, sizeof(struct polyobj_location));
|
||||
for (int i = 0; i < po->nr_textures; i++) {
|
||||
po->textures[i].offset = buffer_read_int32(&r);
|
||||
po->textures[i].length = buffer_read_int32(&r);
|
||||
}
|
||||
po->nr_objects = buffer_read_int32(&r);
|
||||
po->objects = xcalloc(po->nr_objects, sizeof(struct polyobj_location));
|
||||
for (int i = 0; i < po->nr_objects; i++) {
|
||||
po->objects[i].offset = buffer_read_int32(&r);
|
||||
po->objects[i].length = buffer_read_int32(&r);
|
||||
}
|
||||
return po;
|
||||
}
|
||||
|
||||
void polyobj_free(struct polyobj *po)
|
||||
{
|
||||
free(po->textures);
|
||||
free(po->objects);
|
||||
free(po->data);
|
||||
free(po);
|
||||
}
|
||||
|
||||
struct cg *polyobj_get_texture(struct polyobj *po, int index)
|
||||
{
|
||||
if (index < 0 || index >= po->nr_textures)
|
||||
return NULL;
|
||||
struct polyobj_location *loc = &po->textures[index];
|
||||
return cg_load_buffer(po->data + loc->offset, loc->length);
|
||||
}
|
||||
|
||||
struct polyobj_object *polyobj_get_object(struct polyobj *po, int index)
|
||||
{
|
||||
if (index < 0 || index >= po->nr_objects)
|
||||
return NULL;
|
||||
struct polyobj_location *loc = &po->objects[index];
|
||||
struct buffer r;
|
||||
buffer_init(&r, po->data + loc->offset, loc->length);
|
||||
|
||||
struct polyobj_object *obj = xcalloc(1, sizeof(struct polyobj_object));
|
||||
obj->name = strdup(buffer_strdata(&r));
|
||||
buffer_skip(&r, strlen(obj->name) + 1);
|
||||
if (memcmp(buffer_strdata(&r), "POO\0\0\0\0\0", 8)) {
|
||||
polyobj_object_free(obj);
|
||||
return NULL;
|
||||
}
|
||||
buffer_skip(&r, 8);
|
||||
obj->nr_materials = buffer_read_int32(&r);
|
||||
obj->materials = xcalloc(obj->nr_materials, sizeof(int));
|
||||
for (int i = 0; i < obj->nr_materials; i++)
|
||||
obj->materials[i] = buffer_read_int32(&r);
|
||||
obj->nr_parts = buffer_read_int32(&r);
|
||||
obj->parts = xcalloc(obj->nr_parts, sizeof(struct polyobj_part));
|
||||
for (int i = 0; i < obj->nr_parts; i++) {
|
||||
struct polyobj_part *part = &obj->parts[i];
|
||||
part->nr_vertices = buffer_read_int32(&r);
|
||||
part->vertices = xcalloc(part->nr_vertices, sizeof(vec3));
|
||||
for (int j = 0; j < part->nr_vertices; j++) {
|
||||
part->vertices[j][0] = buffer_read_float(&r);
|
||||
part->vertices[j][1] = buffer_read_float(&r);
|
||||
part->vertices[j][2] = buffer_read_float(&r);
|
||||
}
|
||||
|
||||
part->nr_triangles = buffer_read_int32(&r);
|
||||
part->triangles = xcalloc(part->nr_triangles, sizeof(struct polyobj_triangle));
|
||||
for (int j = 0; j < part->nr_triangles; j++) {
|
||||
struct polyobj_triangle *triangle = &part->triangles[j];
|
||||
triangle->material = buffer_read_int32(&r);
|
||||
triangle->index[0] = buffer_read_int32(&r);
|
||||
triangle->index[1] = buffer_read_int32(&r);
|
||||
triangle->index[2] = buffer_read_int32(&r);
|
||||
triangle->uv[0][0] = buffer_read_float(&r);
|
||||
triangle->uv[0][1] = buffer_read_float(&r);
|
||||
triangle->uv[1][0] = buffer_read_float(&r);
|
||||
triangle->uv[1][1] = buffer_read_float(&r);
|
||||
triangle->uv[2][0] = buffer_read_float(&r);
|
||||
triangle->uv[2][1] = buffer_read_float(&r);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
void polyobj_object_free(struct polyobj_object *obj)
|
||||
{
|
||||
for (int i = 0; i < obj->nr_parts; i++) {
|
||||
struct polyobj_part *part = &obj->parts[i];
|
||||
free(part->vertices);
|
||||
free(part->triangles);
|
||||
}
|
||||
free(obj->parts);
|
||||
free(obj->materials);
|
||||
free(obj->name);
|
||||
free(obj);
|
||||
}
|
||||
+129
-15
@@ -20,11 +20,13 @@
|
||||
#include <cglm/cglm.h>
|
||||
#include <GL/glew.h>
|
||||
#include "system4.h"
|
||||
#include "system4/buffer.h"
|
||||
#include "system4/cg.h"
|
||||
|
||||
#include "dungeon/dungeon.h"
|
||||
#include "dungeon/dgn.h"
|
||||
#include "dungeon/dtx.h"
|
||||
#include "dungeon/polyobj.h"
|
||||
#include "dungeon/renderer.h"
|
||||
#include "dungeon/skybox.h"
|
||||
#include "gfx/gfx.h"
|
||||
@@ -73,6 +75,7 @@ static const struct marker_info *marker_tables[] = {
|
||||
|
||||
struct geometry;
|
||||
struct material;
|
||||
struct object3d;
|
||||
|
||||
struct dungeon_renderer {
|
||||
struct shader shader;
|
||||
@@ -99,6 +102,11 @@ struct dungeon_renderer {
|
||||
const struct marker_info *marker_table;
|
||||
bool draw_event_markers;
|
||||
|
||||
int nr_polyobjs;
|
||||
struct object3d *polyobjs;
|
||||
int nr_polyobj_materials;
|
||||
struct material *polyobj_materials;
|
||||
|
||||
struct skybox *skybox;
|
||||
};
|
||||
|
||||
@@ -189,12 +197,14 @@ struct geometry {
|
||||
GLuint vao;
|
||||
GLuint attr_buffer;
|
||||
int nr_vertices;
|
||||
GLenum mode;
|
||||
};
|
||||
|
||||
static struct geometry *geometry_create(struct dungeon_renderer *r, const struct vertex *vertices, size_t size)
|
||||
static struct geometry *geometry_create(struct dungeon_renderer *r, const struct vertex *vertices, size_t size, GLenum mode)
|
||||
{
|
||||
struct geometry *g = xcalloc(1, sizeof(struct geometry));
|
||||
g->nr_vertices = size / sizeof(struct vertex);
|
||||
g->mode = mode;
|
||||
|
||||
glGenVertexArrays(1, &g->vao);
|
||||
glBindVertexArray(g->vao);
|
||||
@@ -224,11 +234,8 @@ struct material {
|
||||
bool opaque;
|
||||
};
|
||||
|
||||
static void init_material(struct material *m, struct dtx *dtx, int type, int index)
|
||||
static void init_material(struct material *m, struct cg *cg)
|
||||
{
|
||||
struct cg *cg = dtx_create_cg(dtx, type, index);
|
||||
if (!cg)
|
||||
return;
|
||||
glGenTextures(1, &m->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m->texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cg->metrics.w, cg->metrics.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, cg->pixels);
|
||||
@@ -239,7 +246,6 @@ static void init_material(struct material *m, struct dtx *dtx, int type, int ind
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
m->opaque = !cg->metrics.has_alpha;
|
||||
cg_free(cg);
|
||||
}
|
||||
|
||||
static void delete_material(struct material *m)
|
||||
@@ -256,7 +262,77 @@ static struct material *get_material(struct dungeon_renderer *r, int type, int i
|
||||
return m;
|
||||
}
|
||||
|
||||
struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version version, struct dtx *dtx, GLuint *event_textures, int nr_event_textures)
|
||||
struct mesh {
|
||||
struct geometry *geometry;
|
||||
int material;
|
||||
};
|
||||
|
||||
struct object3d {
|
||||
int nr_meshes;
|
||||
struct mesh *meshes;
|
||||
};
|
||||
|
||||
static void init_object3d(struct object3d *o3d, struct dungeon_renderer *r, const struct polyobj_object *obj)
|
||||
{
|
||||
o3d->nr_meshes = obj->nr_materials;
|
||||
o3d->meshes = xcalloc(obj->nr_materials, sizeof(struct mesh));
|
||||
for (int i = 0; i < obj->nr_materials; i++)
|
||||
o3d->meshes[i].material = obj->materials[i];
|
||||
|
||||
struct buffer *bufs = xcalloc(obj->nr_materials, sizeof(struct buffer));
|
||||
for (int i = 0; i < obj->nr_parts; i++) {
|
||||
const struct polyobj_part *part = &obj->parts[i];
|
||||
for (int j = 0; j < part->nr_triangles; j++) {
|
||||
const struct polyobj_triangle *triangle = &part->triangles[j];
|
||||
for (int k = 0; k < 3; k++) {
|
||||
const int ltor[] = {0, 2, 1}; // left->right handed system
|
||||
const vec3 *pos = &part->vertices[triangle->index[ltor[k]]];
|
||||
const vec2 *uv = &triangle->uv[ltor[k]];
|
||||
buffer_write_float(&bufs[triangle->material], (*pos)[0]); // x
|
||||
buffer_write_float(&bufs[triangle->material], (*pos)[1]); // y
|
||||
buffer_write_float(&bufs[triangle->material], -(*pos)[2]); // z
|
||||
buffer_write_float(&bufs[triangle->material], (*uv)[0]); // u
|
||||
buffer_write_float(&bufs[triangle->material], (*uv)[1]); // v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < obj->nr_materials; i++) {
|
||||
o3d->meshes[i].geometry = geometry_create(r, (const struct vertex *)bufs[i].buf, bufs[i].index, GL_TRIANGLES);
|
||||
free(bufs[i].buf);
|
||||
}
|
||||
free(bufs);
|
||||
}
|
||||
|
||||
static void delete_object3d(struct object3d *o3d)
|
||||
{
|
||||
for (int i = 0; i < o3d->nr_meshes; i++)
|
||||
geometry_free(o3d->meshes[i].geometry);
|
||||
free(o3d->meshes);
|
||||
}
|
||||
|
||||
static void init_polyobjs(struct dungeon_renderer *r, struct polyobj *po)
|
||||
{
|
||||
r->nr_polyobj_materials = po->nr_textures;
|
||||
r->polyobj_materials = xcalloc(po->nr_textures, sizeof(struct material));
|
||||
for (int i = 0; i < po->nr_textures; i++) {
|
||||
struct cg *cg = polyobj_get_texture(po, i);
|
||||
init_material(&r->polyobj_materials[i], cg);
|
||||
cg_free(cg);
|
||||
}
|
||||
|
||||
r->nr_polyobjs = po->nr_objects;
|
||||
r->polyobjs = xcalloc(po->nr_objects, sizeof(struct object3d));
|
||||
for (int i = 0; i < po->nr_objects; i++) {
|
||||
struct polyobj_object *obj = polyobj_get_object(po, i);
|
||||
if (!obj)
|
||||
continue;
|
||||
init_object3d(&r->polyobjs[i], r, obj);
|
||||
polyobj_object_free(obj);
|
||||
}
|
||||
}
|
||||
|
||||
struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version version, struct dtx *dtx, GLuint *event_textures, int nr_event_textures, struct polyobj *po)
|
||||
{
|
||||
struct dungeon_renderer *r = xcalloc(1, sizeof(struct dungeon_renderer));
|
||||
|
||||
@@ -266,18 +342,22 @@ struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version versi
|
||||
r->alpha_mod = glGetUniformLocation(r->shader.program, "alpha_mod");
|
||||
r->vertex_uv = glGetAttribLocation(r->shader.program, "vertex_uv");
|
||||
|
||||
r->wall_geometry = geometry_create(r, wall_vertices, sizeof(wall_vertices));
|
||||
r->door_left_geometry = geometry_create(r, door_left_vertices, sizeof(door_left_vertices));
|
||||
r->door_right_geometry = geometry_create(r, door_right_vertices, sizeof(door_right_vertices));
|
||||
r->roof_geometry = geometry_create(r, roof_vertices, sizeof(roof_vertices));
|
||||
r->stairs_geometry = geometry_create(r, stairs_vertices, sizeof(stairs_vertices));
|
||||
r->floating_marker_geometry = geometry_create(r, floating_marker_vertices, sizeof(floating_marker_vertices));
|
||||
r->wall_geometry = geometry_create(r, wall_vertices, sizeof(wall_vertices), GL_TRIANGLE_STRIP);
|
||||
r->door_left_geometry = geometry_create(r, door_left_vertices, sizeof(door_left_vertices), GL_TRIANGLE_STRIP);
|
||||
r->door_right_geometry = geometry_create(r, door_right_vertices, sizeof(door_right_vertices), GL_TRIANGLE_STRIP);
|
||||
r->roof_geometry = geometry_create(r, roof_vertices, sizeof(roof_vertices), GL_TRIANGLE_STRIP);
|
||||
r->stairs_geometry = geometry_create(r, stairs_vertices, sizeof(stairs_vertices), GL_TRIANGLE_STRIP);
|
||||
r->floating_marker_geometry = geometry_create(r, floating_marker_vertices, sizeof(floating_marker_vertices), GL_TRIANGLE_STRIP);
|
||||
|
||||
const int nr_types = DTX_DOOR + 1;
|
||||
r->materials = xcalloc(nr_types * dtx->nr_columns, sizeof(struct material));
|
||||
for (int type = 0; type < nr_types; type++) {
|
||||
for (int i = 0; i < dtx->nr_columns; i++) {
|
||||
init_material(&r->materials[type * dtx->nr_columns + i], dtx, type, i);
|
||||
struct cg *cg = dtx_create_cg(dtx, type, i);
|
||||
if (!cg)
|
||||
continue;
|
||||
init_material(&r->materials[type * dtx->nr_columns + i], cg);
|
||||
cg_free(cg);
|
||||
}
|
||||
}
|
||||
r->nr_dtx_columns = dtx->nr_columns;
|
||||
@@ -288,6 +368,9 @@ struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version versi
|
||||
r->marker_table = marker_tables[version];
|
||||
r->draw_event_markers = true;
|
||||
|
||||
if (po)
|
||||
init_polyobjs(r, po);
|
||||
|
||||
r->skybox = skybox_create(dtx);
|
||||
|
||||
return r;
|
||||
@@ -311,6 +394,13 @@ void dungeon_renderer_free(struct dungeon_renderer *r)
|
||||
glDeleteTextures(r->nr_event_textures, r->event_textures);
|
||||
free(r->event_textures);
|
||||
|
||||
for (int i = 0; i < r->nr_polyobjs; i++)
|
||||
delete_object3d(&r->polyobjs[i]);
|
||||
free(r->polyobjs);
|
||||
for (int i = 0; i < r->nr_polyobj_materials; i++)
|
||||
delete_material(&r->polyobj_materials[i]);
|
||||
free(r->polyobj_materials);
|
||||
|
||||
skybox_free(r->skybox);
|
||||
|
||||
free(r);
|
||||
@@ -326,7 +416,7 @@ static void draw(struct dungeon_renderer *r, struct geometry *geometry, GLuint t
|
||||
glUniform1i(r->shader.texture, 0);
|
||||
|
||||
glBindVertexArray(geometry->vao);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, geometry->nr_vertices);
|
||||
glDrawArrays(geometry->mode, 0, geometry->nr_vertices);
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
@@ -397,6 +487,22 @@ static void draw_floating_marker(struct dungeon_renderer *r, const struct marker
|
||||
glUniform1f(r->alpha_mod, 1.0);
|
||||
}
|
||||
|
||||
static void draw_object3d(struct dungeon_renderer *r, struct object3d *o3d, bool render_opaque, vec3 pos, float scale, float rotation_y)
|
||||
{
|
||||
mat4 m;
|
||||
glm_translate_make(m, pos);
|
||||
glm_rotate_y(m, glm_rad(rotation_y), m);
|
||||
glm_scale_uni(m, scale);
|
||||
|
||||
for (int i = 0; i < o3d->nr_meshes; i++) {
|
||||
struct mesh *mesh = &o3d->meshes[i];
|
||||
struct material *material = &r->polyobj_materials[mesh->material];
|
||||
if (material->opaque != render_opaque)
|
||||
continue;
|
||||
draw(r, mesh->geometry, material->texture, m);
|
||||
}
|
||||
}
|
||||
|
||||
static void stairs_matrix(mat4 dst, float x, float y, float z, int orientation)
|
||||
{
|
||||
vec3 pos = {x, y, z};
|
||||
@@ -551,6 +657,14 @@ static void draw_cell(struct dungeon_renderer *r, struct dgn_cell *cell, bool re
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
}
|
||||
if (cell->polyobj_index >= 0) {
|
||||
vec3 pos = {
|
||||
x + cell->polyobj_position_x,
|
||||
y + cell->polyobj_position_y - 1,
|
||||
z - cell->polyobj_position_z
|
||||
};
|
||||
draw_object3d(r, &r->polyobjs[cell->polyobj_index], render_opaque, pos, cell->polyobj_scale, cell->polyobj_rotation_y);
|
||||
}
|
||||
if (r->draw_event_markers && cell->floor_event && !render_opaque) {
|
||||
const struct marker_info *info = get_marker_info(r, cell->floor_event);
|
||||
if (info) {
|
||||
|
||||
@@ -23,6 +23,7 @@ xsystem4 = ['audio.c',
|
||||
'dungeon/dtx.c',
|
||||
'dungeon/dungeon.c',
|
||||
'dungeon/map.c',
|
||||
'dungeon/polyobj.c',
|
||||
'dungeon/renderer.c',
|
||||
'dungeon/skybox.c',
|
||||
'dungeon/tes.c',
|
||||
|
||||
Reference in New Issue
Block a user