Index: ddraw/glDirect3DDevice.cpp |
— | — | @@ -388,6 +388,7 @@ |
389 | 389 | for(i = 0; i < 5; i++)
|
390 | 390 | if(VertexType[i+2].data) blendweights++;
|
391 | 391 | shader |= (__int64)blendweights << 46;
|
| 392 | + if(renderstate[D3DRENDERSTATE_NORMALIZENORMALS]) shader |= (1i64 << 49);
|
392 | 393 | //TODO: Implement texture stages.
|
393 | 394 | for(i = 0; i < 8; i++)
|
394 | 395 | {
|
— | — | @@ -611,14 +612,22 @@ |
612 | 613 | HRESULT WINAPI glDirect3DDevice7::GetLight(DWORD dwLightIndex, LPD3DLIGHT7 lpLight)
|
613 | 614 | {
|
614 | 615 | if(!this) return DDERR_INVALIDPARAMS;
|
615 | | - FIXME("glDirect3DDevice7::GetLight: stub");
|
616 | | - ERR(DDERR_GENERIC);
|
| 616 | + if(!lpLight) return DDERR_INVALIDPARAMS;
|
| 617 | + if(dwLightIndex >= lightsmax) ERR(DDERR_INVALIDOBJECT);
|
| 618 | + if(!lights[dwLightIndex]) ERR(DDERR_INVALIDOBJECT);
|
| 619 | + lights[dwLightIndex]->GetLight7(lpLight);
|
| 620 | + return D3D_OK;
|
617 | 621 | }
|
618 | 622 | HRESULT WINAPI glDirect3DDevice7::GetLightEnable(DWORD dwLightIndex, BOOL* pbEnable)
|
619 | 623 | {
|
620 | 624 | if(!this) return DDERR_INVALIDPARAMS;
|
621 | | - FIXME("glDirect3DDevice7::GetLightEnalbe: stub");
|
622 | | - ERR(DDERR_GENERIC);
|
| 625 | + if(dwLightIndex >= lightsmax) ERR(DDERR_INVALIDOBJECT);
|
| 626 | + if(!lights[dwLightIndex]) ERR(DDERR_INVALIDOBJECT);
|
| 627 | + if(!pbEnable) return DDERR_INVALIDPARAMS;
|
| 628 | + *pbEnable = FALSE;
|
| 629 | + for(int i = 0; i < 8; i++)
|
| 630 | + if(gllights[i] == dwLightIndex) *pbEnable = TRUE;
|
| 631 | + return D3D_OK;
|
623 | 632 | }
|
624 | 633 | HRESULT WINAPI glDirect3DDevice7::GetMaterial(LPD3DMATERIAL7 lpMaterial)
|
625 | 634 | {
|
— | — | @@ -1059,11 +1068,22 @@ |
1060 | 1069 | {
|
1061 | 1070 | GLfloat worldview[16];
|
1062 | 1071 | GLfloat tmp[16];
|
| 1072 | +
|
1063 | 1073 | ZeroMemory(&worldview,sizeof(D3DMATRIX));
|
1064 | 1074 | ZeroMemory(&tmp,sizeof(D3DMATRIX));
|
1065 | 1075 | __gluMultMatricesf(matWorld,matView,worldview); // Get worldview
|
1066 | 1076 | if(__gluInvertMatrixf(worldview,tmp)) // Invert
|
1067 | | - memcpy(matNormal,tmp,16*sizeof(GLfloat));
|
1068 | | - else memcpy(matNormal,worldview,16*sizeof(GLfloat));
|
| 1077 | + {
|
| 1078 | + memcpy(matNormal,tmp,3*sizeof(GLfloat));
|
| 1079 | + memcpy(matNormal+3,tmp+4,3*sizeof(GLfloat));
|
| 1080 | + memcpy(matNormal+6,tmp+8,3*sizeof(GLfloat));
|
| 1081 | + }
|
| 1082 | + else
|
| 1083 | + {
|
| 1084 | + memcpy(matNormal,worldview,3*sizeof(GLfloat));
|
| 1085 | + memcpy(matNormal+3,worldview+4,3*sizeof(GLfloat));
|
| 1086 | + memcpy(matNormal+6,worldview+8,3*sizeof(GLfloat));
|
| 1087 | + }
|
| 1088 | +
|
1069 | 1089 | normal_dirty = false;
|
1070 | 1090 | } |
\ No newline at end of file |
Index: ddraw/glDirect3DDevice.h |
— | — | @@ -124,7 +124,7 @@ |
125 | 125 | GLfloat matWorld[16];
|
126 | 126 | GLfloat matView[16];
|
127 | 127 | GLfloat matProjection[16];
|
128 | | - GLfloat matNormal[16];
|
| 128 | + GLfloat matNormal[9];
|
129 | 129 | bool normal_dirty;
|
130 | 130 | D3DMATERIAL7 material;
|
131 | 131 | D3DVIEWPORT7 viewport;
|
Index: ddraw/glExtensions.cpp |
— | — | @@ -64,6 +64,7 @@ |
65 | 65 | void (APIENTRY *glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) = NULL;
|
66 | 66 | void (APIENTRY *glUniform3fv) (GLint location, GLsizei count, const GLfloat* value) = NULL;
|
67 | 67 | void (APIENTRY *glUniform4fv) (GLint location, GLsizei count, const GLfloat* value) = NULL;
|
| 68 | +void (APIENTRY *glUniformMatrix3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL;
|
68 | 69 | void (APIENTRY *glUniformMatrix4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL;
|
69 | 70 |
|
70 | 71 | void (APIENTRY *glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
|
— | — | @@ -136,6 +137,7 @@ |
137 | 138 | glUniform4f = (PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f");
|
138 | 139 | glUniform3fv = (PFNGLUNIFORM3FVPROC)wglGetProcAddress("glUniform3fv");
|
139 | 140 | glUniform4fv = (PFNGLUNIFORM4FVPROC)wglGetProcAddress("glUniform4fv");
|
| 141 | + glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)wglGetProcAddress("glUniformMatrix3fv");
|
140 | 142 | glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv");
|
141 | 143 | glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation");
|
142 | 144 | glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
|
Index: ddraw/glExtensions.h |
— | — | @@ -84,6 +84,7 @@ |
85 | 85 | GLAPI void (APIENTRY *glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
|
86 | 86 | GLAPI void (APIENTRY *glUniform3fv) (GLint location, GLsizei count, const GLfloat* value);
|
87 | 87 | GLAPI void (APIENTRY *glUniform4fv) (GLint location, GLsizei count, const GLfloat* value);
|
| 88 | +GLAPI void (APIENTRY *glUniformMatrix3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
88 | 89 | GLAPI void (APIENTRY *glUniformMatrix4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
89 | 90 |
|
90 | 91 | GLAPI void (APIENTRY *glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
|
Index: ddraw/glRenderer.cpp |
— | — | @@ -1076,7 +1076,7 @@ |
1077 | 1077 | loc = glGetUniformLocation(prog,"projection");
|
1078 | 1078 | glUniformMatrix4fv(loc,1,false,device->matProjection);
|
1079 | 1079 | loc = glGetUniformLocation(prog,"normalmat");
|
1080 | | - glUniformMatrix4fv(loc,1,true,device->matNormal);
|
| 1080 | + glUniformMatrix3fv(loc,1,true,device->matNormal);
|
1081 | 1081 | loc = glGetUniformLocation(prog,"material.diffuse");
|
1082 | 1082 | glUniform4fv(loc,1,(GLfloat*)&device->material.diffuse);
|
1083 | 1083 | loc = glGetUniformLocation(prog,"material.ambient");
|
— | — | @@ -1142,7 +1142,7 @@ |
1143 | 1143 | if(device->glDDS7->zbuffer) SetFBO(device->glDDS7->texture,device->glDDS7->zbuffer->texture,device->glDDS7->zbuffer->hasstencil);
|
1144 | 1144 | else SetFBO(device->glDDS7->texture,0,false);
|
1145 | 1145 | glViewport(device->viewport.dwX,device->viewport.dwY,device->viewport.dwWidth,device->viewport.dwHeight);
|
1146 | | - if(indices) glDrawRangeElements(mode,0,indexcount,count,GL_UNSIGNED_SHORT,indices);
|
| 1146 | + if(indices) glDrawElements(mode,indexcount,GL_UNSIGNED_SHORT,indices);
|
1147 | 1147 | else glDrawArrays(mode,0,count);
|
1148 | 1148 | if(device->glDDS7->zbuffer) device->glDDS7->zbuffer->dirty |= 2;
|
1149 | 1149 | device->glDDS7->dirty |= 2;
|
Index: ddraw/shadergen.cpp |
— | — | @@ -76,6 +76,7 @@ |
77 | 77 | Bit 37 - Enable normals
|
78 | 78 | Bits 38-45 - Light types
|
79 | 79 | Bits 46-48 - Number of blending weights
|
| 80 | +Bit 49 - Normalize normals
|
80 | 81 | */
|
81 | 82 |
|
82 | 83 | /* Bits in Texture Stage ID:
|
— | — | @@ -215,7 +216,7 @@ |
216 | 217 | static const char unif_matrices[] = "uniform mat4 world;\n\
|
217 | 218 | uniform mat4 view;\n\
|
218 | 219 | uniform mat4 projection;\n\
|
219 | | -uniform mat4 normalmat;\n";
|
| 220 | +uniform mat3 normalmat;\n";
|
220 | 221 | static const char unif_material[] = "struct Material\n\
|
221 | 222 | {\n\
|
222 | 223 | vec4 diffuse;\n\
|
— | — | @@ -244,9 +245,10 @@ |
245 | 246 | static const char unif_ambient[] = "uniform vec4 ambientcolor;\n";
|
246 | 247 | static const char unif_tex[] = "uniform sampler2d texX;\n";
|
247 | 248 | // Variables
|
248 | | -static const char var_colors[] = "vec4 diffuse;\n\
|
| 249 | +static const char var_common[] = "vec4 diffuse;\n\
|
249 | 250 | vec4 specular;\n\
|
250 | | -vec4 ambient;\n";
|
| 251 | +vec4 ambient;\n\
|
| 252 | +vec3 N;";
|
251 | 253 | static const char var_color[] = "vec4 color;\n";
|
252 | 254 | static const char var_xyzw[] = "vec4 xyzw;\n";
|
253 | 255 | // Operations
|
— | — | @@ -253,6 +255,8 @@ |
254 | 256 | static const char op_transform[] = "xyzw = vec4(xyz,1);\n\
|
255 | 257 | vec4 pos = (projection*(view*world))*xyzw;\n\
|
256 | 258 | gl_Position = vec4(pos.x,-pos.y,pos.z,pos.w);\n";
|
| 259 | +static const char op_normalize[] = "N = normalize(normalmat*nxyz);\n";
|
| 260 | +static const char op_normalpassthru[] = "N = normalmat*nxyz;\n";
|
257 | 261 | static const char op_passthru[] = "gl_Position = xyzw;\n";
|
258 | 262 | static const char op_resetcolor[] = "diffuse = specular = vec4(0.0);\n\
|
259 | 263 | ambient = ambientcolor / 255.0;\n";
|
— | — | @@ -268,8 +272,7 @@ |
269 | 273 | static const char func_dirlight[] = "void DirLight(in Light light)\n\
|
270 | 274 | {\n\
|
271 | 275 | float NdotHV = 0.0;\n\
|
272 | | -vec3 N = normalize(vec3(normalmat*vec4(nxyz,1.0)));\n\
|
273 | | -vec3 dir = normalize(light.direction);\n\
|
| 276 | +vec3 dir = normalize(-light.direction);\n\
|
274 | 277 | ambient += light.ambient;\n\
|
275 | 278 | float NdotL = max(dot(N,dir),0.0);\n\
|
276 | 279 | diffuse += light.diffuse*NdotL;\n\
|
— | — | @@ -277,7 +280,7 @@ |
278 | 281 | {\n\
|
279 | 282 | vec3 eye = (-view[3].xyz / view[3].w);\n\
|
280 | 283 | vec3 P = vec3((view*world)*xyzw);\n\
|
281 | | -vec3 L = normalize(light.direction.xyz - P);\n\
|
| 284 | +vec3 L = normalize(-light.direction.xyz - P);\n\
|
282 | 285 | vec3 V = normalize(eye - P);\n\
|
283 | 286 | NdotHV = max(dot(N,L+V),0.0);\n\
|
284 | 287 | specular += (pow(NdotHV,float(material.power))*light.specular);\n\
|
— | — | @@ -348,7 +351,7 @@ |
349 | 352 | }
|
350 | 353 |
|
351 | 354 | // Variables
|
352 | | - vsrc->append(var_colors);
|
| 355 | + vsrc->append(var_common);
|
353 | 356 | if(!((id>>34)&1)) vsrc->append(var_xyzw);
|
354 | 357 |
|
355 | 358 | // Functions
|
— | — | @@ -367,6 +370,8 @@ |
368 | 371 | if((id>>34)&1) vsrc->append(op_passthru);
|
369 | 372 | else vsrc->append(op_transform);
|
370 | 373 | vsrc->append(op_resetcolor);
|
| 374 | + if((id>>49)&1) vsrc->append(op_normalize);
|
| 375 | + else vsrc->append(op_normalpassthru);
|
371 | 376 | if(numlights)
|
372 | 377 | {
|
373 | 378 | for(i = 0; i < numlights; i++)
|