mirror of https://github.com/xemu-project/xemu.git
Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
0c2a617819 | |
![]() |
fee1e58204 | |
![]() |
270dbe01ea | |
![]() |
5685a6290c | |
![]() |
679f6d06bd | |
![]() |
34ed0f75de | |
![]() |
69c8df2a3e | |
![]() |
7a34eedd6f | |
![]() |
86c85023e6 | |
![]() |
1f876ce0da | |
![]() |
2cc926588b | |
![]() |
ebec5e3028 | |
![]() |
f82c6865fc |
10
build.sh
10
build.sh
|
@ -66,8 +66,14 @@ package_macos() {
|
|||
|
||||
cp Info.plist dist/xemu.app/Contents/
|
||||
|
||||
plutil -replace CFBundleShortVersionString -string $(cat ${project_source_dir}/XEMU_VERSION | cut -f1 -d-) dist/xemu.app/Contents/Info.plist
|
||||
plutil -replace CFBundleVersion -string $(cat ${project_source_dir}/XEMU_VERSION | cut -f1 -d-) dist/xemu.app/Contents/Info.plist
|
||||
if [[ -e "${project_source_dir}/XEMU_VERSION" ]]; then
|
||||
xemu_version="$(cat ${project_source_dir}/XEMU_VERSION | cut -f1 -d-)"
|
||||
else
|
||||
xemu_version="0.0.0"
|
||||
fi
|
||||
|
||||
plutil -replace CFBundleShortVersionString -string "${xemu_version}" dist/xemu.app/Contents/Info.plist
|
||||
plutil -replace CFBundleVersion -string "${xemu_version}" dist/xemu.app/Contents/Info.plist
|
||||
|
||||
codesign --force --deep --preserve-metadata=entitlements,requirements,flags,runtime --sign - "${exe_path}"
|
||||
python3 ./scripts/gen-license.py --version-file=macos-libs/$target_arch/INSTALLED > dist/LICENSE.txt
|
||||
|
|
|
@ -6,6 +6,8 @@ Build-Depends: debhelper (>= 11),
|
|||
cmake,
|
||||
git,
|
||||
python3:any,
|
||||
python3-pip,
|
||||
python3-tomli,
|
||||
python3-yaml,
|
||||
python3-venv,
|
||||
ninja-build,
|
||||
|
|
|
@ -423,7 +423,7 @@ const VMStateDescription vmstate_nv2a_pgraph_vertex_attributes = {
|
|||
|
||||
static const VMStateDescription vmstate_nv2a = {
|
||||
.name = "nv2a",
|
||||
.version_id = 2,
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 1,
|
||||
.post_save = nv2a_post_save,
|
||||
.post_load = nv2a_post_load,
|
||||
|
@ -507,9 +507,11 @@ static const VMStateDescription vmstate_nv2a = {
|
|||
VMSTATE_BOOL_ARRAY(pgraph.ltc1_dirty, NV2AState, NV2A_LTC1_COUNT),
|
||||
VMSTATE_STRUCT_ARRAY(pgraph.vertex_attributes, NV2AState, NV2A_VERTEXSHADER_ATTRIBUTES, 1, vmstate_nv2a_pgraph_vertex_attributes, VertexAttribute),
|
||||
VMSTATE_UINT32(pgraph.inline_array_length, NV2AState),
|
||||
VMSTATE_UINT32_ARRAY(pgraph.inline_array, NV2AState, NV2A_MAX_BATCH_LENGTH),
|
||||
VMSTATE_UINT32_SUB_ARRAY(pgraph.inline_array, NV2AState, 0, NV2A_MAX_BATCH_LENGTH_V2),
|
||||
VMSTATE_UINT32_SUB_ARRAY_V(pgraph.inline_array, NV2AState, NV2A_MAX_BATCH_LENGTH_V2, NV2A_MAX_BATCH_LENGTH - NV2A_MAX_BATCH_LENGTH_V2, 3),
|
||||
VMSTATE_UINT32(pgraph.inline_elements_length, NV2AState), // fixme
|
||||
VMSTATE_UINT32_ARRAY(pgraph.inline_elements, NV2AState, NV2A_MAX_BATCH_LENGTH),
|
||||
VMSTATE_UINT32_SUB_ARRAY(pgraph.inline_elements, NV2AState, 0, NV2A_MAX_BATCH_LENGTH_V2),
|
||||
VMSTATE_UINT32_SUB_ARRAY_V(pgraph.inline_elements, NV2AState, NV2A_MAX_BATCH_LENGTH_V2, NV2A_MAX_BATCH_LENGTH - NV2A_MAX_BATCH_LENGTH_V2, 3),
|
||||
VMSTATE_UINT32(pgraph.inline_buffer_length, NV2AState), // fixme
|
||||
VMSTATE_UINT32(pgraph.draw_arrays_length, NV2AState),
|
||||
VMSTATE_UINT32(pgraph.draw_arrays_max_count, NV2AState),
|
||||
|
|
|
@ -315,11 +315,14 @@
|
|||
#define NV_PGRAPH_CSV0_C 0x00000FB8
|
||||
# define NV_PGRAPH_CSV0_C_CHEOPS_PROGRAM_START 0x0000FF00
|
||||
# define NV_PGRAPH_CSV0_C_SPECULAR_ENABLE (1 << 16)
|
||||
# define NV_PGRAPH_CSV0_C_ALPHA_FROM_MATERIAL_SPECULAR (1 << 17)
|
||||
# define NV_PGRAPH_CSV0_C_SEPARATE_SPECULAR (1 << 18)
|
||||
# define NV_PGRAPH_CSV0_C_SPECULAR (3 << 19)
|
||||
# define NV_PGRAPH_CSV0_C_DIFFUSE (3 << 21)
|
||||
# define NV_PGRAPH_CSV0_C_AMBIENT (3 << 23)
|
||||
# define NV_PGRAPH_CSV0_C_EMISSION (3 << 25)
|
||||
# define NV_PGRAPH_CSV0_C_NORMALIZATION_ENABLE (1 << 27)
|
||||
# define NV_PGRAPH_CSV0_C_LOCALEYE (1 << 30)
|
||||
# define NV_PGRAPH_CSV0_C_LIGHTING (1 << 31)
|
||||
#define NV_PGRAPH_CSV1_B 0x00000FBC
|
||||
#define NV_PGRAPH_CSV1_A 0x00000FC0
|
||||
|
@ -882,6 +885,10 @@
|
|||
# define NV097_SET_CONTROL0_STENCIL_WRITE_ENABLE (1 << 0)
|
||||
# define NV097_SET_CONTROL0_Z_FORMAT (1 << 12)
|
||||
# define NV097_SET_CONTROL0_Z_PERSPECTIVE_ENABLE (1 << 16)
|
||||
# define NV097_SET_LIGHT_CONTROL 0x00000294
|
||||
# define NV097_SET_LIGHT_CONTROL_SEPARATE_SPECULAR 1
|
||||
# define NV097_SET_LIGHT_CONTROL_LOCALEYE (1 << 16)
|
||||
# define NV097_SET_LIGHT_CONTROL_ALPHA_FROM_MATERIAL_SPECULAR (1 << 17)
|
||||
# define NV097_SET_COLOR_MATERIAL 0x00000298
|
||||
# define NV097_SET_FOG_MODE 0x0000029C
|
||||
# define NV097_SET_FOG_MODE_V_LINEAR 0x2601
|
||||
|
@ -1049,6 +1056,7 @@
|
|||
# define NV097_SET_TEXGEN_VIEW_MODEL_LOCAL_VIEWER 0
|
||||
# define NV097_SET_TEXGEN_VIEW_MODEL_INFINITE_VIEWER 1
|
||||
# define NV097_SET_FOG_PLANE 0x000009D0
|
||||
# define NV097_SET_SPECULAR_PARAMS 0x000009E0
|
||||
# define NV097_SET_SCENE_AMBIENT_COLOR 0x00000A10
|
||||
# define NV097_SET_VIEWPORT_OFFSET 0x00000A20
|
||||
# define NV097_SET_POINT_PARAMS 0x00000A30
|
||||
|
@ -1099,6 +1107,11 @@
|
|||
# define NV097_SET_TEXCOORD3_4F 0x00001620
|
||||
# define NV097_SET_TEXCOORD3_2S 0x00001610
|
||||
# define NV097_SET_TEXCOORD3_4S 0x00001630
|
||||
# define NV097_SET_FOG_COORD 0x00001698
|
||||
# define NV097_SET_WEIGHT1F 0x0000169C
|
||||
# define NV097_SET_WEIGHT2F 0x000016A0
|
||||
# define NV097_SET_WEIGHT3F 0x000016B0
|
||||
# define NV097_SET_WEIGHT4F 0x000016C0
|
||||
# define NV097_SET_VERTEX_DATA_ARRAY_OFFSET 0x00001720
|
||||
# define NV097_SET_VERTEX_DATA_ARRAY_FORMAT 0x00001760
|
||||
# define NV097_SET_VERTEX_DATA_ARRAY_FORMAT_TYPE 0x0000000F
|
||||
|
@ -1252,6 +1265,7 @@
|
|||
# define NV097_SET_CLEAR_RECT_HORIZONTAL 0x00001D98
|
||||
# define NV097_SET_CLEAR_RECT_VERTICAL 0x00001D9C
|
||||
# define NV097_SET_SPECULAR_FOG_FACTOR 0x00001E20
|
||||
# define NV097_SET_SPECULAR_PARAMS_BACK 0x00001E28
|
||||
# define NV097_SET_COMBINER_COLOR_OCW 0x00001E40
|
||||
# define NV097_SET_COMBINER_CONTROL 0x00001E60
|
||||
# define NV097_SET_SHADOW_ZSLOPE_THRESHOLD 0x00001E68
|
||||
|
@ -1453,7 +1467,22 @@
|
|||
#define NV2A_NUM_SUBCHANNELS 8
|
||||
#define NV2A_CACHE1_SIZE 128
|
||||
|
||||
#define NV2A_MAX_BATCH_LENGTH 0x1FFFF
|
||||
/* This is a multi-use limit. Testing on an Xbox 1.0, it is possible to send
|
||||
* arrays of at least 0x0FFFFF elements without issue, however sending
|
||||
* NV097_DRAW_ARRAYS with a start value > 0xFFFF raises an exception implying
|
||||
* that there may be a vertex limit. Since xemu uses batch length for vertex
|
||||
* elements in NV097_INLINE_ARRAY the size should ideally be high enough to
|
||||
* accommodate 0xFFFF vertices with maximum attributes specified.
|
||||
*
|
||||
* Retail games are known to send at least 0x410FA elements in a single draw, so
|
||||
* a somewhat larger value is selected to balance memory use with real-world
|
||||
* limits.
|
||||
*
|
||||
* NV2A_MAX_BATCH_LENGTH_V2 is the previous limit, for migration.
|
||||
* FIXME: Remove NV2A_MAX_BATCH_LENGTH_V2 at some point in the future.
|
||||
*/
|
||||
#define NV2A_MAX_BATCH_LENGTH 0x07FFFF
|
||||
#define NV2A_MAX_BATCH_LENGTH_V2 0x1FFFF
|
||||
#define NV2A_VERTEXSHADER_ATTRIBUTES 16
|
||||
#define NV2A_MAX_TEXTURES 4
|
||||
|
||||
|
|
|
@ -298,7 +298,7 @@ static const SurfaceFormatInfo kelvin_surface_color_format_gl_map[] = {
|
|||
[NV097_SET_SURFACE_FORMAT_COLOR_LE_B8] =
|
||||
{1, GL_R8, GL_RED, GL_UNSIGNED_BYTE, GL_COLOR_ATTACHMENT0},
|
||||
[NV097_SET_SURFACE_FORMAT_COLOR_LE_G8B8] =
|
||||
{2, GL_RG8, GL_RG, GL_UNSIGNED_SHORT, GL_COLOR_ATTACHMENT0},
|
||||
{2, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, GL_COLOR_ATTACHMENT0},
|
||||
};
|
||||
|
||||
static const SurfaceFormatInfo kelvin_surface_zeta_float_format_gl_map[] = {
|
||||
|
|
|
@ -122,6 +122,7 @@ typedef struct ShaderBinding {
|
|||
GLint light_infinite_direction_loc[NV2A_MAX_LIGHTS];
|
||||
GLint light_local_position_loc[NV2A_MAX_LIGHTS];
|
||||
GLint light_local_attenuation_loc[NV2A_MAX_LIGHTS];
|
||||
int specular_power_loc;
|
||||
|
||||
GLint clip_region_loc[8];
|
||||
|
||||
|
|
|
@ -193,8 +193,11 @@ static void update_shader_constant_locations(ShaderBinding *binding)
|
|||
if (binding->state.fixed_function) {
|
||||
binding->material_alpha_loc =
|
||||
glGetUniformLocation(binding->gl_program, "material_alpha");
|
||||
binding->specular_power_loc =
|
||||
glGetUniformLocation(binding->gl_program, "specularPower");
|
||||
} else {
|
||||
binding->material_alpha_loc = -1;
|
||||
binding->specular_power_loc = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -836,6 +839,10 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding,
|
|||
}
|
||||
}
|
||||
|
||||
if (binding->specular_power_loc != -1) {
|
||||
glUniform1f(binding->specular_power_loc, pg->specular_power);
|
||||
}
|
||||
|
||||
/* estimate the viewport by assuming it matches the surface ... */
|
||||
unsigned int aa_width = 1, aa_height = 1;
|
||||
pgraph_apply_anti_aliasing_factor(pg, &aa_width, &aa_height);
|
||||
|
|
|
@ -230,10 +230,16 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
|||
}
|
||||
|
||||
/* Lighting */
|
||||
if (state->lighting) {
|
||||
|
||||
if (!state->lighting) {
|
||||
mstring_append(body, " oD0 = diffuse;\n");
|
||||
mstring_append(body, " oD1 = specular;\n");
|
||||
mstring_append(body, " oB0 = backDiffuse;\n");
|
||||
mstring_append(body, " oB1 = backSpecular;\n");
|
||||
} else {
|
||||
//FIXME: Do 2 passes if we want 2 sided-lighting?
|
||||
|
||||
mstring_append_fmt(uniforms, "%sfloat specularPower;\n", u);
|
||||
|
||||
static char alpha_source_diffuse[] = "diffuse.a";
|
||||
static char alpha_source_specular[] = "specular.a";
|
||||
static char alpha_source_material[] = "material_alpha";
|
||||
|
@ -264,17 +270,17 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
|||
|
||||
mstring_append(body, "oD1 = vec4(0.0, 0.0, 0.0, specular.a);\n");
|
||||
|
||||
if (state->local_eye) {
|
||||
mstring_append(body,
|
||||
"vec3 VPeye = normalize(eyePosition.xyz / eyePosition.w - tPosition.xyz / tPosition.w);\n"
|
||||
);
|
||||
}
|
||||
|
||||
for (i = 0; i < NV2A_MAX_LIGHTS; i++) {
|
||||
if (state->light[i] == LIGHT_OFF) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* FIXME: It seems that we only have to handle the surface colors if
|
||||
* they are not part of the material [= vertex colors].
|
||||
* If they are material the cpu will premultiply light
|
||||
* colors
|
||||
*/
|
||||
|
||||
mstring_append_fmt(body, "/* Light %d */ {\n", i);
|
||||
|
||||
if (state->light[i] == LIGHT_LOCAL
|
||||
|
@ -285,18 +291,20 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
|||
"%svec3 lightLocalAttenuation%d;\n",
|
||||
u, i, u, i);
|
||||
mstring_append_fmt(body,
|
||||
" vec3 VP = lightLocalPosition%d - tPosition.xyz/tPosition.w;\n"
|
||||
" vec3 tPos = tPosition.xyz/tPosition.w;\n"
|
||||
" vec3 VP = lightLocalPosition%d - tPos;\n"
|
||||
" float d = length(VP);\n"
|
||||
//FIXME: if (d > lightLocalRange) { .. don't process this light .. } /* inclusive?! */ - what about directional lights?
|
||||
" VP = normalize(VP);\n"
|
||||
" float attenuation = 1.0 / (lightLocalAttenuation%d.x\n"
|
||||
" + lightLocalAttenuation%d.y * d\n"
|
||||
" + lightLocalAttenuation%d.z * d * d);\n"
|
||||
" vec3 halfVector = normalize(VP + eyePosition.xyz / eyePosition.w);\n" /* FIXME: Not sure if eyePosition is correct */
|
||||
" float nDotVP = max(0.0, dot(tNormal, VP));\n"
|
||||
" float nDotHV = max(0.0, dot(tNormal, halfVector));\n",
|
||||
i, i, i, i);
|
||||
|
||||
" if (d <= lightLocalRange(%d)) {\n" /* FIXME: Double check that range is inclusive */
|
||||
" VP = normalize(VP);\n"
|
||||
" float attenuation = 1.0 / (lightLocalAttenuation%d.x\n"
|
||||
" + lightLocalAttenuation%d.y * d\n"
|
||||
" + lightLocalAttenuation%d.z * d * d);\n"
|
||||
" vec3 halfVector = normalize(VP + %s);\n"
|
||||
" float nDotVP = max(0.0, dot(tNormal, VP));\n"
|
||||
" float nDotHV = max(0.0, dot(tNormal, halfVector));\n",
|
||||
i, i, i, i, i,
|
||||
state->local_eye ? "VPeye" : "vec3(0.0, 0.0, 0.0)"
|
||||
);
|
||||
}
|
||||
|
||||
switch(state->light[i]) {
|
||||
|
@ -309,15 +317,21 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
|||
"%svec3 lightInfiniteDirection%d;\n",
|
||||
u, i, u, i);
|
||||
mstring_append_fmt(body,
|
||||
" float attenuation = 1.0;\n"
|
||||
" float nDotVP = max(0.0, dot(tNormal, normalize(vec3(lightInfiniteDirection%d))));\n"
|
||||
" float nDotHV = max(0.0, dot(tNormal, vec3(lightInfiniteHalfVector%d)));\n",
|
||||
i, i);
|
||||
|
||||
/* FIXME: Do specular */
|
||||
|
||||
/* FIXME: tBackDiffuse */
|
||||
|
||||
" {\n"
|
||||
" float attenuation = 1.0;\n"
|
||||
" vec3 lightDirection = normalize(lightInfiniteDirection%d);\n"
|
||||
" float nDotVP = max(0.0, dot(tNormal, lightDirection));\n",
|
||||
i);
|
||||
if (state->local_eye) {
|
||||
mstring_append(body,
|
||||
" float nDotHV = max(0.0, dot(tNormal, normalize(lightDirection + VPeye)));\n"
|
||||
);
|
||||
} else {
|
||||
mstring_append_fmt(body,
|
||||
" float nDotHV = max(0.0, dot(tNormal, lightInfiniteHalfVector%d));\n",
|
||||
i
|
||||
);
|
||||
}
|
||||
break;
|
||||
case LIGHT_LOCAL:
|
||||
/* Everything done already */
|
||||
|
@ -325,18 +339,18 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
|||
case LIGHT_SPOT:
|
||||
/* https://docs.microsoft.com/en-us/windows/win32/direct3d9/attenuation-and-spotlight-factor#spotlight-factor */
|
||||
mstring_append_fmt(body,
|
||||
" vec4 spotDir = lightSpotDirection(%d);\n"
|
||||
" float invScale = 1/length(spotDir.xyz);\n"
|
||||
" float cosHalfPhi = -invScale*spotDir.w;\n"
|
||||
" float cosHalfTheta = invScale + cosHalfPhi;\n"
|
||||
" float spotDirDotVP = dot(spotDir.xyz, VP);\n"
|
||||
" float rho = invScale*spotDirDotVP;\n"
|
||||
" if (rho > cosHalfTheta) {\n"
|
||||
" } else if (rho <= cosHalfPhi) {\n"
|
||||
" attenuation = 0.0;\n"
|
||||
" } else {\n"
|
||||
" attenuation *= spotDirDotVP + spotDir.w;\n" /* FIXME: lightSpotFalloff */
|
||||
" }\n",
|
||||
" vec4 spotDir = lightSpotDirection(%d);\n"
|
||||
" float invScale = 1/length(spotDir.xyz);\n"
|
||||
" float cosHalfPhi = -invScale*spotDir.w;\n"
|
||||
" float cosHalfTheta = invScale + cosHalfPhi;\n"
|
||||
" float spotDirDotVP = dot(spotDir.xyz, VP);\n"
|
||||
" float rho = invScale*spotDirDotVP;\n"
|
||||
" if (rho > cosHalfTheta) {\n"
|
||||
" } else if (rho <= cosHalfPhi) {\n"
|
||||
" attenuation = 0.0;\n"
|
||||
" } else {\n"
|
||||
" attenuation *= spotDirDotVP + spotDir.w;\n" /* FIXME: lightSpotFalloff */
|
||||
" }\n",
|
||||
i);
|
||||
break;
|
||||
default:
|
||||
|
@ -345,52 +359,83 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
|||
}
|
||||
|
||||
mstring_append_fmt(body,
|
||||
" float pf;\n"
|
||||
" if (nDotVP == 0.0) {\n"
|
||||
" pf = 0.0;\n"
|
||||
" } else {\n"
|
||||
" pf = pow(nDotHV, /* specular(l, m, n, l1, m1, n1) */ 0.001);\n"
|
||||
" }\n"
|
||||
" vec3 lightAmbient = lightAmbientColor(%d) * attenuation;\n"
|
||||
" vec3 lightDiffuse = lightDiffuseColor(%d) * attenuation * nDotVP;\n"
|
||||
" vec3 lightSpecular = lightSpecularColor(%d) * pf;\n",
|
||||
" float pf;\n"
|
||||
" if (nDotVP == 0.0) {\n"
|
||||
" pf = 0.0;\n"
|
||||
" } else {\n"
|
||||
" pf = pow(nDotHV, specularPower);\n"
|
||||
" }\n"
|
||||
" vec3 lightAmbient = lightAmbientColor(%d) * attenuation;\n"
|
||||
" vec3 lightDiffuse = lightDiffuseColor(%d) * attenuation * nDotVP;\n"
|
||||
" vec3 lightSpecular = lightSpecularColor(%d) * attenuation * pf;\n",
|
||||
i, i, i);
|
||||
|
||||
mstring_append(body,
|
||||
" oD0.xyz += lightAmbient;\n");
|
||||
" oD0.xyz += lightAmbient;\n");
|
||||
|
||||
switch (state->diffuse_src) {
|
||||
case MATERIAL_COLOR_SRC_MATERIAL:
|
||||
mstring_append(body,
|
||||
" oD0.xyz += lightDiffuse;\n");
|
||||
" oD0.xyz += lightDiffuse;\n");
|
||||
break;
|
||||
case MATERIAL_COLOR_SRC_DIFFUSE:
|
||||
mstring_append(body,
|
||||
" oD0.xyz += diffuse.xyz * lightDiffuse;\n");
|
||||
" oD0.xyz += diffuse.xyz * lightDiffuse;\n");
|
||||
break;
|
||||
case MATERIAL_COLOR_SRC_SPECULAR:
|
||||
mstring_append(body,
|
||||
" oD0.xyz += specular.xyz * lightDiffuse;\n");
|
||||
" oD0.xyz += specular.xyz * lightDiffuse;\n");
|
||||
break;
|
||||
}
|
||||
|
||||
mstring_append(body,
|
||||
" oD1.xyz += specular.xyz * lightSpecular;\n");
|
||||
switch (state->specular_src) {
|
||||
case MATERIAL_COLOR_SRC_MATERIAL:
|
||||
mstring_append(body,
|
||||
" oD1.xyz += lightSpecular;\n");
|
||||
break;
|
||||
case MATERIAL_COLOR_SRC_DIFFUSE:
|
||||
mstring_append(body,
|
||||
" oD1.xyz += diffuse.xyz * lightSpecular;\n");
|
||||
break;
|
||||
case MATERIAL_COLOR_SRC_SPECULAR:
|
||||
mstring_append(body,
|
||||
" oD1.xyz += specular.xyz * lightSpecular;\n");
|
||||
break;
|
||||
}
|
||||
|
||||
mstring_append(body, "}\n");
|
||||
mstring_append(body, " }\n"
|
||||
"}\n");
|
||||
}
|
||||
} else {
|
||||
mstring_append(body, " oD0 = diffuse;\n");
|
||||
mstring_append(body, " oD1 = specular;\n");
|
||||
|
||||
/* TODO: Implement two-sided lighting */
|
||||
mstring_append(body, " oB0 = backDiffuse;\n");
|
||||
mstring_append(body, " oB1 = backSpecular;\n");
|
||||
}
|
||||
|
||||
if (!state->specular_enable) {
|
||||
mstring_append(body, " oD1 = vec4(0.0, 0.0, 0.0, 1.0);\n");
|
||||
mstring_append(body, " oB1 = vec4(0.0, 0.0, 0.0, 1.0);\n");
|
||||
} else {
|
||||
if (!state->separate_specular) {
|
||||
if (state->lighting) {
|
||||
mstring_append(body,
|
||||
" oD0.xyz += oD1.xyz;\n"
|
||||
" oB0.xyz += oB1.xyz;\n"
|
||||
);
|
||||
}
|
||||
mstring_append(body,
|
||||
" oD1 = specular;\n"
|
||||
" oB1 = backSpecular;\n"
|
||||
);
|
||||
}
|
||||
if (state->ignore_specular_alpha) {
|
||||
mstring_append(body,
|
||||
" oD1.a = 1.0;\n"
|
||||
" oB1.a = 1.0;\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
mstring_append(body, " oB0 = backDiffuse;\n");
|
||||
mstring_append(body, " oB1 = backSpecular;\n");
|
||||
|
||||
/* Fog */
|
||||
if (state->fog_enable) {
|
||||
|
||||
|
@ -414,7 +459,7 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
|||
mstring_append(body, " float fogDistance = fogCoord;\n");
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
assert(!"Invalid foggen mode");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -256,6 +256,13 @@ MString *pgraph_gen_vsh_glsl(const ShaderState *state, bool prefix_outputs)
|
|||
" vtxD1 = clamp(oD1, 0.0, 1.0);\n"
|
||||
" vtxB1 = clamp(oB1, 0.0, 1.0);\n"
|
||||
);
|
||||
|
||||
if (state->ignore_specular_alpha) {
|
||||
mstring_append(body,
|
||||
" vtxD1.w = 1.0;\n"
|
||||
" vtxB1.w = 1.0;\n"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
mstring_append(body,
|
||||
" vtxD1 = vec4(0.0, 0.0, 0.0, 1.0);\n"
|
||||
|
|
|
@ -27,6 +27,7 @@ DEF_METHOD(NV097, SET_COMBINER_SPECULAR_FOG_CW0)
|
|||
DEF_METHOD(NV097, SET_COMBINER_SPECULAR_FOG_CW1)
|
||||
DEF_METHOD_CASE_4(NV097, SET_TEXTURE_ADDRESS, 64)
|
||||
DEF_METHOD(NV097, SET_CONTROL0)
|
||||
DEF_METHOD(NV097, SET_LIGHT_CONTROL)
|
||||
DEF_METHOD(NV097, SET_COLOR_MATERIAL)
|
||||
DEF_METHOD(NV097, SET_FOG_MODE)
|
||||
DEF_METHOD(NV097, SET_FOG_GEN_MODE)
|
||||
|
@ -95,6 +96,7 @@ DEF_METHOD_RANGE(NV097, SET_FOG_PARAMS, 3)
|
|||
DEF_METHOD_RANGE(NV097, SET_TEXGEN_PLANE_S, 4*4*4)
|
||||
DEF_METHOD(NV097, SET_TEXGEN_VIEW_MODEL)
|
||||
DEF_METHOD_RANGE(NV097, SET_FOG_PLANE, 4)
|
||||
DEF_METHOD_RANGE(NV097, SET_SPECULAR_PARAMS, 6)
|
||||
DEF_METHOD_RANGE(NV097, SET_SCENE_AMBIENT_COLOR, 3)
|
||||
DEF_METHOD_RANGE(NV097, SET_VIEWPORT_OFFSET, 4)
|
||||
DEF_METHOD_RANGE(NV097, SET_POINT_PARAMS, 8)
|
||||
|
@ -134,6 +136,11 @@ DEF_METHOD_RANGE(NV097, SET_TEXCOORD3_2F, 2)
|
|||
DEF_METHOD_RANGE(NV097, SET_TEXCOORD3_4F, 4)
|
||||
DEF_METHOD_RANGE(NV097, SET_TEXCOORD3_2S, 1)
|
||||
DEF_METHOD_RANGE(NV097, SET_TEXCOORD3_4S, 2)
|
||||
DEF_METHOD(NV097, SET_FOG_COORD)
|
||||
DEF_METHOD(NV097, SET_WEIGHT1F)
|
||||
DEF_METHOD_RANGE(NV097, SET_WEIGHT2F, 2)
|
||||
DEF_METHOD_RANGE(NV097, SET_WEIGHT3F, 3)
|
||||
DEF_METHOD_RANGE(NV097, SET_WEIGHT4F, 4)
|
||||
DEF_METHOD_RANGE(NV097, SET_VERTEX_DATA_ARRAY_FORMAT, 16)
|
||||
DEF_METHOD_RANGE(NV097, SET_VERTEX_DATA_ARRAY_OFFSET, 16)
|
||||
DEF_METHOD(NV097, SET_LOGIC_OP_ENABLE)
|
||||
|
@ -177,6 +184,7 @@ DEF_METHOD(NV097, CLEAR_SURFACE)
|
|||
DEF_METHOD(NV097, SET_CLEAR_RECT_HORIZONTAL)
|
||||
DEF_METHOD(NV097, SET_CLEAR_RECT_VERTICAL)
|
||||
DEF_METHOD_RANGE(NV097, SET_SPECULAR_FOG_FACTOR, 2)
|
||||
DEF_METHOD_RANGE(NV097, SET_SPECULAR_PARAMS_BACK, 6)
|
||||
DEF_METHOD(NV097, SET_SHADER_CLIP_PLANE_MODE)
|
||||
DEF_METHOD_RANGE(NV097, SET_COMBINER_COLOR_OCW, 8)
|
||||
DEF_METHOD(NV097, SET_COMBINER_CONTROL)
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "hw/xbox/nv2a/nv2a_int.h"
|
||||
#include "ui/xemu-notifications.h"
|
||||
#include "ui/xemu-settings.h"
|
||||
|
@ -1075,6 +1077,18 @@ DEF_METHOD(NV097, SET_CONTROL0)
|
|||
z_perspective);
|
||||
}
|
||||
|
||||
DEF_METHOD(NV097, SET_LIGHT_CONTROL)
|
||||
{
|
||||
PG_SET_MASK(NV_PGRAPH_CSV0_C, NV_PGRAPH_CSV0_C_SEPARATE_SPECULAR,
|
||||
(parameter & NV097_SET_LIGHT_CONTROL_SEPARATE_SPECULAR) != 0);
|
||||
|
||||
PG_SET_MASK(NV_PGRAPH_CSV0_C, NV_PGRAPH_CSV0_C_LOCALEYE,
|
||||
(parameter & NV097_SET_LIGHT_CONTROL_LOCALEYE) != 0);
|
||||
|
||||
PG_SET_MASK(NV_PGRAPH_CSV0_C, NV_PGRAPH_CSV0_C_ALPHA_FROM_MATERIAL_SPECULAR,
|
||||
(parameter & NV097_SET_LIGHT_CONTROL_ALPHA_FROM_MATERIAL_SPECULAR) != 0);
|
||||
}
|
||||
|
||||
DEF_METHOD(NV097, SET_COLOR_MATERIAL)
|
||||
{
|
||||
PG_SET_MASK(NV_PGRAPH_CSV0_C, NV_PGRAPH_CSV0_C_EMISSION,
|
||||
|
@ -1791,6 +1805,113 @@ DEF_METHOD_INC(NV097, SET_FOG_PLANE)
|
|||
pg->vsh_constants_dirty[NV_IGRAPH_XF_XFCTX_FOG] = true;
|
||||
}
|
||||
|
||||
struct CurveCoefficients {
|
||||
float a;
|
||||
float b;
|
||||
float c;
|
||||
};
|
||||
|
||||
static const struct CurveCoefficients curve_coefficients[] = {
|
||||
{1.000108475163, -9.838607076280, 54.829089549713},
|
||||
{1.199164441703, -3.292603784852, 7.799987995214},
|
||||
{8.653441252033, 29.189473787191, 43.586027561823},
|
||||
{-531.307758450301, 117.398468683934, 113.155490738338},
|
||||
{-4.662713151292, 1.221108944572, 1.217360986939},
|
||||
{-124.435242105211, 35.401219563514, 35.408114377045},
|
||||
{10672560.259502287954, 21565843.555823743343, 10894794.336297152564},
|
||||
{-51973801.463933646679, -104199997.554352939129, -52225454.356278456748},
|
||||
{972270.324080004124, 2025882.096547174733, 1054898.052467488218},
|
||||
};
|
||||
|
||||
static const float kCoefficient0StepPoints[] = {
|
||||
-0.022553957999, // power = 1.25
|
||||
-0.421539008617, // power = 4.00
|
||||
-0.678715527058, // power = 9.00
|
||||
-0.838916420937, // power = 20.00
|
||||
-0.961754500866, // power = 90.00
|
||||
-0.990773200989, // power = 375.00
|
||||
-0.994858562946, // power = 650.00
|
||||
-0.996561050415, // power = 1000.00
|
||||
-0.999547004700, // power = 1250.00
|
||||
};
|
||||
|
||||
static float reconstruct_quadratic(float c0, const struct CurveCoefficients *coefficients) {
|
||||
return coefficients->a + coefficients->b * c0 + coefficients->c * c0 * c0;
|
||||
}
|
||||
|
||||
static float reconstruct_saturation_growth_rate(float c0, const struct CurveCoefficients *coefficients) {
|
||||
return (coefficients->a * c0) / (coefficients->b + coefficients->c * c0);
|
||||
}
|
||||
|
||||
static float (* const reconstruct_func_map[])(float, const struct CurveCoefficients *) = {
|
||||
reconstruct_quadratic, // 1.0..1.25 max error 0.01 %
|
||||
reconstruct_quadratic, // 1.25..4.0 max error 2.2 %
|
||||
reconstruct_quadratic, // 4.0..9.0 max error 2.3 %
|
||||
reconstruct_saturation_growth_rate, // 9.0..20.0 max error 1.4 %
|
||||
reconstruct_saturation_growth_rate, // 20.0..90.0 max error 2.1 %
|
||||
reconstruct_saturation_growth_rate, // 90.0..375.0 max error 2.8%
|
||||
reconstruct_quadratic, // 375..650 max error 1.0 %
|
||||
reconstruct_quadratic, // 650..1000 max error 1.7%
|
||||
reconstruct_quadratic, // 1000..1250 max error 1.0%
|
||||
};
|
||||
|
||||
static float reconstruct_specular_power(const float *params) {
|
||||
// See https://github.com/dracc/xgu/blob/db3172d8c983629f0dc971092981846da22438ae/xgux.h#L279
|
||||
|
||||
// Values < 1.0 will result in a positive c1 and (c2 - c0 * 2) will be very
|
||||
// close to the original value.
|
||||
if (params[1] > 0.0f && params[2] < 1.0f) {
|
||||
return params[2] - (params[0] * 2.0f);
|
||||
}
|
||||
|
||||
float c0 = params[0];
|
||||
float c3 = params[3];
|
||||
// FIXME: This handling is not correct, but is distinct without crashing.
|
||||
// It does not appear possible for a DirectX-generated value to be positive,
|
||||
// so while this differs from hardware behavior, it may be irrelevant in
|
||||
// practice.
|
||||
if (c0 > 0.0f || c3 > 0.0f) {
|
||||
return 0.0001f;
|
||||
}
|
||||
|
||||
float reconstructed_power = 0.f;
|
||||
for (uint32_t i = 0; i < sizeof(kCoefficient0StepPoints) / sizeof(kCoefficient0StepPoints[0]); ++i) {
|
||||
if (c0 > kCoefficient0StepPoints[i]) {
|
||||
reconstructed_power = reconstruct_func_map[i](c0, &curve_coefficients[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float reconstructed_half_power = 0.f;
|
||||
for (uint32_t i = 0; i < sizeof(kCoefficient0StepPoints) / sizeof(kCoefficient0StepPoints[0]); ++i) {
|
||||
if (c3 > kCoefficient0StepPoints[i]) {
|
||||
reconstructed_half_power = reconstruct_func_map[i](c3, &curve_coefficients[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The range can be extended beyond 1250 by using the half power params. This
|
||||
// will only work for DirectX generated values, arbitrary params could
|
||||
// erroneously trigger this.
|
||||
//
|
||||
// There are some very low power (~1) values that have inverted powers, but
|
||||
// they are easily identified by comparatively high c0 parameters.
|
||||
if (reconstructed_power == 0.f || (reconstructed_half_power > reconstructed_power && c0 < -0.1f)) {
|
||||
return reconstructed_half_power * 2.f;
|
||||
}
|
||||
|
||||
return reconstructed_power;
|
||||
}
|
||||
|
||||
DEF_METHOD_INC(NV097, SET_SPECULAR_PARAMS)
|
||||
{
|
||||
int slot = (method - NV097_SET_SPECULAR_PARAMS) / 4;
|
||||
pg->specular_params[slot] = *(float *)¶meter;
|
||||
if (slot == 5) {
|
||||
pg->specular_power = reconstruct_specular_power(pg->specular_params);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_METHOD_INC(NV097, SET_SCENE_AMBIENT_COLOR)
|
||||
{
|
||||
int slot = (method - NV097_SET_SCENE_AMBIENT_COLOR) / 4;
|
||||
|
@ -2010,6 +2131,26 @@ DEF_METHOD_INC(NV097, SET_VERTEX4F)
|
|||
}
|
||||
}
|
||||
|
||||
DEF_METHOD(NV097, SET_FOG_COORD)
|
||||
{
|
||||
VertexAttribute *attribute = &pg->vertex_attributes[NV2A_VERTEX_ATTR_FOG];
|
||||
pgraph_allocate_inline_buffer_vertices(pg, NV2A_VERTEX_ATTR_FOG);
|
||||
attribute->inline_value[0] = *(float*)¶meter;
|
||||
attribute->inline_value[1] = attribute->inline_value[0];
|
||||
attribute->inline_value[2] = attribute->inline_value[0];
|
||||
attribute->inline_value[3] = attribute->inline_value[0];
|
||||
}
|
||||
|
||||
DEF_METHOD(NV097, SET_WEIGHT1F)
|
||||
{
|
||||
VertexAttribute *attribute = &pg->vertex_attributes[NV2A_VERTEX_ATTR_WEIGHT];
|
||||
pgraph_allocate_inline_buffer_vertices(pg, NV2A_VERTEX_ATTR_WEIGHT);
|
||||
attribute->inline_value[0] = *(float*)¶meter;
|
||||
attribute->inline_value[1] = 0.f;
|
||||
attribute->inline_value[2] = 0.f;
|
||||
attribute->inline_value[3] = 1.f;
|
||||
}
|
||||
|
||||
DEF_METHOD_INC(NV097, SET_NORMAL3S)
|
||||
{
|
||||
int slot = (method - NV097_SET_NORMAL3S) / 4;
|
||||
|
@ -2144,7 +2285,6 @@ DEF_METHOD_INC(NV097, SET_TEXCOORD1_4F)
|
|||
SET_VERTEX_ATTRIBUTE_F(NV097_SET_TEXCOORD1_4F, NV2A_VERTEX_ATTR_TEXTURE1);
|
||||
}
|
||||
|
||||
|
||||
DEF_METHOD_INC(NV097, SET_TEXCOORD2_4F)
|
||||
{
|
||||
SET_VERTEX_ATTRIBUTE_F(NV097_SET_TEXCOORD2_4F, NV2A_VERTEX_ATTR_TEXTURE2);
|
||||
|
@ -2155,8 +2295,34 @@ DEF_METHOD_INC(NV097, SET_TEXCOORD3_4F)
|
|||
SET_VERTEX_ATTRIBUTE_F(NV097_SET_TEXCOORD3_4F, NV2A_VERTEX_ATTR_TEXTURE3);
|
||||
}
|
||||
|
||||
DEF_METHOD_INC(NV097, SET_WEIGHT4F)
|
||||
{
|
||||
SET_VERTEX_ATTRIBUTE_F(NV097_SET_WEIGHT4F, NV2A_VERTEX_ATTR_WEIGHT);
|
||||
}
|
||||
|
||||
#undef SET_VERTEX_ATTRIBUTE_F
|
||||
|
||||
DEF_METHOD_INC(NV097, SET_WEIGHT2F)
|
||||
{
|
||||
int slot = (method - NV097_SET_WEIGHT2F) / 4;
|
||||
VertexAttribute *attribute =
|
||||
&pg->vertex_attributes[NV2A_VERTEX_ATTR_WEIGHT];
|
||||
pgraph_allocate_inline_buffer_vertices(pg, NV2A_VERTEX_ATTR_WEIGHT);
|
||||
attribute->inline_value[slot] = *(float*)¶meter;
|
||||
attribute->inline_value[2] = 0.0f;
|
||||
attribute->inline_value[3] = 1.0f;
|
||||
}
|
||||
|
||||
DEF_METHOD_INC(NV097, SET_WEIGHT3F)
|
||||
{
|
||||
int slot = (method - NV097_SET_WEIGHT3F) / 4;
|
||||
VertexAttribute *attribute =
|
||||
&pg->vertex_attributes[NV2A_VERTEX_ATTR_WEIGHT];
|
||||
pgraph_allocate_inline_buffer_vertices(pg, NV2A_VERTEX_ATTR_WEIGHT);
|
||||
attribute->inline_value[slot] = *(float*)¶meter;
|
||||
attribute->inline_value[3] = 1.0f;
|
||||
}
|
||||
|
||||
#define SET_VERTEX_ATRIBUTE_TEX_2F(command, attr_index) \
|
||||
do { \
|
||||
int slot = (method - (command)) / 4; \
|
||||
|
@ -2526,7 +2692,11 @@ DEF_METHOD(NV097, DRAW_ARRAYS)
|
|||
int32_t count = GET_MASK(parameter, NV097_DRAW_ARRAYS_COUNT) + 1;
|
||||
|
||||
if (pg->inline_elements_length) {
|
||||
/* FIXME: Determine HW behavior for overflow case. */
|
||||
/* FIXME: HW throws an exception if the start index is > 0xFFFF. This
|
||||
* would prevent this assert from firing for any reasonable choice of
|
||||
* NV2A_MAX_BATCH_LENGTH (which must be larger to accommodate
|
||||
* NV097_INLINE_ARRAY anyway)
|
||||
*/
|
||||
assert((pg->inline_elements_length + count) < NV2A_MAX_BATCH_LENGTH);
|
||||
assert(!pg->draw_arrays_prevent_connect);
|
||||
|
||||
|
@ -2728,6 +2898,15 @@ DEF_METHOD_INC(NV097, SET_SPECULAR_FOG_FACTOR)
|
|||
pgraph_reg_w(pg, NV_PGRAPH_SPECFOGFACTOR0 + slot*4, parameter);
|
||||
}
|
||||
|
||||
DEF_METHOD_INC(NV097, SET_SPECULAR_PARAMS_BACK)
|
||||
{
|
||||
int slot = (method - NV097_SET_SPECULAR_PARAMS_BACK) / 4;
|
||||
pg->specular_params_back[slot] = *(float *)¶meter;
|
||||
if (slot == 5) {
|
||||
pg->specular_power_back = reconstruct_specular_power(pg->specular_params_back);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_METHOD(NV097, SET_SHADER_CLIP_PLANE_MODE)
|
||||
{
|
||||
pgraph_reg_w(pg, NV_PGRAPH_SHADERCLIPMODE, parameter);
|
||||
|
|
|
@ -197,6 +197,11 @@ typedef struct PGRAPHState {
|
|||
float light_local_position[NV2A_MAX_LIGHTS][3];
|
||||
float light_local_attenuation[NV2A_MAX_LIGHTS][3];
|
||||
|
||||
float specular_params[6];
|
||||
float specular_power;
|
||||
float specular_params_back[6];
|
||||
float specular_power_back;
|
||||
|
||||
float point_params[8];
|
||||
|
||||
VertexAttribute vertex_attributes[NV2A_VERTEXSHADER_ATTRIBUTES];
|
||||
|
|
|
@ -92,6 +92,16 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
|
|||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_SPECULAR);
|
||||
}
|
||||
|
||||
state.separate_specular = GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_SEPARATE_SPECULAR);
|
||||
state.ignore_specular_alpha = !GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_ALPHA_FROM_MATERIAL_SPECULAR);
|
||||
state.local_eye = GET_MASK(
|
||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_LOCALEYE);
|
||||
|
||||
state.specular_power = pg->specular_power;
|
||||
state.specular_power_back = pg->specular_power_back;
|
||||
|
||||
/* vertex program stuff */
|
||||
state.vertex_program = vertex_program,
|
||||
state.z_perspective = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
|
||||
|
|
|
@ -79,6 +79,12 @@ typedef struct ShaderState {
|
|||
enum MaterialColorSource diffuse_src;
|
||||
enum MaterialColorSource specular_src;
|
||||
|
||||
bool separate_specular;
|
||||
bool ignore_specular_alpha;
|
||||
bool local_eye;
|
||||
float specular_power;
|
||||
float specular_power_back;
|
||||
|
||||
bool lighting;
|
||||
enum VshLight light[NV2A_MAX_LIGHTS];
|
||||
|
||||
|
|
|
@ -190,6 +190,7 @@ typedef struct ShaderBinding {
|
|||
int light_infinite_direction_loc[NV2A_MAX_LIGHTS];
|
||||
int light_local_position_loc[NV2A_MAX_LIGHTS];
|
||||
int light_local_attenuation_loc[NV2A_MAX_LIGHTS];
|
||||
int specular_power_loc;
|
||||
|
||||
int clip_region_loc;
|
||||
|
||||
|
|
|
@ -313,6 +313,9 @@ static void update_shader_constant_locations(ShaderBinding *binding)
|
|||
|
||||
binding->uniform_attrs_loc =
|
||||
uniform_index(&binding->vertex->uniforms, "inlineValue");
|
||||
|
||||
binding->specular_power_loc =
|
||||
uniform_index(&binding->vertex->uniforms, "specularPower");
|
||||
}
|
||||
|
||||
static void shader_cache_entry_init(Lru *lru, LruNode *node, void *state)
|
||||
|
@ -607,6 +610,11 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding,
|
|||
}
|
||||
}
|
||||
|
||||
if (binding->specular_power_loc != -1) {
|
||||
uniform1f(&binding->vertex->uniforms, binding->specular_power_loc,
|
||||
pg->specular_power);
|
||||
}
|
||||
|
||||
/* estimate the viewport by assuming it matches the surface ... */
|
||||
unsigned int aa_width = 1, aa_height = 1;
|
||||
pgraph_apply_anti_aliasing_factor(pg, &aa_width, &aa_height);
|
||||
|
|
|
@ -55,8 +55,6 @@ enum VshFoggen {
|
|||
FOGGEN_RADIAL,
|
||||
FOGGEN_PLANAR,
|
||||
FOGGEN_ABS_PLANAR,
|
||||
FOGGEN_ERROR4,
|
||||
FOGGEN_ERROR5,
|
||||
FOGGEN_FOG_X
|
||||
};
|
||||
|
||||
|
|
|
@ -1085,6 +1085,9 @@ extern const VMStateInfo vmstate_info_qlist;
|
|||
#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
|
||||
VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
|
||||
|
||||
#define VMSTATE_UINT32_SUB_ARRAY_V(_f, _s, _start, _num, _v) \
|
||||
VMSTATE_SUB_ARRAY(_f, _s, _start, _num, _v, vmstate_info_uint32, uint32_t)
|
||||
|
||||
#define VMSTATE_UINT32_2DARRAY(_f, _s, _n1, _n2) \
|
||||
VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, 0)
|
||||
|
||||
|
|
Loading…
Reference in New Issue