mirror of https://github.com/sm64pc/sm64pc.git
Reflection fresnel support, change API to require texture name instead of texture hash, support ray picking to edit texture mods.
This commit is contained in:
parent
470a1bb5e5
commit
44fbecce37
|
@ -24,19 +24,20 @@
|
|||
#define RT64_MATERIAL_CC_SHADER_TEXEL1 7
|
||||
|
||||
// Material attributes.
|
||||
#define RT64_ATTRIBUTE_NONE 0x0
|
||||
#define RT64_ATTRIBUTE_IGNORE_NORMAL_FACTOR 0x1
|
||||
#define RT64_ATTRIBUTE_NORMAL_MAP_SCALE 0x2
|
||||
#define RT64_ATTRIBUTE_REFLECTION_FACTOR 0x4
|
||||
#define RT64_ATTRIBUTE_REFLECTION_SHINE_FACTOR 0x8
|
||||
#define RT64_ATTRIBUTE_REFRACTION_FACTOR 0x10
|
||||
#define RT64_ATTRIBUTE_SPECULAR_INTENSITY 0x20
|
||||
#define RT64_ATTRIBUTE_SPECULAR_EXPONENT 0x40
|
||||
#define RT64_ATTRIBUTE_SOLID_ALPHA_MULTIPLIER 0x80
|
||||
#define RT64_ATTRIBUTE_SHADOW_ALPHA_MULTIPLIER 0x100
|
||||
#define RT64_ATTRIBUTE_SELF_LIGHT 0x200
|
||||
#define RT64_ATTRIBUTE_LIGHT_GROUP_MASK_BITS 0x400
|
||||
#define RT64_ATTRIBUTE_DIFFUSE_COLOR_MIX 0x800
|
||||
#define RT64_ATTRIBUTE_NONE 0x0000
|
||||
#define RT64_ATTRIBUTE_IGNORE_NORMAL_FACTOR 0x0001
|
||||
#define RT64_ATTRIBUTE_NORMAL_MAP_SCALE 0x0002
|
||||
#define RT64_ATTRIBUTE_REFLECTION_FACTOR 0x0004
|
||||
#define RT64_ATTRIBUTE_REFLECTION_FRESNEL_FACTOR 0x0008
|
||||
#define RT64_ATTRIBUTE_REFLECTION_SHINE_FACTOR 0x0010
|
||||
#define RT64_ATTRIBUTE_REFRACTION_FACTOR 0x0020
|
||||
#define RT64_ATTRIBUTE_SPECULAR_INTENSITY 0x0040
|
||||
#define RT64_ATTRIBUTE_SPECULAR_EXPONENT 0x0080
|
||||
#define RT64_ATTRIBUTE_SOLID_ALPHA_MULTIPLIER 0x0100
|
||||
#define RT64_ATTRIBUTE_SHADOW_ALPHA_MULTIPLIER 0x0200
|
||||
#define RT64_ATTRIBUTE_SELF_LIGHT 0x0400
|
||||
#define RT64_ATTRIBUTE_LIGHT_GROUP_MASK_BITS 0x0800
|
||||
#define RT64_ATTRIBUTE_DIFFUSE_COLOR_MIX 0x1000
|
||||
|
||||
// Mesh flags.
|
||||
#define RT64_MESH_RAYTRACE_ENABLED 0x1
|
||||
|
@ -83,6 +84,7 @@ typedef struct {
|
|||
float ignoreNormalFactor;
|
||||
float normalMapScale;
|
||||
float reflectionFactor;
|
||||
float reflectionFresnelFactor;
|
||||
float reflectionShineFactor;
|
||||
float refractionFactor;
|
||||
float specularIntensity;
|
||||
|
@ -95,7 +97,6 @@ typedef struct {
|
|||
RT64_VECTOR4 diffuseColorMix;
|
||||
float fogMul;
|
||||
float fogOffset;
|
||||
int _padA;
|
||||
|
||||
// N64 Color combiner parameters.
|
||||
int c0[4];
|
||||
|
@ -153,6 +154,10 @@ inline void RT64_ApplyMaterialAttributes(RT64_MATERIAL *dst, RT64_MATERIAL *src)
|
|||
dst->reflectionFactor = src->reflectionFactor;
|
||||
}
|
||||
|
||||
if (src->enabledAttributes & RT64_ATTRIBUTE_REFLECTION_FRESNEL_FACTOR) {
|
||||
dst->reflectionFresnelFactor = src->reflectionFresnelFactor;
|
||||
}
|
||||
|
||||
if (src->enabledAttributes & RT64_ATTRIBUTE_REFLECTION_SHINE_FACTOR) {
|
||||
dst->reflectionShineFactor = src->reflectionShineFactor;
|
||||
}
|
||||
|
@ -196,6 +201,7 @@ typedef void(*DrawDevicePtr)(RT64_DEVICE* device, int vsyncInterval);
|
|||
typedef void(*DestroyDevicePtr)(RT64_DEVICE* device);
|
||||
typedef RT64_VIEW* (*CreateViewPtr)(RT64_SCENE* scenePtr);
|
||||
typedef void(*SetViewPerspectivePtr)(RT64_VIEW* viewPtr, RT64_VECTOR3 eyePosition, RT64_VECTOR3 eyeFocus, RT64_VECTOR3 eyeUpDirection, float fovRadians, float nearDist, float farDist);
|
||||
typedef RT64_INSTANCE* (*GetViewRaytracedInstanceAtPtr)(RT64_VIEW *viewPtr, int x, int y);
|
||||
typedef void(*DestroyViewPtr)(RT64_VIEW* viewPtr);
|
||||
typedef RT64_SCENE* (*CreateScenePtr)(RT64_DEVICE* devicePtr);
|
||||
typedef void (*SetSceneLightsPtr)(RT64_SCENE* scenePtr, RT64_LIGHT* lightArray, int lightCount);
|
||||
|
@ -210,7 +216,7 @@ typedef RT64_TEXTURE* (*CreateTextureFromRGBA8Ptr)(RT64_DEVICE* devicePtr, const
|
|||
typedef void(*DestroyTexturePtr)(RT64_TEXTURE* texture);
|
||||
typedef RT64_INSPECTOR* (*CreateInspectorPtr)(RT64_DEVICE* devicePtr);
|
||||
typedef bool(*HandleMessageInspectorPtr)(RT64_INSPECTOR* inspectorPtr, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
typedef void (*SetMaterialInspectorPtr)(RT64_INSPECTOR* inspectorPtr, RT64_MATERIAL* material);
|
||||
typedef void (*SetMaterialInspectorPtr)(RT64_INSPECTOR* inspectorPtr, RT64_MATERIAL* material, const char *materialName);
|
||||
typedef void(*SetLightsInspectorPtr)(RT64_INSPECTOR* inspectorPtr, RT64_LIGHT* lights, int *lightCount, int maxLightCount);
|
||||
typedef void(*PrintToInspectorPtr)(RT64_INSPECTOR* inspectorPtr, const char* message);
|
||||
typedef void(*DestroyInspectorPtr)(RT64_INSPECTOR* inspectorPtr);
|
||||
|
@ -223,6 +229,7 @@ typedef struct {
|
|||
DestroyDevicePtr DestroyDevice;
|
||||
CreateViewPtr CreateView;
|
||||
SetViewPerspectivePtr SetViewPerspective;
|
||||
GetViewRaytracedInstanceAtPtr GetViewRaytracedInstanceAt;
|
||||
DestroyViewPtr DestroyView;
|
||||
CreateScenePtr CreateScene;
|
||||
SetSceneLightsPtr SetSceneLights;
|
||||
|
@ -258,6 +265,7 @@ inline RT64_LIBRARY RT64_LoadLibrary() {
|
|||
lib.DestroyDevice = (DestroyDevicePtr)(GetProcAddress(lib.handle, "RT64_DestroyDevice"));
|
||||
lib.CreateView = (CreateViewPtr)(GetProcAddress(lib.handle, "RT64_CreateView"));
|
||||
lib.SetViewPerspective = (SetViewPerspectivePtr)(GetProcAddress(lib.handle, "RT64_SetViewPerspective"));
|
||||
lib.GetViewRaytracedInstanceAt = (GetViewRaytracedInstanceAtPtr)(GetProcAddress(lib.handle, "RT64_GetViewRaytracedInstanceAt"));
|
||||
lib.DestroyView = (DestroyViewPtr)(GetProcAddress(lib.handle, "RT64_DestroyView"));
|
||||
lib.CreateScene = (CreateScenePtr)(GetProcAddress(lib.handle, "RT64_CreateScene"));
|
||||
lib.SetSceneLights = (SetSceneLightsPtr)(GetProcAddress(lib.handle, "RT64_SetSceneLights"));
|
||||
|
|
|
@ -446,10 +446,14 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, co
|
|||
}
|
||||
*node = &gfx_texture_cache.pool[gfx_texture_cache.pool_pos++];
|
||||
if ((*node)->texture_addr == NULL) {
|
||||
#ifndef GFX_REQUIRE_TEXTURE_HASH
|
||||
(*node)->texture_id = gfx_rapi->new_texture();
|
||||
#ifdef GFX_REQUIRE_TEXTURE_NAME
|
||||
# ifdef EXTERNAL_DATA
|
||||
(*node)->texture_id = gfx_rapi->new_texture((const char *)(orig_addr));
|
||||
# else
|
||||
# error "GFX_REQUIRE_TEXTURE_NAME requires EXTERNAL_DATA to be enabled."
|
||||
# endif
|
||||
#else
|
||||
(*node)->texture_id = gfx_rapi->new_texture(string_hash(orig_addr));
|
||||
(*node)->texture_id = gfx_rapi->new_texture();
|
||||
#endif
|
||||
}
|
||||
gfx_rapi->select_texture(tile, (*node)->texture_id);
|
||||
|
|
|
@ -16,10 +16,10 @@ struct GfxRenderingAPI {
|
|||
struct ShaderProgram *(*create_and_load_new_shader)(uint32_t shader_id);
|
||||
struct ShaderProgram *(*lookup_shader)(uint32_t shader_id);
|
||||
void (*shader_get_info)(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]);
|
||||
#ifndef GFX_REQUIRE_TEXTURE_HASH
|
||||
#ifndef GFX_REQUIRE_TEXTURE_NAME
|
||||
uint32_t (*new_texture)(void);
|
||||
#else
|
||||
uint32_t (*new_texture)(uint64_t hash);
|
||||
uint32_t (*new_texture)(const char *name);
|
||||
#endif
|
||||
void (*select_texture)(int tile, uint32_t texture_id);
|
||||
void (*upload_texture)(const uint8_t *rgba32_buf, int width, int height);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# define GFX_OUTPUT_NORMALS_TO_VBO
|
||||
# define GFX_SEPARATE_PROJECTIONS
|
||||
# define GFX_SEPARATE_FOG
|
||||
# define GFX_REQUIRE_TEXTURE_HASH
|
||||
# define GFX_REQUIRE_TEXTURE_NAME
|
||||
# define GFX_ENABLE_GRAPH_NODE_MODS
|
||||
#endif
|
||||
|
||||
|
|
|
@ -137,6 +137,12 @@ struct {
|
|||
RT64_LIGHT levelLights[MAX_LEVELS][MAX_AREAS][MAX_LEVEL_LIGHTS];
|
||||
int levelLightCounts[MAX_LEVELS][MAX_AREAS];
|
||||
|
||||
// Ray picking data.
|
||||
bool pickTextureNextFrame;
|
||||
bool pickTextureHighlight;
|
||||
uint64_t pickedTextureHash;
|
||||
std::unordered_map<RT64_INSTANCE *, uint64_t> lastInstanceTextureHashes;
|
||||
|
||||
// Geo layout mods.
|
||||
void *geoLayoutStack[MAX_GEO_LAYOUT_STACK_SIZE];
|
||||
int geoLayoutStackSize;
|
||||
|
@ -410,6 +416,11 @@ void gfx_rt64_load_material_mod(const json &jmatmod, RT64_MATERIAL *materialMod)
|
|||
materialMod->enabledAttributes |= RT64_ATTRIBUTE_REFLECTION_FACTOR;
|
||||
}
|
||||
|
||||
if (jmatmod.find("reflectionFresnelFactor") != jmatmod.end()) {
|
||||
materialMod->reflectionFresnelFactor = jmatmod["reflectionFresnelFactor"];
|
||||
materialMod->enabledAttributes |= RT64_ATTRIBUTE_REFLECTION_FRESNEL_FACTOR;
|
||||
}
|
||||
|
||||
if (jmatmod.find("reflectionShineFactor") != jmatmod.end()) {
|
||||
materialMod->reflectionShineFactor = jmatmod["reflectionShineFactor"];
|
||||
materialMod->enabledAttributes |= RT64_ATTRIBUTE_REFLECTION_SHINE_FACTOR;
|
||||
|
@ -475,6 +486,10 @@ json gfx_rt64_save_material_mod(RT64_MATERIAL *materialMod) {
|
|||
jmatmod["reflectionFactor"] = materialMod->reflectionFactor;
|
||||
}
|
||||
|
||||
if (materialMod->enabledAttributes & RT64_ATTRIBUTE_REFLECTION_FRESNEL_FACTOR) {
|
||||
jmatmod["reflectionFresnelFactor"] = materialMod->reflectionFresnelFactor;
|
||||
}
|
||||
|
||||
if (materialMod->enabledAttributes & RT64_ATTRIBUTE_REFLECTION_SHINE_FACTOR) {
|
||||
jmatmod["reflectionShineFactor"] = materialMod->reflectionShineFactor;
|
||||
}
|
||||
|
@ -737,6 +752,14 @@ LRESULT CALLBACK gfx_rt64_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARA
|
|||
}
|
||||
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
RT64.pickedTextureHash = 0;
|
||||
RT64.pickTextureNextFrame = true;
|
||||
RT64.pickTextureHighlight = true;
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
RT64.pickTextureHighlight = false;
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
if (wParam == VK_F5) {
|
||||
gfx_rt64_save_geo_layout_mods();
|
||||
|
@ -862,6 +885,9 @@ static void gfx_rt64_wapi_init(const char *window_title) {
|
|||
RT64.fogColor.y = 0.0f;
|
||||
RT64.fogColor.z = 0.0f;
|
||||
RT64.fogMul = RT64.fogOffset = 0;
|
||||
RT64.pickTextureNextFrame = false;
|
||||
RT64.pickTextureHighlight = false;
|
||||
RT64.pickedTextureHash = 0;
|
||||
|
||||
// Preload a blank texture.
|
||||
int blankBytesCount = 256 * 256 * 4;
|
||||
|
@ -884,6 +910,7 @@ static void gfx_rt64_wapi_init(const char *window_title) {
|
|||
RT64.defaultMaterial.ignoreNormalFactor = 0.0f;
|
||||
RT64.defaultMaterial.normalMapScale = 1.0f;
|
||||
RT64.defaultMaterial.reflectionFactor = 0.0f;
|
||||
RT64.defaultMaterial.reflectionFresnelFactor = 1.0f;
|
||||
RT64.defaultMaterial.reflectionShineFactor = 0.0f;
|
||||
RT64.defaultMaterial.refractionFactor = 0.0f;
|
||||
RT64.defaultMaterial.specularIntensity = 1.0f;
|
||||
|
@ -1089,15 +1116,15 @@ static void gfx_rt64_rapi_shader_get_info(struct ShaderProgram *prg, uint8_t *nu
|
|||
used_textures[1] = prg->used_textures[1];
|
||||
}
|
||||
|
||||
static uint32_t gfx_rt64_rapi_new_texture(uint64_t hash) {
|
||||
static uint32_t gfx_rt64_rapi_new_texture(const char *name) {
|
||||
uint32_t textureKey = RT64.textures.size();
|
||||
auto &recordedTexture = RT64.textures[textureKey];
|
||||
recordedTexture.texture = nullptr;
|
||||
recordedTexture.linearFilter = 0;
|
||||
recordedTexture.cms = 0;
|
||||
recordedTexture.cmt = 0;
|
||||
recordedTexture.hash = hash;
|
||||
RT64.textureHashIdMap[hash] = textureKey;
|
||||
recordedTexture.hash = gfx_rt64_get_texture_name_hash(name);
|
||||
RT64.textureHashIdMap[recordedTexture.hash] = textureKey;
|
||||
return textureKey;
|
||||
}
|
||||
|
||||
|
@ -1361,8 +1388,12 @@ static void gfx_rt64_rapi_draw_triangles_common(RT64_MATRIX4 transform, float bu
|
|||
RecordedMod *textureMod = nullptr;
|
||||
bool linearFilter = false;
|
||||
uint32_t cms = 0, cmt = 0;
|
||||
|
||||
// Create the instance.
|
||||
RT64_INSTANCE *instance = gfx_rt64_rapi_add_instance();
|
||||
|
||||
// Find all parameters associated to the texture if it's used.
|
||||
bool highlightMaterial = false;
|
||||
if (RT64.shaderProgram->used_textures[0]) {
|
||||
RecordedTexture &recordedTexture = RT64.textures[RT64.currentTextureIds[RT64.currentTile]];
|
||||
linearFilter = recordedTexture.linearFilter;
|
||||
|
@ -1377,6 +1408,13 @@ static void gfx_rt64_rapi_draw_triangles_common(RT64_MATRIX4 transform, float bu
|
|||
if (texModIt != RT64.texMods.end()) {
|
||||
textureMod = texModIt->second;
|
||||
}
|
||||
|
||||
// Update data for ray picking.
|
||||
if (RT64.pickTextureHighlight && (recordedTexture.hash == RT64.pickedTextureHash)) {
|
||||
highlightMaterial = true;
|
||||
}
|
||||
|
||||
RT64.lastInstanceTextureHashes[instance] = recordedTexture.hash;
|
||||
}
|
||||
|
||||
// Build material with applied mods.
|
||||
|
@ -1389,8 +1427,13 @@ static void gfx_rt64_rapi_draw_triangles_common(RT64_MATRIX4 transform, float bu
|
|||
gfx_rt64_rapi_apply_mod(&material, &normalMapTexture, textureMod, transform);
|
||||
}
|
||||
|
||||
// Create the instance and process the mesh that corresponds to the VBO.
|
||||
RT64_INSTANCE *instance = gfx_rt64_rapi_add_instance();
|
||||
if (highlightMaterial) {
|
||||
material.diffuseColorMix = { 1.0f, 0.0f, 1.0f, 0.5f };
|
||||
material.selfLight = { 1.0f, 1.0f, 1.0f };
|
||||
material.lightGroupMaskBits = 0;
|
||||
}
|
||||
|
||||
// Process the mesh that corresponds to the VBO.
|
||||
RT64_MESH *mesh = gfx_rt64_rapi_process_mesh(buf_vbo, buf_vbo_len, buf_vbo_num_tris, raytrace);
|
||||
|
||||
// Mark the right instance flags.
|
||||
|
@ -1496,6 +1539,47 @@ static void gfx_rt64_rapi_end_frame(void) {
|
|||
sprintf(message, "RT64: %.3f ms\n", ElapsedMicroseconds.QuadPart / 1000.0);
|
||||
RT64.lib.PrintToInspector(RT64.inspector, message);
|
||||
|
||||
// Left click allows to pick a texture for editing from the viewport.
|
||||
if (RT64.pickTextureNextFrame) {
|
||||
POINT cursorPos = {};
|
||||
GetCursorPos(&cursorPos);
|
||||
ScreenToClient(RT64.hwnd, &cursorPos);
|
||||
RT64_INSTANCE *instance = RT64.lib.GetViewRaytracedInstanceAt(RT64.view, cursorPos.x, cursorPos.y);
|
||||
if (instance != nullptr) {
|
||||
auto instIt = RT64.lastInstanceTextureHashes.find(instance);
|
||||
if (instIt != RT64.lastInstanceTextureHashes.end()) {
|
||||
RT64.pickedTextureHash = instIt->second;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RT64.pickedTextureHash = 0;
|
||||
}
|
||||
|
||||
RT64.pickTextureNextFrame = false;
|
||||
}
|
||||
|
||||
RT64.lastInstanceTextureHashes.clear();
|
||||
|
||||
// Edit last picked texture.
|
||||
if (RT64.pickedTextureHash != 0) {
|
||||
const std::string textureName = RT64.texNameMap[RT64.pickedTextureHash];
|
||||
RecordedMod *texMod = RT64.texMods[RT64.pickedTextureHash];
|
||||
if (texMod == nullptr) {
|
||||
texMod = new RecordedMod();
|
||||
texMod->materialMod = nullptr;
|
||||
texMod->lightMod = nullptr;
|
||||
texMod->normalMapHash = 0;
|
||||
RT64.texMods[RT64.pickedTextureHash] = texMod;
|
||||
}
|
||||
|
||||
if (texMod->materialMod == nullptr) {
|
||||
texMod->materialMod = new RT64_MATERIAL();
|
||||
texMod->materialMod->enabledAttributes = RT64_ATTRIBUTE_NONE;
|
||||
}
|
||||
|
||||
RT64.lib.SetMaterialInspector(RT64.inspector, texMod->materialMod, textureName.c_str());
|
||||
}
|
||||
|
||||
// Mesh key cleanup.
|
||||
auto keyIt = RT64.dynamicMeshKeys.begin();
|
||||
while (keyIt != RT64.dynamicMeshKeys.end()) {
|
||||
|
|
Loading…
Reference in New Issue