The camera view direction was computed incorrectly in two ways:
1. glm_euler (XYZ order) applies pitch around world X. The original
engine uses YXZ where pitch is around the camera's local X after yaw.
2. SetCameraAngle negated the input yaw.
POL v4 introduces material groups with texture blending. A material's
sub-material can be a "blend group" containing exactly two leaf
materials, whose textures are blended using per-vertex weights for
smooth terrain transitions.
The `defines` string in load_shader() is prepended to the glsl file, but
it was not terminated with a newline, so the resulting shader source
looked like this:
#define REIGN_ENGINE 0
#define TAPIR_ENGINE 1
#define ENGINE 1/* Copyright (C) ...
*
* This program is free software; ...
...
This confused some OpenGL ES implementations, causing a syntax error.
https://github.com/kichikuou/xsystem4-android/issues/15
Skinned models can have multiple texture images for animation. When a
material colormap in the .pol file is `image.png`, additional images are
stored with names like `image[1].png`, `image[2].png`, etc.
Animation frame information is stored in `<motion_name>.txa` file. This
is a text file containing newline-separated integers, specifying the
texture index for each motion frame.
In ReignEngine, alpha blending is the default. Alpha testing is used if
the mesh/material has the (sprite) attribute.
In TapirEngine, alpha testing is the default. Alpha blending is used if
the mesh/material has the (alpha) attribute.
Before this, the BoneTransforms uniform block consumed
(4 * 4 * sizeof(float) * MAX_BONES) = 19712 bytes, which exceeds 16384,
the minimum possible value of GL_MAX_UNIFORM_BLOCK_SIZE in OpenGL ES
3.2.
Since the bone matrices are affine, we can drop the 4th rows and pack
them into a mat4x3 array. Now the BoneTransforms block is 14784 bytes
and it should work with all OpenGL ES 3.2 implementations.
In TapirEngine, the following lighting features are not used:
- global ambient
- directional lights
- specular lights
- rim lights
- fog
(The setters / getters for these parameters are still there, but they
don't affect rendering.)
This implementation disables those features in GLSL using #ifdefs. The C
code that sets up the lighting remains almost unchanged --
glGetUniformLocation() will return -1 if the specified uniform variable
name is not found, and glUniform*(-1, ...) will be no-op.
This is the maximum number of bones in a model for Rance Quest
(pasuteru_full.POL).
Now bone transform matrices are stored in a uniform buffer object,
because its size exceeds GL_MAX_VERTEX_UNIFORM_COMPONENTS in iOS Safari.
- Use glm_look_anyup() to avoid singularities when the shadow light
direction is parallel to the up vector
- Fix bounding sphere calculation when there are multiple shadow casters
TapirEngine is the 3D rendering engine used in RanceQuest.
This implements the minimum functionality that is needed to render the
first battle scene. The lighting is still incorrect.
This fixes an issue where height detection fails due to gaps in
suspension bridge planks.
If the depth map has no value for the given point, return the average
of 4 neighbors.
Now parsed particle-effect definitions are cached in a hash map in the
plugin object. To make it possible, static part of `struct
particle_effect` and `struct particle_object` are factored out to
`struct pae` and `struct pae_object` respectively.
It visualizes the bounding sphere of the instance. Although it is only
called from dead code in Toushin Toshi 3, it's useful for debugging
shadow mapping.
This fixes broken shadow rendering e.g. when Nacht climbs a ladder.
Now update_bones() calculates the instance's bounding sphere which
is the minimum sphere containing the AABB of current bone coordinates.
This corresponds to the sphere that is displayed when calling
SetInstanceDebugDrawShadowVolume on the original ReignEngine.dll.
This fixes billboard rendering issue in some dungeons.
* For polygon models, use its AABB's center coordinates.
* Consider the camera angle, i.e. sort by view-space Z-coordinate
instead of world-space Z-coordinate.
There are two types of transparent materials: materials that have an
alpha map and materials that have a color map with an alpha channel.
This change makes the latter to be considered transparent.
Before this, the order of drawing was determined on an instance-by-
instance basis. Instances with even a single transparent material were
drawn after fully opaque instances.
After this, first the opaque meshes in all instances are drawn, and then
the transparent meshes are drawn from the nearest to the farthest.