1 /* 2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <iostream> 27 28 #include "D3DPipeline.h" 29 #include "D3DContext.h" 30 #include "D3DPipelineManager.h" 31 #include "PassThroughVS.h" 32 33 #include "com_sun_prism_d3d_D3DContext.h" 34 #include "D3DLight.h" 35 #include "D3DMesh.h" 36 #include "D3DMeshView.h" 37 #include "D3DPhongMaterial.h" 38 using std::cout; 39 using std::endl; 40 /** 41 * Note: this method assumes that r is different from a, b! 42 */ 43 inline void D3DUtils_MatrixMultTransposed(D3DMATRIX& r, const D3DMATRIX& a, const D3DMATRIX& b) { 44 for (int i=0; i<4; i++) { 45 for (int j=0; j<4; j++) { 46 float t = 0; 47 for (int k=0; k<4; k++) { 48 // transpose on the fly 49 t += a.m[i][k] * b.m[k][j]; 50 } 51 r.m[j][i] = t; 52 } 53 } 54 } 55 56 inline void D3DUtils_MatrixTransposed(D3DMATRIX& r, const D3DMATRIX& a) { 57 for (int i=0; i<4; i++) { 58 for (int j=0; j<4; j++) { 59 r.m[j][i] = a.m[i][j]; 60 } 61 } 62 } 63 64 inline void D3DUtils_SetIdentityMatrix(D3DMATRIX *m) { 65 m->_12 = m->_13 = m->_14 = m->_21 = m->_23 = m->_24 = 0.0f; 66 m->_31 = m->_32 = m->_34 = m->_41 = m->_42 = m->_43 = 0.0f; 67 m->_11 = m->_22 = m->_33 = m->_44 = 1.0f; 68 } 69 70 // static 71 HRESULT 72 D3DContext::CreateInstance(IDirect3D9 *pd3d9, IDirect3D9Ex *pd3d9Ex, UINT adapter, D3DContext **ppCtx) 73 { 74 HRESULT res; 75 *ppCtx = new D3DContext(pd3d9, pd3d9Ex, adapter); 76 if (FAILED(res = (*ppCtx)->InitContext())) { 77 delete *ppCtx; 78 *ppCtx = NULL; 79 } 80 return res; 81 } 82 83 D3DContext::D3DContext(IDirect3D9 *pd3d, IDirect3D9Ex *pd3dEx, UINT adapter) 84 { 85 TraceLn(NWT_TRACE_INFO, "D3DContext::D3DContext"); 86 TraceLn1(NWT_TRACE_VERBOSE, " pd3d=0x%x", pd3d); 87 pd3dObject = pd3d; 88 pd3dObjectEx = pd3dEx; 89 pd3dDevice = NULL; 90 pd3dDeviceEx = NULL; 91 adapterOrdinal = adapter; 92 defaulResourcePool = D3DPOOL_SYSTEMMEM; 93 94 pResourceMgr = NULL; 95 96 pPassThroughVS = NULL; 97 pVertexDecl = NULL; 98 pIndices = NULL; 99 pVertexBufferRes = NULL; 100 101 bBeginScenePending = FALSE; 102 phongShader = NULL; 103 104 ZeroMemory(&devCaps, sizeof(D3DCAPS9)); 105 ZeroMemory(&curParams, sizeof(curParams)); 106 } 107 108 /** 109 * This method releases context resources either from the default pool only 110 * (basically from vram) or all of them, depending on the passed argument. 111 * 112 * Note that some resources are still not under ResourceManager control so we 113 * have to handle them separately. Ideally we'd move every allocated resource 114 * under RM control. 115 * 116 * The reason we have single method instead of a pair of methods (one for 117 * default only and one for everything) is to reduce code duplication. It is 118 * possible to call ReleaseDefPoolResources from ReleaseContextResources but 119 * then we'd traverse the resources list twice (may not be a big deal). 120 */ 121 void D3DContext::ReleaseContextResources(int releaseType) 122 { 123 TraceLn2(NWT_TRACE_INFO, 124 "D3DContext::ReleaseContextResources: %d pd3dDevice = 0x%x", 125 releaseType, pd3dDevice); 126 127 if (releaseType != RELEASE_ALL && releaseType != RELEASE_DEFAULT) { 128 TraceLn1(NWT_TRACE_ERROR, 129 "D3DContext::ReleaseContextResources unknown type: %d", 130 releaseType); 131 return; 132 } 133 134 EndScene(); 135 136 if (releaseType == RELEASE_DEFAULT) { 137 if (pVertexBufferRes != NULL && pVertexBufferRes->IsDefaultPool()) { 138 // if VB is in the default pool it will be released by the RM 139 pVertexBufferRes = NULL; 140 } 141 pResourceMgr->ReleaseDefPoolResources(); 142 } else if (releaseType == RELEASE_ALL){ 143 // will be released with the resource manager 144 pVertexBufferRes = NULL; 145 SAFE_RELEASE(pVertexDecl); 146 SAFE_RELEASE(pIndices); 147 SAFE_RELEASE(pPassThroughVS); 148 SAFE_DELETE(pResourceMgr); 149 } 150 } 151 152 D3DContext::~D3DContext() {} 153 154 int D3DContext::release() { 155 156 TraceLn2(NWT_TRACE_INFO, 157 "~D3DContext: pd3dDevice=0x%x, pd3dObject =0x%x", 158 pd3dDevice, pd3dObject); 159 ReleaseContextResources(RELEASE_ALL); 160 SAFE_RELEASE(pd3dDevice); 161 SAFE_RELEASE(pd3dDeviceEx); 162 163 if (phongShader) { 164 delete phongShader; 165 phongShader = NULL; 166 } 167 168 delete this; 169 return 0; 170 } 171 172 /* 173 * Class: com_sun_prism_d3d_D3DContext 174 * Method: nCreateD3DMesh 175 * Signature: (J)J 176 */ 177 JNIEXPORT jlong JNICALL Java_com_sun_prism_d3d_D3DContext_nCreateD3DMesh 178 (JNIEnv *env, jclass, jlong ctx) 179 { 180 TraceLn(NWT_TRACE_INFO, "D3DContext_nCreateD3DMesh"); 181 D3DContext *pCtx = (D3DContext*) jlong_to_ptr(ctx); 182 RETURN_STATUS_IF_NULL(pCtx, 0L); 183 184 D3DMesh *mesh = new D3DMesh(pCtx); 185 return ptr_to_jlong(mesh); 186 } 187 188 /* 189 * Class: com_sun_prism_d3d_D3DContext 190 * Method: nReleaseD3DMesh 191 * Signature: (JJ)V 192 */ 193 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nReleaseD3DMesh 194 (JNIEnv *env, jclass, jlong ctx, jlong nativeMesh) 195 { 196 TraceLn(NWT_TRACE_INFO, "D3DContext_nReleaseD3DMesh"); 197 D3DMesh *mesh = (D3DMesh *) jlong_to_ptr(nativeMesh); 198 if (mesh) { 199 delete mesh; 200 } 201 } 202 203 /* 204 * Class: com_sun_prism_d3d_D3DContext 205 * Method: nBuildNativeGeometryShort 206 * Signature: (JJ[FI[SI)Z 207 */ 208 JNIEXPORT jboolean JNICALL Java_com_sun_prism_d3d_D3DContext_nBuildNativeGeometryShort 209 (JNIEnv *env, jclass, jlong ctx, jlong nativeMesh, jfloatArray vb, jint vbSize, jshortArray ib, jint ibSize) 210 { 211 TraceLn(NWT_TRACE_INFO, "D3DContext_nBuildNativeGeometryShort"); 212 D3DMesh *mesh = (D3DMesh *) jlong_to_ptr(nativeMesh); 213 RETURN_STATUS_IF_NULL(mesh, JNI_FALSE); 214 215 UINT vertexBufferSize = env->GetArrayLength(vb); 216 float *vertexBuffer = (float *) (env->GetPrimitiveArrayCritical(vb, NULL)); 217 UINT indexBufferSize = env->GetArrayLength(ib); 218 USHORT *indexBuffer = (USHORT *) (env->GetPrimitiveArrayCritical(ib, NULL)); 219 220 if (vbSize < 0 || ibSize < 0) { 221 return JNI_FALSE; 222 } 223 224 UINT uvbSize = (UINT) vbSize; 225 UINT uibSize = (UINT) ibSize; 226 if (vertexBuffer == NULL || indexBuffer == NULL 227 || uvbSize > vertexBufferSize || uibSize > indexBufferSize) { 228 return JNI_FALSE; 229 } 230 231 boolean result = mesh->buildBuffers(vertexBuffer, uvbSize, indexBuffer, uibSize); 232 env->ReleasePrimitiveArrayCritical(ib, indexBuffer, 0); 233 env->ReleasePrimitiveArrayCritical(vb, vertexBuffer, 0); 234 235 return result; 236 } 237 238 /* 239 * Class: com_sun_prism_d3d_D3DContext 240 * Method: nBuildNativeGeometryInt 241 * Signature: (JJ[FI[II)Z 242 */ 243 JNIEXPORT jboolean JNICALL Java_com_sun_prism_d3d_D3DContext_nBuildNativeGeometryInt 244 (JNIEnv *env, jclass, jlong ctx, jlong nativeMesh, jfloatArray vb, jint vbSize, jintArray ib, jint ibSize) 245 { 246 TraceLn(NWT_TRACE_INFO, "D3DContext_nBuildNativeGeometryInt"); 247 D3DMesh *mesh = (D3DMesh *) jlong_to_ptr(nativeMesh); 248 RETURN_STATUS_IF_NULL(mesh, JNI_FALSE); 249 250 UINT vertexBufferSize = env->GetArrayLength(vb); 251 float *vertexBuffer = (float *) (env->GetPrimitiveArrayCritical(vb, NULL)); 252 UINT indexBufferSize = env->GetArrayLength(ib); 253 UINT *indexBuffer = (UINT *) (env->GetPrimitiveArrayCritical(ib, NULL)); 254 255 if (vbSize < 0 || ibSize < 0) { 256 return JNI_FALSE; 257 } 258 259 UINT uvbSize = (UINT) vbSize; 260 UINT uibSize = (UINT) ibSize; 261 if (vertexBuffer == NULL || indexBuffer == NULL 262 || uvbSize > vertexBufferSize || uibSize > indexBufferSize) { 263 return JNI_FALSE; 264 } 265 266 boolean result = mesh->buildBuffers(vertexBuffer, uvbSize, indexBuffer, uibSize); 267 env->ReleasePrimitiveArrayCritical(ib, indexBuffer, 0); 268 env->ReleasePrimitiveArrayCritical(vb, vertexBuffer, 0); 269 270 return result; 271 } 272 273 /* 274 * Class: com_sun_prism_d3d_D3DContext 275 * Method: nCreateD3DPhongMaterial 276 * Signature: (J)J 277 */ 278 JNIEXPORT jlong JNICALL Java_com_sun_prism_d3d_D3DContext_nCreateD3DPhongMaterial 279 (JNIEnv *env, jclass, jlong ctx) 280 { 281 TraceLn(NWT_TRACE_INFO, "D3DContext_nCreateD3DPhongMaterial"); 282 D3DContext *pCtx = (D3DContext*) jlong_to_ptr(ctx); 283 RETURN_STATUS_IF_NULL(pCtx, 0L); 284 285 D3DPhongMaterial *phongMaterial = new D3DPhongMaterial(pCtx); 286 return ptr_to_jlong(phongMaterial); 287 } 288 289 /* 290 * Class: com_sun_prism_d3d_D3DContext 291 * Method: nReleaseD3DPhongMaterial 292 * Signature: (JJ)V 293 */ 294 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nReleaseD3DPhongMaterial 295 (JNIEnv *env, jclass, jlong ctx, jlong nativePhongMaterial) 296 { 297 TraceLn(NWT_TRACE_INFO, "D3DContext_nReleaseD3DPhongMaterial"); 298 D3DPhongMaterial *phongMaterial = (D3DPhongMaterial *) jlong_to_ptr(nativePhongMaterial); 299 if (phongMaterial) { 300 delete phongMaterial; 301 } 302 } 303 304 /* 305 * Class: com_sun_prism_d3d_D3DContext 306 * Method: nSetSolidColor 307 * Signature: (JJFFFF)V 308 */ 309 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nSetSolidColor 310 (JNIEnv *env, jclass, jlong ctx, jlong nativePhongMaterial, 311 jfloat r, jfloat g, jfloat b, jfloat a) 312 { 313 TraceLn(NWT_TRACE_INFO, "D3DContext_nSetSolidColor"); 314 D3DPhongMaterial *phongMaterial = (D3DPhongMaterial *) jlong_to_ptr(nativePhongMaterial); 315 RETURN_IF_NULL(phongMaterial); 316 317 phongMaterial->setSolidColor(r, g, b, a); 318 } 319 320 /* 321 * Class: com_sun_prism_d3d_D3DContext 322 * Method: nSetMap 323 * Signature: (JJIJZZ)V 324 */ 325 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nSetMap 326 (JNIEnv *env, jclass, jlong ctx, jlong nativePhongMaterial, 327 jint mapType, jlong nativeTexture, jboolean isSpecularAlpha, jboolean isBumpAlpha) 328 { 329 TraceLn(NWT_TRACE_INFO, "D3DContext_nSetMap"); 330 D3DPhongMaterial *phongMaterial = (D3DPhongMaterial *) jlong_to_ptr(nativePhongMaterial); 331 IDirect3DBaseTexture9 *texMap = (IDirect3DBaseTexture9 *) jlong_to_ptr(nativeTexture); 332 RETURN_IF_NULL(phongMaterial); 333 334 phongMaterial->setMap(mapType, texMap, isSpecularAlpha ? true : false, isBumpAlpha ? true : false); 335 } 336 337 /* 338 * Class: com_sun_prism_d3d_D3DContext 339 * Method: nCreateD3DMeshView 340 * Signature: (JJ)J 341 */ 342 JNIEXPORT jlong JNICALL Java_com_sun_prism_d3d_D3DContext_nCreateD3DMeshView 343 (JNIEnv *env, jclass, jlong ctx, jlong nativeMesh) 344 { 345 TraceLn(NWT_TRACE_INFO, "D3DContext_nCreateD3DMeshView"); 346 D3DContext *pCtx = (D3DContext*) jlong_to_ptr(ctx); 347 RETURN_STATUS_IF_NULL(pCtx, 0L); 348 349 D3DMesh *mesh = (D3DMesh *) jlong_to_ptr(nativeMesh); 350 RETURN_STATUS_IF_NULL(mesh, 0L); 351 352 D3DMeshView *meshView = new D3DMeshView(pCtx, mesh); 353 return ptr_to_jlong(meshView); 354 } 355 356 /* 357 * Class: com_sun_prism_d3d_D3DContext 358 * Method: nReleaseD3DMeshView 359 * Signature: (JJ)V 360 */ 361 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nReleaseD3DMeshView 362 (JNIEnv *env, jclass, jlong ctx, jlong nativeMeshView) 363 { 364 TraceLn(NWT_TRACE_INFO, "D3DContext_nReleaseD3DMeshView"); 365 D3DMeshView *meshView = (D3DMeshView *) jlong_to_ptr(nativeMeshView); 366 if (meshView) { 367 delete meshView; 368 } 369 } 370 371 /* 372 * Class: com_sun_prism_d3d_D3DContext 373 * Method: nSetCullingMode 374 * Signature: (JJI)V 375 */ 376 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nSetCullingMode 377 (JNIEnv *env, jclass, jlong ctx, jlong nativeMeshView, jint cullMode) 378 { 379 TraceLn(NWT_TRACE_INFO, "D3DContext_nSetCullingMode"); 380 D3DMeshView *meshView = (D3DMeshView *) jlong_to_ptr(nativeMeshView); 381 RETURN_IF_NULL(meshView); 382 383 switch (cullMode) { 384 case com_sun_prism_d3d_D3DContext_CULL_BACK: 385 cullMode = D3DCULL_CW; 386 break; 387 case com_sun_prism_d3d_D3DContext_CULL_FRONT: 388 cullMode = D3DCULL_CCW; 389 break; 390 case com_sun_prism_d3d_D3DContext_CULL_NONE: 391 cullMode = D3DCULL_NONE; 392 break; 393 } 394 meshView->setCullingMode(cullMode); 395 } 396 397 /* 398 * Class: com_sun_prism_d3d_D3DContext 399 * Method: nBlit 400 * Signature: (JJJIIIIIIII)V 401 */ 402 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nBlit 403 (JNIEnv *env, jclass, jlong ctx, jlong nSrcRTT, jlong nDstRTT, 404 jint srcX0, jint srcY0, jint srcX1, jint srcY1, 405 jint dstX0, jint dstY0, jint dstX1, jint dstY1) 406 { 407 TraceLn(NWT_TRACE_INFO, "D3DContext_nBlit"); 408 D3DContext *pCtx = (D3DContext*) jlong_to_ptr(ctx); 409 RETURN_IF_NULL(pCtx); 410 411 D3DResource *srcRes = (D3DResource*) jlong_to_ptr(nSrcRTT); 412 if (srcRes == NULL) { 413 TraceLn(NWT_TRACE_INFO, " error srcRes is NULL"); 414 return; 415 } 416 417 IDirect3DSurface9 *pSrcSurface = srcRes->GetSurface(); 418 if (pSrcSurface == NULL) { 419 TraceLn(NWT_TRACE_INFO, " error pSrcSurface is NULL"); 420 return; 421 } 422 423 D3DResource *dstRes = (D3DResource*) jlong_to_ptr(nDstRTT); 424 IDirect3DSurface9 *pDstSurface = (dstRes == NULL) ? NULL : dstRes->GetSurface(); 425 426 pCtx->stretchRect(pSrcSurface, srcX0, srcY0, srcX1, srcY1, 427 pDstSurface, dstX0, dstY0, dstX1, dstY1); 428 } 429 430 /* 431 * Class: com_sun_prism_d3d_D3DContext 432 * Method: nSetMaterial 433 * Signature: (JJJ)V 434 */ 435 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nSetMaterial 436 (JNIEnv *env, jclass, jlong ctx, jlong nativeMeshView, jlong nativePhongMaterial) 437 { 438 TraceLn(NWT_TRACE_INFO, "D3DContext_nSetMaterial"); 439 D3DMeshView *meshView = (D3DMeshView *) jlong_to_ptr(nativeMeshView); 440 RETURN_IF_NULL(meshView); 441 442 D3DPhongMaterial *phongMaterial = (D3DPhongMaterial *) jlong_to_ptr(nativePhongMaterial); 443 meshView->setMaterial(phongMaterial); 444 } 445 446 /* 447 * Class: com_sun_prism_d3d_D3DContext 448 * Method: nSetWireframe 449 * Signature: (JJZ)V 450 */ 451 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nSetWireframe 452 (JNIEnv *env, jclass, jlong ctx, jlong nativeMeshView, jboolean wireframe) 453 { 454 TraceLn(NWT_TRACE_INFO, "D3DContext_nSetWireframe"); 455 D3DMeshView *meshView = (D3DMeshView *) jlong_to_ptr(nativeMeshView); 456 RETURN_IF_NULL(meshView); 457 458 meshView->setWireframe(wireframe ? true : false); 459 } 460 461 /* 462 * Class: com_sun_prism_d3d_D3DContext 463 * Method: nSetAmbientLight 464 * Signature: (JJFFF)V 465 */ 466 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nSetAmbientLight 467 (JNIEnv *env, jclass, jlong ctx, jlong nativeMeshView, 468 jfloat r, jfloat g, jfloat b) 469 { 470 TraceLn(NWT_TRACE_INFO, "D3DContext_nSetAmbientLight"); 471 D3DMeshView *meshView = (D3DMeshView *) jlong_to_ptr(nativeMeshView); 472 RETURN_IF_NULL(meshView); 473 474 meshView->setAmbientLight(r, g, b); 475 } 476 477 /* 478 * Class: com_sun_prism_d3d_D3DContext 479 * Method: nSetPointLight 480 * Signature: (JJIFFFFFFF)V 481 */ 482 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nSetPointLight 483 (JNIEnv *env, jclass, jlong ctx, jlong nativeMeshView, jint index, 484 jfloat x, jfloat y, jfloat z, jfloat r, jfloat g, jfloat b, jfloat w) 485 { 486 TraceLn(NWT_TRACE_INFO, "D3DContext_nSetPointLight"); 487 D3DMeshView *meshView = (D3DMeshView *) jlong_to_ptr(nativeMeshView); 488 RETURN_IF_NULL(meshView); 489 490 meshView->setPointLight(index, x, y, z, r, g, b, w); 491 } 492 493 /* 494 * Class: com_sun_prism_d3d_D3DContext 495 * Method: nRenderMeshView 496 * Signature: (JJ)V 497 */ 498 JNIEXPORT void JNICALL Java_com_sun_prism_d3d_D3DContext_nRenderMeshView 499 (JNIEnv *env, jclass, jlong ctx, jlong nativeMeshView) 500 { 501 TraceLn(NWT_TRACE_INFO, "D3DContext_nRenderMeshView"); 502 D3DMeshView *meshView = (D3DMeshView *) jlong_to_ptr(nativeMeshView); 503 RETURN_IF_NULL(meshView); 504 505 meshView->render(); 506 } 507 508 /* 509 * Class: com_sun_prism_d3d_D3DContext 510 * Method: nSetDeviceParametersFor2D 511 */ 512 513 JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DContext_nSetDeviceParametersFor2D 514 (JNIEnv *, jclass, jlong ctx) 515 { 516 TraceLn(NWT_TRACE_INFO, "D3DContext_nSetDeviceParametersFor2D"); 517 D3DContext *pCtx = (D3DContext*)jlong_to_ptr(ctx); 518 RETURN_STATUS_IF_NULL(pCtx, S_FALSE); 519 520 return pCtx->setDeviceParametersFor2D(); 521 } 522 523 HRESULT D3DContext::setDeviceParametersFor2D() { 524 525 RETURN_STATUS_IF_NULL(pd3dDevice, S_FALSE); 526 527 HRESULT res = S_OK; 528 529 IDirect3DVertexBuffer9 *vb = pVertexBufferRes->GetVertexBuffer(); 530 531 SUCCEEDED(res = pd3dDevice->SetVertexDeclaration(pVertexDecl)) && 532 SUCCEEDED(res = pd3dDevice->SetIndices(pIndices)) && 533 SUCCEEDED(res = pd3dDevice->SetVertexShader(pPassThroughVS)) && 534 SUCCEEDED(res = pd3dDevice->SetStreamSource(0, vb, 0, sizeof (PRISM_VERTEX_2D))); 535 536 if (res == S_OK) { 537 // Note: No need to restore blend and scissor states as the 2D states were 538 // invalidated on the Java side. 539 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE)) && 540 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID)) && 541 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE)); 542 } 543 return res; 544 } 545 546 /* 547 * Class: com_sun_prism_d3d_D3DContext 548 * Method: nSetDeviceParametersFor3D 549 */ 550 551 JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DContext_nSetDeviceParametersFor3D 552 (JNIEnv *, jclass, jlong ctx) 553 { 554 TraceLn(NWT_TRACE_INFO, "D3DContext_nSet3DVShaderAndVertexBuffer"); 555 D3DContext *pCtx = (D3DContext*)jlong_to_ptr(ctx); 556 RETURN_STATUS_IF_NULL(pCtx, S_FALSE); 557 558 return pCtx->setDeviceParametersFor3D(); 559 } 560 561 HRESULT D3DContext::setDeviceParametersFor3D() { 562 563 RETURN_STATUS_IF_NULL(pd3dDevice, S_FALSE); 564 565 D3DMATRIX mat; 566 HRESULT res = S_OK; 567 float cPos[4]; 568 569 if (!phongShader) { 570 phongShader = new D3DPhongShader(pd3dDevice); 571 } 572 573 D3DUtils_MatrixTransposed(mat, projection); 574 cPos[0] = camPos.x; 575 cPos[1] = camPos.y; 576 cPos[2] = camPos.z; 577 cPos[3] = 0; 578 579 // std::cout << "Camera Position: " << camPos.x << ", " << camPos.y << ", " << camPos.z << std::endl; 580 // Use D3DPhongShader.h -- VSR_VIEWPROJMATRIX, VSR_CAMERAPOS 581 SUCCEEDED(res = pd3dDevice->SetVertexShaderConstantF(VSR_VIEWPROJMATRIX, (float*) mat.m, 4)) && 582 SUCCEEDED(res = pd3dDevice->SetVertexShaderConstantF(VSR_CAMERAPOS, cPos, 1)); 583 584 // Reset 3D states 585 state.wireframe = false; 586 state.cullMode = D3DCULL_NONE; 587 if (res == S_OK) { 588 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE)) && 589 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID)) && 590 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE)) && 591 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO)) && 592 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE)) && 593 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE)) && 594 SUCCEEDED(res = pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE)); 595 } 596 return res; 597 } 598 599 /* 600 * Note: this method assumes that pIndices is not null 601 */ 602 static HRESULT fillQuadIndices(IDirect3DIndexBuffer9 *pIndices, int maxQuads) { 603 short * data = 0; 604 HRESULT hr = pIndices->Lock(0, maxQuads * 6 * sizeof(short), (void **)&data, 0); 605 if (SUCCEEDED(hr) && data) { 606 for (int i = 0; i != maxQuads; ++i) { 607 int vtx = i * 4; 608 int idx = i * 6; 609 data[idx + 0] = vtx + 0; 610 data[idx + 1] = vtx + 1; 611 data[idx + 2] = vtx + 2; 612 data[idx + 3] = vtx + 2; 613 data[idx + 4] = vtx + 1; 614 data[idx + 5] = vtx + 3; 615 } 616 hr = pIndices->Unlock(); 617 } 618 return hr; 619 } 620 621 HRESULT D3DContext::InitDevice(IDirect3DDevice9 *pd3dDevice) 622 { 623 #if defined PERF_COUNTERS 624 stats.clear(); 625 #endif 626 627 RETURN_STATUS_IF_NULL(pd3dDevice, S_FALSE); 628 629 HRESULT res = S_OK; 630 631 pd3dDevice->GetDeviceCaps(&devCaps); 632 633 RlsTraceLn1(NWT_TRACE_INFO, 634 "D3DContext::InitDevice: device %d", adapterOrdinal); 635 636 // disable some of the unneeded and costly d3d functionality 637 pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE); 638 pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); 639 pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); 640 pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE); 641 pd3dDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE); 642 pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); 643 644 // set clipping to true inorder support near and far clipping 645 pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE); 646 647 pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 648 pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); 649 state.wireframe = false; 650 state.cullMode = D3DCULL_NONE; 651 652 if (pResourceMgr == NULL) { 653 pResourceMgr = D3DResourceManager::CreateInstance(this); 654 } 655 656 D3DUtils_SetIdentityMatrix(&world); 657 D3DUtils_SetIdentityMatrix(&projection); 658 camPos.x = 0.0f; 659 camPos.y = 0.0f; 660 camPos.z = 0.0f; 661 662 pixadjustx = pixadjusty = 0.0f; 663 664 if (pVertexDecl == NULL) { 665 res = pd3dDevice->CreateVertexDeclaration(PrismVDecl, &pVertexDecl); 666 RETURN_STATUS_IF_FAILED(res); 667 } 668 // res = pd3dDevice->SetVertexDeclaration(pVertexDecl); 669 // RETURN_STATUS_IF_FAILED(res); 670 671 if (pIndices == NULL) { 672 res = pd3dDevice->CreateIndexBuffer(sizeof(short) * 6 * MAX_BATCH_QUADS, 673 D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, getResourcePool(), &pIndices, 0); 674 if (pIndices) { 675 res = fillQuadIndices(pIndices, MAX_BATCH_QUADS); 676 } 677 RETURN_STATUS_IF_FAILED(res); 678 } 679 // res = pd3dDevice->SetIndices(pIndices); 680 // RETURN_STATUS_IF_FAILED(res); 681 682 if (pPassThroughVS == NULL) { 683 res = pd3dDevice->CreateVertexShader((DWORD*)g_vs30_passThrough, &pPassThroughVS); 684 RETURN_STATUS_IF_FAILED(res); 685 } 686 // res = pd3dDevice->SetVertexShader(pPassThroughVS); 687 // RETURN_STATUS_IF_FAILED(res); 688 689 if (pVertexBufferRes == NULL) { 690 res = GetResourceManager()->CreateVertexBuffer(&pVertexBufferRes); 691 RETURN_STATUS_IF_FAILED(res); 692 } 693 // res = pd3dDevice->SetStreamSource(0, pVertexBufferRes->GetVertexBuffer(), 694 // 0, sizeof(PRISM_VERTEX_2D)); 695 // RETURN_STATUS_IF_FAILED(res); 696 697 bBeginScenePending = FALSE; 698 699 RlsTraceLn1(NWT_TRACE_INFO, 700 "D3DContext::InitDevice: successfully initialized device %d", 701 adapterOrdinal); 702 703 return res; 704 } 705 706 HRESULT 707 D3DContext::TestCooperativeLevel() 708 { 709 TraceLn(NWT_TRACE_INFO, "D3DContext::testCooperativeLevel"); 710 711 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 712 713 HRESULT res = pd3dDevice->TestCooperativeLevel(); 714 715 switch (res) { 716 case S_OK: break; 717 case D3DERR_DEVICELOST: 718 TraceLn1(NWT_TRACE_VERBOSE, " device %d is still lost", 719 adapterOrdinal); 720 break; 721 case D3DERR_DEVICENOTRESET: 722 TraceLn1(NWT_TRACE_VERBOSE, " device %d needs to be reset", 723 adapterOrdinal); 724 break; 725 case E_FAIL: 726 TraceLn(NWT_TRACE_VERBOSE, " null device"); 727 break; 728 default: 729 TraceLn1(NWT_TRACE_ERROR, "D3DContext::testCooperativeLevel: "\ 730 "unknown error %x from TestCooperativeLevel", res); 731 } 732 733 return res; 734 } 735 736 HRESULT 737 D3DContext::Clear(DWORD colorArgbPre, BOOL clearDepth, BOOL ignoreScissor) 738 { 739 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 740 741 HRESULT res; 742 DWORD bSE = FALSE; 743 DWORD bDE = FALSE; 744 DWORD flags = D3DCLEAR_TARGET; 745 746 if (ignoreScissor) { 747 // scissor test affects Clear so it needs to be disabled first 748 pd3dDevice->GetRenderState(D3DRS_SCISSORTESTENABLE, &bSE); 749 if (bSE) { 750 pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); 751 } 752 } 753 if (clearDepth) { 754 // Must ensure that there is a depth buffer before attempting to clear it 755 IDirect3DSurface9 *pCurrentDepth = NULL; 756 pd3dDevice->GetDepthStencilSurface(&pCurrentDepth); 757 clearDepth = pCurrentDepth == NULL ? FALSE : clearDepth; 758 SAFE_RELEASE(pCurrentDepth); 759 } 760 if (clearDepth) { 761 flags |= D3DCLEAR_ZBUFFER; 762 // also make sure depth writes are enabled for the clear operation 763 pd3dDevice->GetRenderState(D3DRS_ZWRITEENABLE, &bDE); 764 if (!bDE) { 765 pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_TRUE); 766 } 767 } 768 769 res = pd3dDevice->Clear(0, NULL, flags, colorArgbPre, 1.0f, 0x0L); 770 771 // restore previous state 772 if (ignoreScissor && bSE) { 773 pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); 774 } 775 if (clearDepth && !bDE) { 776 pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE); 777 } 778 return res; 779 } 780 781 BOOL D3DContext::IsDepthStencilBufferOk(D3DSURFACE_DESC *pTargetDesc, IDirect3DSurface9 *pTargetDepth) 782 { 783 TraceLn(NWT_TRACE_INFO, "D3DContext::IsDepthStencilBufferOk"); 784 785 RETURN_STATUS_IF_NULL(pTargetDepth, true); 786 RETURN_STATUS_IF_NULL(pd3dDevice, false); 787 RETURN_STATUS_IF_NULL(pd3dObject, false); 788 789 D3DSURFACE_DESC descStencil; 790 pTargetDepth->GetDesc(&descStencil); 791 792 D3DDISPLAYMODE dm; 793 return 794 (SUCCEEDED(pd3dDevice->GetDisplayMode(0, &dm)) && 795 pTargetDesc->Width <= descStencil.Width && 796 pTargetDesc->Height <= descStencil.Height && 797 pTargetDesc->MultiSampleType == descStencil.MultiSampleType && 798 pTargetDesc->MultiSampleQuality == descStencil.MultiSampleQuality && 799 SUCCEEDED(pd3dObject->CheckDepthStencilMatch( 800 adapterOrdinal, 801 devCaps.DeviceType, 802 dm.Format, pTargetDesc->Format, 803 descStencil.Format))); 804 } 805 806 HRESULT 807 D3DContext::InitDepthStencilBuffer(D3DSURFACE_DESC *pTargetDesc, IDirect3DSurface9 **ppDepthSSurface) 808 { 809 TraceLn(NWT_TRACE_INFO, "D3DContext::InitDepthStencilBuffer"); 810 811 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 812 RETURN_STATUS_IF_NULL(pTargetDesc, E_FAIL); 813 814 HRESULT res; 815 D3DDISPLAYMODE dm; 816 if (FAILED(res = pd3dDevice->GetDisplayMode(0, &dm))) { 817 return res; 818 } 819 820 D3DFORMAT newFormat = 821 D3DPipelineManager::GetInstance()->GetMatchingDepthStencilFormat( 822 adapterOrdinal, dm.Format, pTargetDesc->Format); 823 824 res = pd3dDevice->CreateDepthStencilSurface( 825 pTargetDesc->Width, pTargetDesc->Height, newFormat, 826 pTargetDesc->MultiSampleType, pTargetDesc->MultiSampleQuality, false, ppDepthSSurface, 0); 827 828 return res; 829 } 830 831 HRESULT 832 D3DContext::UpdateVertexShaderTX() 833 { 834 TraceLn(NWT_TRACE_INFO, "D3DContext::UpdateVertexShaderTX"); 835 836 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 837 838 D3DMATRIX wvp; 839 // create the WorldViewProj matrix 840 // wvp = T(w * v * p); 841 // since view is currently included in the projection matrix, wvp = T(w * p) 842 D3DUtils_MatrixMultTransposed(wvp, world, projection); 843 // Apply the pixel adjustment values for the current render target. 844 // These values adjust our default (identity) coordinates so that the 845 // pixel edges are at integer coordinate locations. 846 wvp._14 += pixadjustx; 847 wvp._24 += pixadjusty; 848 849 // fprintf(stderr, "UpdateVertexShaderTX:\n"); 850 // fprintf(stderr, " %5f %5f %5f %5f\n", wvp._11, wvp._12, wvp._13, wvp._14); 851 // fprintf(stderr, " %5f %5f %5f %5f\n", wvp._21, wvp._22, wvp._23, wvp._24); 852 // fprintf(stderr, " %5f %5f %5f %5f\n", wvp._31, wvp._32, wvp._33, wvp._34); 853 // fprintf(stderr, " %5f %5f %5f %5f\n", wvp._41, wvp._42, wvp._43, wvp._44); 854 855 return pd3dDevice->SetVertexShaderConstantF(0, (float*)wvp.m, 4); 856 } 857 858 HRESULT 859 D3DContext::SetRenderTarget(IDirect3DSurface9 *pSurface, 860 IDirect3DSurface9 **ppTargetDepthSurface, 861 BOOL depthBuffer, BOOL msaa) 862 { 863 TraceLn1(NWT_TRACE_INFO, 864 "D3DContext::SetRenderTarget: pSurface=0x%x", 865 pSurface); 866 867 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 868 RETURN_STATUS_IF_NULL(pSurface, E_FAIL); 869 870 HRESULT res; 871 D3DSURFACE_DESC descNew; 872 IDirect3DSurface9 *pCurrentTarget; 873 bool renderTargetChanged = false; 874 875 pSurface->GetDesc(&descNew); 876 877 if (SUCCEEDED(res = pd3dDevice->GetRenderTarget(0, &pCurrentTarget))) { 878 if (pCurrentTarget != pSurface) { 879 renderTargetChanged = true; 880 #if defined PERF_COUNTERS 881 getStats().numRenderTargetSwitch++; 882 #endif 883 884 if (FAILED(res = pd3dDevice->SetRenderTarget(0, pSurface))) { 885 DebugPrintD3DError(res, "D3DContext::SetRenderTarget: "\ 886 "error setting render target"); 887 SAFE_RELEASE(pCurrentTarget); 888 return res; 889 } 890 891 currentSurface = pSurface; 892 } 893 SAFE_RELEASE(pCurrentTarget); 894 895 IDirect3DSurface9 *pCurrentDepth; 896 res = pd3dDevice->GetDepthStencilSurface(&pCurrentDepth); 897 if (res == D3DERR_NOTFOUND) { 898 pCurrentDepth = NULL; 899 res = D3D_OK; 900 } else if (FAILED(res)) { 901 return res; 902 } 903 904 if (!IsDepthStencilBufferOk(&descNew, *ppTargetDepthSurface)) { 905 *ppTargetDepthSurface = NULL; 906 } 907 bool depthIsNew = false; 908 if (depthBuffer && (*ppTargetDepthSurface) == NULL) { 909 if (FAILED(res = InitDepthStencilBuffer(&descNew, ppTargetDepthSurface))) { 910 DebugPrintD3DError(res, "D3DContext::SetRenderTarget: error creating new depth buffer"); 911 return res; 912 } 913 depthIsNew = true; 914 } 915 if (pCurrentDepth != (*ppTargetDepthSurface)) { 916 res = pd3dDevice->SetDepthStencilSurface(*ppTargetDepthSurface); 917 if ((*ppTargetDepthSurface) != NULL && depthIsNew) { 918 // Depth buffer must be cleared after it is created, also 919 // if depth buffer was not attached when render target was 920 // cleared, then the depth buffer will contain garbage 921 pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_TRUE); 922 res = pd3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, NULL , 1.0f, 0x0L); 923 if (FAILED(res)) { 924 DebugPrintD3DError(res, 925 "D3DContext::SetRenderTarget: error clearing depth buffer"); 926 } 927 } 928 } else if (!renderTargetChanged) { 929 SAFE_RELEASE(pCurrentDepth); 930 return res; // Render target has not changed 931 } 932 SAFE_RELEASE(pCurrentDepth); 933 pd3dDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, msaa); 934 } 935 // NOTE PRISM: changed to only recalculate the matrix if current target is 936 // different for now 937 938 // we set the transform even if the render target didn't change; 939 // this is because in some cases (fs mode) we use the default SwapChain of 940 // the device, and its render target will be the same as the device's, and 941 // we have to set the matrix correctly. This shouldn't be a performance 942 // issue as render target changes are relatively rare 943 944 // By default D3D has integer device coordinates at the center of pixels 945 // but we want integer device coordinates to be at the edges of pixels. 946 // Additionally, its default viewport is set so that coordinates on a 947 // surface map onto (-1, +1) -> (+1, -1) as one moves from the upper left 948 // corner to the lower right corner. We need to move the values towards 949 // -X and +Y by half a pixel using the following adjustment values: 950 // half of (((+1) - (-1)) / dim), or half of (2 / dim) == (1 / dim). 951 pixadjustx = -1.0f / descNew.Width; 952 pixadjusty = +1.0f / descNew.Height; 953 TraceLn1(NWT_TRACE_VERBOSE, " current render target=0x%x", pSurface); 954 TraceLn2(NWT_TRACE_VERBOSE, " pixel adjustments=%f, %f", pixadjustx, pixadjusty); 955 return res; 956 } 957 958 HRESULT 959 D3DContext::SetCameraPosition(jdouble camPosX, jdouble camPosY, jdouble camPosZ) 960 { 961 TraceLn(NWT_TRACE_INFO, "D3DContext::SetCameraPosition"); 962 963 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 964 965 camPos.x = (float) camPosX; 966 camPos.y = (float) camPosY; 967 camPos.z = (float) camPosZ; 968 return D3D_OK; 969 } 970 971 972 HRESULT 973 D3DContext::SetProjViewMatrix(BOOL depthTest, 974 jdouble m00, jdouble m01, jdouble m02, jdouble m03, 975 jdouble m10, jdouble m11, jdouble m12, jdouble m13, 976 jdouble m20, jdouble m21, jdouble m22, jdouble m23, 977 jdouble m30, jdouble m31, jdouble m32, jdouble m33) 978 { 979 TraceLn(NWT_TRACE_INFO, "D3DContext::SetProjViewMatrix"); 980 TraceLn1(NWT_TRACE_VERBOSE, " depthTest=%d", depthTest); 981 982 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 983 984 projection._11 = (float)m00; // Scale X 985 projection._12 = (float)m10; // Shear Y 986 projection._13 = (float)m20; 987 projection._14 = (float)m30; 988 989 projection._21 = (float)m01; // Shear X 990 projection._22 = (float)m11; // Scale Y 991 projection._23 = (float)m21; 992 projection._24 = (float)m31; 993 994 projection._31 = (float)m02; 995 projection._32 = (float)m12; 996 projection._33 = (float)m22; 997 projection._34 = (float)m32; 998 999 projection._41 = (float)m03; // Translate X 1000 projection._42 = (float)m13; // Translate Y 1001 projection._43 = (float)m23; 1002 projection._44 = (float)m33; // 1.0f; 1003 1004 TraceLn4(NWT_TRACE_VERBOSE, 1005 " %5f %5f %5f %5f", projection._11, projection._12, projection._13, projection._14); 1006 TraceLn4(NWT_TRACE_VERBOSE, 1007 " %5f %5f %5f %5f", projection._21, projection._22, projection._23, projection._24); 1008 TraceLn4(NWT_TRACE_VERBOSE, 1009 " %5f %5f %5f %5f", projection._31, projection._32, projection._33, projection._34); 1010 TraceLn4(NWT_TRACE_VERBOSE, 1011 " %5f %5f %5f %5f", projection._41, projection._42, projection._43, projection._44); 1012 1013 // fprintf(stderr, "SetProjViewMatrix: depthTest = %d\n", depthTest); 1014 // fprintf(stderr, " %5f %5f %5f %5f\n", projection._11, projection._12, projection._13, projection._14); 1015 // fprintf(stderr, " %5f %5f %5f %5f\n", projection._21, projection._22, projection._23, projection._24); 1016 // fprintf(stderr, " %5f %5f %5f %5f\n", projection._31, projection._32, projection._33, projection._34); 1017 // fprintf(stderr, " %5f %5f %5f %5f\n", projection._41, projection._42, projection._43, projection._44); 1018 if (depthTest) { 1019 pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); 1020 pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_TRUE); 1021 pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); 1022 1023 pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); 1024 pd3dDevice->SetRenderState(D3DRS_ALPHAREF, 0x0); 1025 pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); 1026 } else { 1027 pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); 1028 pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE); 1029 pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE); 1030 } 1031 1032 return D3D_OK; 1033 } 1034 1035 void 1036 D3DContext::setWorldTransformIndentity() { 1037 TraceLn(NWT_TRACE_INFO, "D3DContext::setWorldTransformIndentity"); 1038 1039 RETURN_IF_NULL(pd3dDevice); 1040 1041 D3DUtils_SetIdentityMatrix(&world); 1042 } 1043 1044 void 1045 setWorldTx(D3DMATRIX &mat, jdouble m00, jdouble m01, jdouble m02, jdouble m03, 1046 jdouble m10, jdouble m11, jdouble m12, jdouble m13, 1047 jdouble m20, jdouble m21, jdouble m22, jdouble m23, 1048 jdouble m30, jdouble m31, jdouble m32, jdouble m33) { 1049 1050 mat._11 = (float)m00; // Scale X 1051 mat._12 = (float)m10; // Shear Y 1052 mat._13 = (float)m20; 1053 mat._14 = (float)m30; 1054 1055 mat._21 = (float)m01; // Shear X 1056 mat._22 = (float)m11; // Scale Y 1057 mat._23 = (float)m21; 1058 mat._24 = (float)m31; 1059 1060 mat._31 = (float)m02; 1061 mat._32 = (float)m12; 1062 mat._33 = (float)m22; 1063 mat._34 = (float)m32; 1064 1065 mat._41 = (float)m03; // Translate X 1066 mat._42 = (float)m13; // Translate Y 1067 mat._43 = (float)m23; 1068 mat._44 = (float)m33; // 1.0f; 1069 1070 TraceLn4(NWT_TRACE_VERBOSE, 1071 " %5f %5f %5f %5f", mat._11, mat._12, mat._13, mat._14); 1072 TraceLn4(NWT_TRACE_VERBOSE, 1073 " %5f %5f %5f %5f", mat._21, mat._22, mat._23, mat._24); 1074 TraceLn4(NWT_TRACE_VERBOSE, 1075 " %5f %5f %5f %5f", mat._31, mat._32, mat._33, mat._34); 1076 TraceLn4(NWT_TRACE_VERBOSE, 1077 " %5f %5f %5f %5f", mat._41, mat._42, mat._43, mat._44); 1078 1079 // fprintf(stderr, "World Matrix:\n"); 1080 // fprintf(stderr, " %5f %5f %5f %5f\n", mat._11, mat._12, mat._13, mat._14); 1081 // fprintf(stderr, " %5f %5f %5f %5f\n", mat._21, mat._22, mat._23, mat._24); 1082 // fprintf(stderr, " %5f %5f %5f %5f\n", mat._31, mat._32, mat._33, mat._34); 1083 // fprintf(stderr, " %5f %5f %5f %5f\n", mat._41, mat._42, mat._43, mat._44); 1084 } 1085 1086 void 1087 D3DContext::setWorldTransform(jdouble m00, jdouble m01, jdouble m02, jdouble m03, 1088 jdouble m10, jdouble m11, jdouble m12, jdouble m13, 1089 jdouble m20, jdouble m21, jdouble m22, jdouble m23, 1090 jdouble m30, jdouble m31, jdouble m32, jdouble m33) { 1091 1092 // std::cerr << "D3DContext::setWorldTransform" << std::endl; 1093 TraceLn(NWT_TRACE_INFO, "D3DContext::setWorldTransform"); 1094 1095 RETURN_IF_NULL(pd3dDevice); 1096 1097 setWorldTx(world, 1098 m00, m01, m02, m03, 1099 m10, m11, m12, m13, 1100 m20, m21, m22, m23, 1101 m30, m31, m32, m33); 1102 } 1103 1104 HRESULT 1105 D3DContext::ResetTransform() 1106 { 1107 TraceLn(NWT_TRACE_INFO, "D3DContext::ResetTransform"); 1108 1109 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 1110 1111 D3DUtils_SetIdentityMatrix(&world); 1112 return UpdateVertexShaderTX(); 1113 } 1114 1115 HRESULT 1116 D3DContext::SetTransform(jdouble m00, jdouble m01, jdouble m02, jdouble m03, 1117 jdouble m10, jdouble m11, jdouble m12, jdouble m13, 1118 jdouble m20, jdouble m21, jdouble m22, jdouble m23, 1119 jdouble m30, jdouble m31, jdouble m32, jdouble m33) 1120 1121 { 1122 1123 // std::cerr << "D3DContext::SetTransform" << std::endl; 1124 TraceLn(NWT_TRACE_INFO, "D3DContext::SetTransform"); 1125 1126 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 1127 1128 setWorldTx(world, 1129 m00, m01, m02, m03, 1130 m10, m11, m12, m13, 1131 m20, m21, m22, m23, 1132 m30, m31, m32, m33); 1133 1134 return UpdateVertexShaderTX(); 1135 } 1136 1137 HRESULT 1138 D3DContext::SetRectClip(int x1, int y1, int x2, int y2) 1139 { 1140 TraceLn(NWT_TRACE_INFO, "D3DContext::SetRectClip"); 1141 TraceLn4(NWT_TRACE_VERBOSE, 1142 " x1=%-4d y1=%-4d x2=%-4d y2=%-4d", 1143 x1, y1, x2, y2); 1144 1145 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 1146 1147 IDirect3DSurface9 *pCurrentTarget; 1148 HRESULT res = pd3dDevice->GetRenderTarget(0, &pCurrentTarget); 1149 RETURN_STATUS_IF_FAILED(res); 1150 1151 D3DSURFACE_DESC desc; 1152 pCurrentTarget->GetDesc(&desc); 1153 SAFE_RELEASE(pCurrentTarget); 1154 1155 if (x1 <= 0 && y1 <= 0 && 1156 (UINT)x2 >= desc.Width && (UINT)y2 >= desc.Height) 1157 { 1158 TraceLn(NWT_TRACE_VERBOSE, 1159 " disabling clip (== render target dimensions)"); 1160 return pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); 1161 } 1162 1163 // clip to the dimensions of the target surface, otherwise 1164 // SetScissorRect will fail 1165 if (x1 < 0) x1 = 0; 1166 if (y1 < 0) y1 = 0; 1167 if ((UINT)x2 > desc.Width) x2 = desc.Width; 1168 if ((UINT)y2 > desc.Height) y2 = desc.Height; 1169 if (x1 > x2) x2 = x1 = 0; 1170 if (y1 > y2) y2 = y1 = 0; 1171 RECT newRect = { x1, y1, x2, y2 }; 1172 if (SUCCEEDED(res = pd3dDevice->SetScissorRect(&newRect))) { 1173 res = pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); 1174 } else { 1175 DebugPrintD3DError(res, "Error setting scissor rect"); 1176 RlsTraceLn4(NWT_TRACE_ERROR, 1177 " x1=%-4d y1=%-4d x2=%-4d y2=%-4d", 1178 x1, y1, x2, y2); 1179 } 1180 1181 return res; 1182 } 1183 1184 HRESULT 1185 D3DContext::ResetClip() 1186 { 1187 TraceLn(NWT_TRACE_INFO, "D3DContext::ResetClip"); 1188 1189 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 1190 1191 return pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); 1192 } 1193 1194 HRESULT D3DContext::BeginScene() 1195 { 1196 RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL); 1197 1198 if (!bBeginScenePending) { 1199 bBeginScenePending = TRUE; 1200 HRESULT res = pd3dDevice->BeginScene(); 1201 TraceLn(NWT_TRACE_INFO, "D3DContext::BeginScene"); 1202 return res; 1203 } 1204 return S_OK; 1205 } 1206 1207 HRESULT D3DContext::EndScene() 1208 { 1209 if (bBeginScenePending) { 1210 bBeginScenePending = FALSE; 1211 TraceLn(NWT_TRACE_INFO, "D3DContext::EndScene"); 1212 return pd3dDevice->EndScene(); 1213 } 1214 return S_OK; 1215 } 1216 1217 HRESULT D3DContext::InitContextCaps() { 1218 if (!IsPow2TexturesOnly()) { 1219 RlsTraceLn(NWT_TRACE_VERBOSE, " CAPS_TEXNONPOW2"); 1220 } 1221 if (!IsSquareTexturesOnly()) { 1222 RlsTraceLn(NWT_TRACE_VERBOSE, " CAPS_TEXNONSQUARE"); 1223 } 1224 return S_OK; 1225 }