Index: ddraw/glDirect3DDevice.cpp |
— | — | @@ -30,6 +30,7 @@ |
31 | 31 | #include "glDirect3DLight.h"
|
32 | 32 | #include "glDirect3DExecuteBuffer.h"
|
33 | 33 | #include <string>
|
| 34 | +#include <cmath>
|
34 | 35 | using namespace std;
|
35 | 36 | #include "shadergen.h"
|
36 | 37 | #include "glutil.h"
|
— | — | @@ -356,6 +357,8 @@ |
357 | 358 | d3ddesc.dwMaxTextureRepeat = d3ddesc.dwMaxTextureAspectRatio = renderer->gl_caps.TextureMax;
|
358 | 359 | d3ddesc3.dwMaxTextureWidth = d3ddesc3.dwMaxTextureHeight =
|
359 | 360 | d3ddesc3.dwMaxTextureRepeat = d3ddesc3.dwMaxTextureAspectRatio = renderer->gl_caps.TextureMax;
|
| 361 | + scalex = scaley = 0;
|
| 362 | + mhWorld = mhView = mhProjection = 0;
|
360 | 363 | renderer->InitD3D(zbuffer);
|
361 | 364 | error = D3D_OK;
|
362 | 365 | }
|
— | — | @@ -1937,7 +1940,10 @@ |
1938 | 1941 | if(!d3dMatHandle) return DDERR_INVALIDPARAMS;
|
1939 | 1942 | if(d3dMatHandle >= matrixcount) return DDERR_INVALIDPARAMS;
|
1940 | 1943 | if(!matrices[d3dMatHandle].active) return D3DERR_MATRIX_SETDATA_FAILED;
|
1941 | | - memcpy(&matrices[d3dMatHandle],lpD3DMatrix,sizeof(D3DMATRIX));
|
| 1944 | + memcpy(&matrices[d3dMatHandle].matrix,lpD3DMatrix,sizeof(D3DMATRIX));
|
| 1945 | + if(d3dMatHandle == mhWorld) SetTransform(D3DTRANSFORMSTATE_WORLD,lpD3DMatrix);
|
| 1946 | + if(d3dMatHandle == mhView) SetTransform(D3DTRANSFORMSTATE_VIEW,lpD3DMatrix);
|
| 1947 | + if(d3dMatHandle == mhProjection) SetTransform(D3DTRANSFORMSTATE_PROJECTION,lpD3DMatrix);
|
1942 | 1948 | return D3D_OK;
|
1943 | 1949 | }
|
1944 | 1950 |
|
— | — | @@ -1979,19 +1985,8 @@ |
1980 | 1986 | void glDirect3DDevice7::UpdateTransform()
|
1981 | 1987 | {
|
1982 | 1988 | GLfloat mat1[16];
|
1983 | | - GLfloat mat2[16];
|
1984 | | - GLfloat matViewport[16];
|
1985 | 1989 | __gluMultMatricesf(matWorld,matView,mat1);
|
1986 | | - __gluMultMatricesf(mat1,matProjection,mat2);
|
1987 | | - matViewport[1] = matViewport[2] = matViewport[3] = matViewport[4] = matViewport[6] = matViewport[7] =
|
1988 | | - matViewport[8] = matViewport[9] = matViewport[11] = matViewport[15] = 0;
|
1989 | | - matViewport[0] = (GLfloat)viewport.dwWidth / 2.0f;
|
1990 | | - matViewport[5] = (GLfloat)viewport.dwHeight / 2.0f;
|
1991 | | - matViewport[10] = (viewport.dvMaxZ - viewport.dvMinZ) / 2.0f;
|
1992 | | - matViewport[12] = (GLfloat)viewport.dwX + ((GLfloat)viewport.dwWidth / 2.0f);
|
1993 | | - matViewport[13] = (GLfloat)viewport.dwY + ((GLfloat)viewport.dwHeight / 2.0f);
|
1994 | | - matViewport[14] = (viewport.dvMinZ + viewport.dvMaxZ) / 2.0f;
|
1995 | | - __gluMultMatricesf(mat2,matViewport,matTransform);
|
| 1990 | + __gluMultMatricesf(mat1,matProjection,matTransform);
|
1996 | 1991 | transform_dirty = false;
|
1997 | 1992 | }
|
1998 | 1993 |
|
— | — | @@ -2014,9 +2009,92 @@ |
2015 | 2010 | if((LONG)maxY > extents->y2) extents->y2 = (LONG)maxY;
|
2016 | 2011 | }
|
2017 | 2012 |
|
| 2013 | +inline void glDirect3DDevice7::TransformViewport(D3DTLVERTEX *vertex)
|
| 2014 | +{
|
| 2015 | + vertex->dvSX = vertex->dvSX / vertex->dvRHW * scalex + viewport.dwX + viewport.dwWidth / 2;
|
| 2016 | + vertex->dvSY = vertex->dvSY / vertex->dvRHW * scaley + viewport.dwY + viewport.dwHeight / 2;
|
| 2017 | + vertex->dvSZ /= vertex->dvRHW;
|
| 2018 | + vertex->dvRHW = 1 / vertex->dvRHW;
|
| 2019 | +}
|
| 2020 | +
|
| 2021 | +// function from project.c from Mesa source code. See matrix.cpp for license.
|
| 2022 | +static void normalize(float v[3])
|
| 2023 | +{
|
| 2024 | + float r;
|
| 2025 | +
|
| 2026 | + r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
|
| 2027 | + if (r == 0.0) return;
|
| 2028 | +
|
| 2029 | + v[0] /= r;
|
| 2030 | + v[1] /= r;
|
| 2031 | + v[2] /= r;
|
| 2032 | +}
|
| 2033 | +
|
| 2034 | +inline void AddD3DCV(D3DCOLORVALUE *dest, D3DCOLORVALUE *src)
|
| 2035 | +{
|
| 2036 | + dest->r += src->r;
|
| 2037 | + dest->g += src->g;
|
| 2038 | + dest->b += src->b;
|
| 2039 | + dest->a += src->a;
|
| 2040 | +}
|
| 2041 | +
|
| 2042 | +inline void MulD3DCV(D3DCOLORVALUE *dest, D3DCOLORVALUE *src)
|
| 2043 | +{
|
| 2044 | + dest->r *= src->r;
|
| 2045 | + dest->g *= src->g;
|
| 2046 | + dest->b *= src->b;
|
| 2047 | + dest->a *= src->a;
|
| 2048 | +}
|
| 2049 | +
|
| 2050 | +inline void MulD3DCVFloat(D3DCOLORVALUE *dest, float src)
|
| 2051 | +{
|
| 2052 | + dest->r *= src;
|
| 2053 | + dest->g *= src;
|
| 2054 | + dest->b *= src;
|
| 2055 | + dest->a *= src;
|
| 2056 | +}
|
| 2057 | +
|
| 2058 | +inline void NegativeVec3(float v[3])
|
| 2059 | +{
|
| 2060 | + v[0] = -v[0];
|
| 2061 | + v[1] = -v[1];
|
| 2062 | + v[2] = -v[2];
|
| 2063 | +}
|
| 2064 | +
|
| 2065 | +inline void SubVec3(float dest[3], float src[3])
|
| 2066 | +{
|
| 2067 | + dest[0] -= src[0];
|
| 2068 | + dest[1] -= src[1];
|
| 2069 | + dest[2] -= src[2];
|
| 2070 | +}
|
| 2071 | +
|
| 2072 | +inline void AddVec3(float dest[3], float src[3])
|
| 2073 | +{
|
| 2074 | + dest[0] += src[0];
|
| 2075 | + dest[1] += src[1];
|
| 2076 | + dest[2] += src[2];
|
| 2077 | +}
|
| 2078 | +
|
| 2079 | +inline float dot3(float a[3], float b[3])
|
| 2080 | +{
|
| 2081 | + return (a[0]*b[0])+(a[1]*b[1])+(a[2]*b[2]);
|
| 2082 | +}
|
| 2083 | +
|
2018 | 2084 | INT glDirect3DDevice7::TransformAndLight(D3DTLVERTEX **output, DWORD *outsize, D3DVERTEX *input, WORD start, WORD dest, DWORD count, D3DRECT *extents)
|
2019 | 2085 | {
|
2020 | | - GLfloat in[4];
|
| 2086 | + D3DVALUE dir[3];
|
| 2087 | + D3DVALUE eye[3] = {0.0,0.0,1.0};
|
| 2088 | + D3DVALUE P[4];
|
| 2089 | + D3DVALUE L[4];
|
| 2090 | + D3DVALUE V[4];
|
| 2091 | + D3DVALUE in[4];
|
| 2092 | + D3DCOLORVALUE ambient;
|
| 2093 | + D3DCOLORVALUE diffuse;
|
| 2094 | + D3DCOLORVALUE specular;
|
| 2095 | + D3DCOLORVALUE color1;
|
| 2096 | + D3DCOLORVALUE color2;
|
| 2097 | + D3DVALUE NdotHV;
|
| 2098 | + D3DVALUE NdotL;
|
2021 | 2099 | in[3] = 1.0f;
|
2022 | 2100 | if(transform_dirty) UpdateTransform();
|
2023 | 2101 | if(*outsize < (dest+count)*sizeof(D3DTLVERTEX))
|
— | — | @@ -2032,10 +2110,72 @@ |
2033 | 2111 | in[1] = input[i+start].dvY;
|
2034 | 2112 | in[2] = input[i+start].dvZ;
|
2035 | 2113 | __gluMultMatrixVecf(matTransform,in,&(*output)[i+dest].dvSX);
|
| 2114 | + TransformViewport(&(*output)[i+dest]);
|
2036 | 2115 | (*output)[i+dest].dvRHW = 1.0f/(*output)[i+dest].dvRHW;
|
2037 | | - // Do lighting
|
2038 | 2116 | (*output)[i+dest].dvTU = input[i+start].dvTU;
|
2039 | 2117 | (*output)[i+dest].dvTV = input[i+start].dvTV;
|
| 2118 | + diffuse.r = diffuse.g = diffuse.b = diffuse.a = 0;
|
| 2119 | + specular.r = specular.g = specular.b = specular.a = 0;
|
| 2120 | + ambient.r = (D3DVALUE)RGBA_GETRED(renderstate[D3DRENDERSTATE_AMBIENT]) / 255.0;
|
| 2121 | + ambient.g = (D3DVALUE)RGBA_GETGREEN(renderstate[D3DRENDERSTATE_AMBIENT]) / 255.0;
|
| 2122 | + ambient.b = (D3DVALUE)RGBA_GETBLUE(renderstate[D3DRENDERSTATE_AMBIENT]) / 255.0;
|
| 2123 | + ambient.a = (D3DVALUE)RGBA_GETALPHA(renderstate[D3DRENDERSTATE_AMBIENT]) / 255.0;
|
| 2124 | + for(int l = 0; l < 8; l++)
|
| 2125 | + {
|
| 2126 | + if(gllights[l] != -1)
|
| 2127 | + {
|
| 2128 | + switch(lights[gllights[l]]->light.dltType)
|
| 2129 | + {
|
| 2130 | + case D3DLIGHT_DIRECTIONAL:
|
| 2131 | + NdotHV = 0;
|
| 2132 | + memcpy(dir,&lights[gllights[l]]->light.dvDirection,3*sizeof(D3DVALUE));
|
| 2133 | + normalize(dir);
|
| 2134 | + AddD3DCV(&ambient,&lights[gllights[l]]->light.dcvAmbient);
|
| 2135 | + NdotL = max(dot3((float*)&input[i+start].dvNX,(float*)&dir),0.0f);
|
| 2136 | + color1 = lights[gllights[l]]->light.dcvDiffuse;
|
| 2137 | + MulD3DCVFloat(&color1,NdotL);
|
| 2138 | + AddD3DCV(&diffuse,&color1);
|
| 2139 | + if((NdotL > 0.0) && (material.dvPower != 0.0))
|
| 2140 | + {
|
| 2141 | + __gluMultMatrixVecf(matWorld,&input[i+start].dvX,P);
|
| 2142 | + memcpy(L ,&lights[gllights[l]]->light.dvDirection,3*sizeof(D3DVALUE));
|
| 2143 | + NegativeVec3(L);
|
| 2144 | + SubVec3(L,P);
|
| 2145 | + normalize(L);
|
| 2146 | + memcpy(V,eye,3*sizeof(D3DVALUE));
|
| 2147 | + SubVec3(V,P);
|
| 2148 | + normalize(V);
|
| 2149 | + AddVec3(L,V);
|
| 2150 | + NdotHV = max(dot3((float*)&input[i+start].dvNX,L),0.0f);
|
| 2151 | + color1 = lights[gllights[l]]->light.dcvSpecular;
|
| 2152 | + MulD3DCVFloat(&color1,pow(NdotHV,material.dvPower));
|
| 2153 | + AddD3DCV(&specular,&color1);
|
| 2154 | + }
|
| 2155 | + break;
|
| 2156 | + case D3DLIGHT_POINT:
|
| 2157 | + break;
|
| 2158 | + case D3DLIGHT_SPOT:
|
| 2159 | + break;
|
| 2160 | + case D3DLIGHT_PARALLELPOINT:
|
| 2161 | + break;
|
| 2162 | + case D3DLIGHT_GLSPOT:
|
| 2163 | + break;
|
| 2164 | + default:
|
| 2165 | + break;
|
| 2166 | + }
|
| 2167 | + }
|
| 2168 | + color1 = material.dcvDiffuse;
|
| 2169 | + MulD3DCV(&color1,&diffuse);
|
| 2170 | + color2 = material.dcvAmbient;
|
| 2171 | + MulD3DCV(&color2,&ambient);
|
| 2172 | + AddD3DCV(&color1,&color2);
|
| 2173 | + AddD3DCV(&color1,&material.dcvEmissive);
|
| 2174 | + color2 = material.dcvSpecular;
|
| 2175 | + MulD3DCV(&color2,&specular);
|
| 2176 | + AddD3DCV(&color1,&color2);
|
| 2177 | + (*output)[i+dest].dcColor = D3DRGBA(color1.r,color1.g,color1.b,color1.a);
|
| 2178 | + (*output)[i+dest].dcSpecular = D3DRGBA(color2.r,color2.g,color2.b,color2.a);
|
| 2179 | + }
|
2040 | 2180 | }
|
2041 | 2181 | if(extents) CalculateExtents(extents,*output,count);
|
2042 | 2182 | return 0;
|
— | — | @@ -2058,6 +2198,7 @@ |
2059 | 2199 | in[1] = input[i+start].dvY;
|
2060 | 2200 | in[2] = input[i+start].dvZ;
|
2061 | 2201 | __gluMultMatrixVecf(matTransform,in,&(*output)[i+dest].dvSX);
|
| 2202 | + TransformViewport(&(*output)[i+dest]);
|
2062 | 2203 | (*output)[i+dest].dvRHW = 1.0f/(*output)[i+dest].dvRHW;
|
2063 | 2204 | (*output)[i+dest].dcColor = 0xFFFFFFFF;
|
2064 | 2205 | (*output)[i+dest].dcSpecular = 0;
|
— | — | @@ -2085,6 +2226,7 @@ |
2086 | 2227 | in[1] = input[i+start].dvY;
|
2087 | 2228 | in[2] = input[i+start].dvZ;
|
2088 | 2229 | __gluMultMatrixVecf(matTransform,in,&(*output)[i+dest].dvSX);
|
| 2230 | + TransformViewport(&(*output)[i+dest]);
|
2089 | 2231 | (*output)[i+dest].dvRHW = 1.0f/(*output)[i+dest].dvRHW;
|
2090 | 2232 | (*output)[i+dest].dcColor = input[i+start].dcColor;
|
2091 | 2233 | (*output)[i+dest].dcSpecular = input[i+start].dcSpecular;
|
— | — | @@ -2245,6 +2387,20 @@ |
2246 | 2388 | {
|
2247 | 2389 | GetMatrix(((D3DSTATE*)opptr)->dwArg[0],&mat1);
|
2248 | 2390 | SetTransform(((D3DSTATE*)opptr)->dtstTransformStateType,&mat1);
|
| 2391 | + switch(((D3DSTATE*)opptr)->dtstTransformStateType)
|
| 2392 | + {
|
| 2393 | + case D3DTRANSFORMSTATE_WORLD:
|
| 2394 | + mhWorld = ((D3DSTATE*)opptr)->dwArg[0];
|
| 2395 | + break;
|
| 2396 | + case D3DTRANSFORMSTATE_VIEW:
|
| 2397 | + mhView = ((D3DSTATE*)opptr)->dwArg[0];
|
| 2398 | + break;
|
| 2399 | + case D3DTRANSFORMSTATE_PROJECTION:
|
| 2400 | + mhProjection = ((D3DSTATE*)opptr)->dwArg[0];
|
| 2401 | + break;
|
| 2402 | + default:
|
| 2403 | + break;
|
| 2404 | + }
|
2249 | 2405 | opptr += instruction->bSize;
|
2250 | 2406 | }
|
2251 | 2407 | break;
|
— | — | @@ -2309,6 +2465,7 @@ |
2310 | 2466 | else TransformAndLight((D3DTLVERTEX**)&outbuffer,&outbuffersize,(D3DVERTEX*)in_vertptr,((D3DPROCESSVERTICES*)opptr)->wStart,
|
2311 | 2467 | ((D3DPROCESSVERTICES*)opptr)->wDest,((D3DPROCESSVERTICES*)opptr)->dwCount,&data.dsStatus.drExtent);
|
2312 | 2468 | }
|
| 2469 | + break;
|
2313 | 2470 | case D3DPROCESSVERTICES_COPY:
|
2314 | 2471 | if(((D3DPROCESSVERTICES*)opptr)->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS)
|
2315 | 2472 | CopyVertices((D3DTLVERTEX**)&outbuffer,&outbuffersize,(D3DTLVERTEX*)in_vertptr,((D3DPROCESSVERTICES*)opptr)->wStart,
|
Index: ddraw/glDirect3DDevice.h |
— | — | @@ -162,6 +162,7 @@ |
163 | 163 | HRESULT GetPickRecords(LPDWORD lpCount, LPD3DPICKRECORD lpD3DPickRec);
|
164 | 164 | HRESULT Pick(LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags,
|
165 | 165 | LPD3DRECT lpRect);
|
| 166 | + inline void TransformViewport(D3DTLVERTEX *vertex);
|
166 | 167 | INT TransformAndLight(D3DTLVERTEX **output, DWORD *outsize, D3DVERTEX *input, WORD start, WORD dest, DWORD count, D3DRECT *extents);
|
167 | 168 | INT TransformOnly(D3DTLVERTEX **output, DWORD *outsize, D3DVERTEX *input, WORD start, WORD dest, DWORD count, D3DRECT *extents);
|
168 | 169 | INT TransformOnly(D3DTLVERTEX **output, DWORD *outsize, D3DLVERTEX *input, WORD start, WORD dest, DWORD count, D3DRECT *extents);
|
— | — | @@ -169,6 +170,7 @@ |
170 | 171 | void UpdateTransform();
|
171 | 172 | void InitDX5();
|
172 | 173 | __int64 SelectShader(GLVERTEX *VertexType);
|
| 174 | + void SetScale(D3DVALUE x, D3DVALUE y){scalex = x; scaley = y;}
|
173 | 175 | GLfloat matWorld[16];
|
174 | 176 | GLfloat matView[16];
|
175 | 177 | GLfloat matProjection[16];
|
— | — | @@ -223,6 +225,11 @@ |
224 | 226 | DWORD ebBufferSize;
|
225 | 227 | unsigned char *outbuffer;
|
226 | 228 | DWORD outbuffersize;
|
| 229 | + D3DVALUE scalex;
|
| 230 | + D3DVALUE scaley;
|
| 231 | + D3DMATRIXHANDLE mhWorld;
|
| 232 | + D3DMATRIXHANDLE mhView;
|
| 233 | + D3DMATRIXHANDLE mhProjection;
|
227 | 234 | };
|
228 | 235 |
|
229 | 236 | #endif //__GLDIRECT3DDEVICE_H
|
Index: ddraw/glDirect3DViewport.cpp |
— | — | @@ -294,6 +294,8 @@ |
295 | 295 | vp.dvClipX = viewport.dvClipX;
|
296 | 296 | vp.dvClipY = viewport.dvClipY;
|
297 | 297 | viewport = vp;
|
| 298 | + scaleX = lpData->dvScaleX;
|
| 299 | + scaleY = lpData->dvScaleY;
|
298 | 300 | if(current && device) Sync();
|
299 | 301 | return D3D_OK;
|
300 | 302 | }
|
— | — | @@ -334,6 +336,7 @@ |
335 | 337 | vp7.dvMinZ = viewport.dvMinZ;
|
336 | 338 | vp7.dvMaxZ = viewport.dvMaxZ;
|
337 | 339 | device->SetViewport(&vp7);
|
| 340 | + device->SetScale(scaleX,scaleY);
|
338 | 341 | }
|
339 | 342 |
|
340 | 343 | void glDirect3DViewport3::SyncLights()
|
Index: ddraw/shadergen.cpp |
— | — | @@ -280,7 +280,7 @@ |
281 | 281 | gl_Position = vec4(pos.x,-pos.y,pos.z,pos.w);\n";
|
282 | 282 | static const char op_normalize[] = "N = normalize(gl_NormalMatrix*nxyz);\n";
|
283 | 283 | static const char op_normalpassthru[] = "N = gl_NormalMatrix*nxyz;\n";
|
284 | | -static const char op_passthru[] = "gl_Position = vec4(((xyz.x/rhw)/(width/2.0))-1.0,((xyz.y/rhw)/(height/2.0))-1.0,(xyz.z/rhw),1.0/rhw);\n";
|
| 284 | +static const char op_passthru[] = "gl_Position = vec4(((xyz.x)/(width/2.0))-1.0,((xyz.y)/(height/2.0))-1.0,(xyz.z),1.0);\n";
|
285 | 285 | static const char op_resetcolor[] = "diffuse = specular = vec4(0.0);\n\
|
286 | 286 | ambient = ambientcolor / 255.0;\n";
|
287 | 287 | static const char op_dirlight[] = "DirLight(lightX);\n";
|