• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

kurlyak

Members
  • Content count

    50
  • Joined

  • Last visited

Community Reputation

122 Neutral

About kurlyak

  • Rank
    Member

Personal Information

  • Location
    Ukraine
  1. Hi guys! Very thanks for you attention.   For example I have front poly of cube 1st tri:   2-3 | / 1   and second tri:    2  /  | 1-3   Then run program, and move cube left behind left edge of screen. My code write log file:   num_tri=1 : tri=0 : y1=-9.166122 : y2=9.166122 : y3=1.458612 num_tri=2 : tri=1 : y1=-9.166122 : y2=1.458612 : y3=-1.458612 num_tri=1 : tri=0 : y1=-9.166122 : y2=9.166122 : y3=1.458612 num_tri=2 : tri=1 : y1=-9.166122 : y2=1.458612 : y3=-1.458612 num_tri=1 : tri=0 : y1=-13.575529 : y2=13.575529 : y3=1.483807 num_tri=2 : tri=1 : y1=-13.575529 : y2=1.483807 : y3=-1.483807 num_tri=1 : tri=0 : y1=-26.473291 : y2=26.473291 : y3=1.513117 num_tri=2 : tri=1 : y1=-26.473291 : y2=1.513117 : y3=-1.513117 num_tri=1 : tri=0 : y1=-670.692383 : y2=670.692383 : y3=1.546930 num_tri=2 : tri=1 : y1=-670.692383 : y2=1.546930 : y3=-1.546930 num_tri=1 : tri=0 : y1=-670.692383 : y2=670.692383 : y3=1.546930 num_tri=2 : tri=1 : y1=-670.692383 : y2=1.546930 : y3=-1.546930 num_tri=1 : tri=0 : y1=-670.692383 : y2=670.692383 : y3=1.546930 num_tri=2 : tri=1 : y1=-670.692383 : y2=1.546930 : y3=-1.546930 num_tri=1 : tri=0 : y1=28.466400 : y2=-28.466400 : y3=1.585725 num_tri=2 : tri=1 : y1=28.466400 : y2=1.585725 : y3=-1.585725 num_tri=1 : tri=0 : y1=13.883531 : y2=-13.883531 : y3=1.630078   where num_tri = is count of triangle to draw presently, tri = number of triangle (front face cube tri 0 and 1) and y1, y2, y3 - is Y coord of vert 1,2,3. This records log file before fault. As you can see y1 coord was y1=-670.692383 (vert1 - y1 is located below screen and left) and next record abrupt y1 = y1=28.466400 (that means vert1- y1 is located in range screen).   I think my clipping OK because in rendering process draw only triangle 0 and 1 (front face of cuble) and this show log file. But code:   for(int i = 0; i < 12; i++) { My3DVector3 v1 = My3DVector3(pMy3DTriangle_Original[i].v1.x, pMy3DTriangle_Original[i].v1.y, pMy3DTriangle_Original[i].v1.z); My3DVector3 v2 = My3DVector3(pMy3DTriangle_Original[i].v2.x, pMy3DTriangle_Original[i].v2.y, pMy3DTriangle_Original[i].v2.z); My3DVector3 v3 = My3DVector3(pMy3DTriangle_Original[i].v3.x, pMy3DTriangle_Original[i].v3.y, pMy3DTriangle_Original[i].v3.z); My3DVector3 m_BoundsMin, m_BoundsMax; m_BoundsMin = My3DVector3( 999999.0f, 999999.0f, 999999.0f ); m_BoundsMax = My3DVector3( -999999.0f, -999999.0f, -999999.0f ); if ( v1.x < m_BoundsMin.x ) m_BoundsMin.x = v1.x; if ( v1.y < m_BoundsMin.y ) m_BoundsMin.y = v1.y; if ( v1.z < m_BoundsMin.z ) m_BoundsMin.z = v1.z; if ( v1.x > m_BoundsMax.x ) m_BoundsMax.x = v1.x; if ( v1.y > m_BoundsMax.y ) m_BoundsMax.y = v1.y; if ( v1.z > m_BoundsMax.z ) m_BoundsMax.z = v1.z; if ( v2.x < m_BoundsMin.x ) m_BoundsMin.x = v2.x; if ( v2.y < m_BoundsMin.y ) m_BoundsMin.y = v2.y; if ( v2.z < m_BoundsMin.z ) m_BoundsMin.z = v2.z; if ( v2.x > m_BoundsMax.x ) m_BoundsMax.x = v2.x; if ( v2.y > m_BoundsMax.y ) m_BoundsMax.y = v2.y; if ( v2.z > m_BoundsMax.z ) m_BoundsMax.z = v2.z; if ( v3.x < m_BoundsMin.x ) m_BoundsMin.x = v3.x; if ( v3.y < m_BoundsMin.y ) m_BoundsMin.y = v3.y; if ( v3.z < m_BoundsMin.z ) m_BoundsMin.z = v3.z; if ( v3.x > m_BoundsMax.x ) m_BoundsMax.x = v3.x; if ( v3.y > m_BoundsMax.y ) m_BoundsMax.y = v3.y; if ( v3.z > m_BoundsMax.z ) m_BoundsMax.z = v3.z; if (!BoundsInFrustum(m_BoundsMin, m_BoundsMax, mRes)) pMy3DTriangle_Transformed[i].TriState_Clipped = CLIPPED; else pMy3DTriangle_Transformed[i].TriState_Clipped = NOTCLIPPED; } And render proc:   DDraw_Lock_Back_Surface(); myTRI = 0; myNumTri = 0; for ( int i = 0; i < 12; i++) { if(pMy3DTriangle_Transformed[i].TriState_Cull == CULL) continue; if(pMy3DTriangle_Transformed[i].TriState_Clipped == CLIPPED) continue; myTRI = i; myNumTri++; FILE *f; f = fopen("log.txt", "at"); char szBuff[256]; sprintf_s(szBuff,256, "num_tri=%d : tri=%d : y1=%f : y2=%f : y3=%f\n", myNumTri, myTRI, pMy3DTriangle_Transformed[i].v1.y, pMy3DTriangle_Transformed[i].v2.y, pMy3DTriangle_Transformed[i].v3.y); fwrite((void*)szBuff, strlen(szBuff), 1, f); fclose(f); Draw_Textured_Triangle(pMy3DTriangle_Transformed[i], back_buffer, back_lpitch); } DDraw_Unlock_Back_Surface(); DDraw_Flip(); void CMy3DApp::Draw_Textured_Triangle(My3DTriangle tri, UCHAR *dest_buffer, // pointer to video buffer int mem_pitch) // bytes per line, 320, 640 etc. { int side; float x1, x2, x3; float y1, y2, y3; float iz1, uiz1, viz1, iz2, uiz2, viz2, iz3, uiz3, viz3; float tempf; int y1i, y2i, y3i; float dxdy1, dxdy2, dxdy3; float dy; float dyl, dyr; x1 = tri.vScreen1.x + 0.5f; y1 = tri.vScreen1.y + 0.5f; x2 = tri.vScreen2.x + 0.5f; y2 = tri.vScreen2.y + 0.5f; x3 = tri.vScreen3.x + 0.5f; y3 = tri.vScreen3.y + 0.5f; iz1 = 1.0f / tri.v1.z; iz2 = 1.0f / tri.v2.z; iz3 = 1.0f / tri.v3.z; uiz1 = tri.v1.tu * iz1; viz1 = tri.v1.tv * iz1; uiz2 = tri.v2.tu * iz2; viz2 = tri.v2.tv * iz2; uiz3 = tri.v3.tu * iz3; viz3 = tri.v3.tv * iz3; #define swapfloat(x, y) tempf = x; x = y; y = tempf; if (y1 > y2) { swapfloat(x1, x2); swapfloat(y1, y2); swapfloat(iz1, iz2); swapfloat(uiz1, uiz2); swapfloat(viz1, viz2); } if (y1 > y3) { swapfloat(x1, x3); swapfloat(y1, y3); swapfloat(iz1, iz3); swapfloat(uiz1, uiz3); swapfloat(viz1, viz3); } if (y2 > y3) { swapfloat(x2, x3); swapfloat(y2, y3); swapfloat(iz2, iz3); swapfloat(uiz2, uiz3); swapfloat(viz2, viz3); } #undef swapfloat //variables for log file myY1 = y1; myY2 = y2; myY3 = y3; y1i = (int) y1; y2i = (int) y2; y3i = (int) y3; if ((y1i == y2i && y1i == y3i) || ((int) x1 == (int) x2 && (int) x1 == (int) x3)) return; dxdy1 = 0.0; dxdy2 = 0.0; dxdy3 = 0.0; if (y2 > y1) dxdy1 = (x2 - x1) / (y2 - y1); if (y3 > y1) dxdy2 = (x3 - x1) / (y3 - y1); if (y3 > y2) dxdy3 = (x3 - x2) / (y3 - y2); // Determine which side of the poly the longer edge is on side = dxdy2 > dxdy1; if (y1 == y2) side = x1 > x2; if (y2 == y3) side = x3 > x2; int nMinClipY = nViewY; int nMaxClipY = nViewHeight; int nMinClipX = nViewX; int nMaxClipX = nViewWidth; if(y1i> nMaxClipY) y1i = 599; if(y2i> nMaxClipY) y2i = 599; if(y3i> nMaxClipY) y3i = 599; if(y1i< nMinClipY) y1i = 0; if(y2i< nMinClipY) y2i = 0; if(y3i< nMinClipY) y3i = 0; if (!side) // Longer edge is on the left side { dyl = y3 - y1; dxdyl = (x3 - x1) / dyl; dudyl = (uiz3 - uiz1) / dyl; dvdyl = (viz3 - viz1) / dyl; dzdyl = (iz3 - iz1) / dyl; dy = 1 - (y1 - y1i); xl = x1 + dy * dxdyl; ul = uiz1 + dy * dudyl; vl = viz1 + dy * dvdyl; zl = iz1 + dy * dzdyl; if(y1 < nMinClipY) { dy = nMinClipY - y1; xl = x1 + dy * dxdyl; ul = uiz1 + dy * dudyl; vl = viz1 + dy * dvdyl; zl = iz1 + dy * dzdyl; } if (y1 < y2) // Draw upper segment if possibly visible { dyr = y2 - y1; dxdyr = (x2 - x1) / dyr; dudyr = (uiz2 - uiz1) / dyr; dvdyr = (viz2 - viz1) / dyr; dzdyr = (iz2 - iz1) / dyr; xr = x1 + dy * dxdyr; ur = uiz1 + dy * dudyr; vr = viz1 + dy * dvdyr; zr = iz1 + dy * dzdyr; if(y1 < nMinClipY) { dy = nMinClipY - y1; xr = x1 + dy * dxdyr; ur = uiz1 + dy * dudyr; vr = viz1 + dy * dvdyr; zr = iz1 + dy * dzdyr; } Draw_Textured_Poly(y1i, y2i, back_buffer, back_lpitch); } if (y2 < y3) // Draw lower segment if possibly visible { dyr = y3 - y2; dxdyr = (x3 - x2) / dyr; dudyr = (uiz3 - uiz2) / dyr; dvdyr = (viz3 - viz2) / dyr; dzdyr = (iz3 - iz2) / dyr; xr = x2 + (1 - (y2 - y2i)) * dxdyr; ur = uiz2 + (1 - (y2 - y2i)) * dudyr; vr = viz2 + (1 - (y2 - y2i)) * dvdyr; zr = iz2 + (1 - (y2 - y2i)) * dzdyr; if(y2 < nMinClipY) { dy = nMinClipY - y2; xr = x2 + dy * dxdyr; ur = uiz2 + dy * dudyr; vr = viz2 + dy * dvdyr; zr = iz2 + dy * dzdyr; } Draw_Textured_Poly(y2i, y3i, back_buffer, back_lpitch); } } else // Longer edge is on the right side { dyr = y3 - y1; dxdyr = (x3 - x1) / dyr; dudyr = (uiz3 - uiz1) / dyr; dvdyr = (viz3 - viz1) / dyr; dzdyr = (iz3 - iz1) / dyr; dy = 1 - (y1 - y1i); xr = x1 + dy * dxdyr; ur = uiz1 + dy * dudyr; vr = viz1 + dy * dvdyr; zr = iz1 + dy * dzdyr; if(y1 < nMinClipY) { dy = nMinClipY - y1; xr = x1 + dy * dxdyr; ur = uiz1 + dy * dudyr; vr = viz1 + dy * dvdyr; zr = iz1 + dy * dzdyr; } if (y1 < y2) // Draw upper segment if possibly visible { dyl = y2 - y1; dxdyl = (x2 - x1) / dyl; dudyl = (uiz2 - uiz1) / dyl; dvdyl = (viz2 - viz1) / dyl; dzdyl = (iz2 - iz1) / dyl; xl = x1 + dy * dxdyl; ul = uiz1 + dy * dudyl; vl = viz1 + dy * dvdyl; zl = iz1 + dy * dzdyl; if(y1 < nMinClipY) { dy = nMinClipY - y1; xl = x1 + dy * dxdyl; ul = uiz1 + dy * dudyl; vl = viz1 + dy * dvdyl; zl = iz1 + dy * dzdyl; } Draw_Textured_Poly(y1i, y2i, back_buffer, back_lpitch); } if (y2 < y3) // Draw lower segment if possibly visible { dyl = y3 - y2; dxdyl = (x3 - x2) / dyl; dudyl = (uiz3 - uiz2) / dyl; dvdyl = (viz3 - viz2) / dyl; dzdyl = (iz3 - iz2) / dyl; dy = 1 - (y2 - y2i); xl = x2 + dy * dxdyl; ul = uiz2 + dy * dudyl; vl = viz2 + dy * dvdyl; zl = iz2 + dy * dzdyl; if(y2 < nMinClipY) { dy = nMinClipY - y2; xl = x2 + dy * dxdyl; ul = uiz2 + dy * dudyl; vl = viz2 + dy * dvdyl; zl = iz2 + dy * dzdyl; } Draw_Textured_Poly(y2i, y3i, back_buffer, back_lpitch); } } } // end Draw_Textured_Triangle void CMy3DApp::Draw_Textured_Poly(int y1, int y2, UCHAR *dest_buffer, int mem_pitch) { int x1, x2; int dx; float ui, vi, zi; float du, dv, dz; int nMinClipX = nViewX; int nMaxClipX = nViewWidth; UCHAR *screen_ptr = NULL; screen_ptr = dest_buffer + (y1 * mem_pitch); for (int yi = y1; yi<y2; yi++) { x1 = (int) xl; x2 = (int) xr; ui = ul; vi = vl; zi = zl; if ((dx = (x2 - x1))>0) { du = (ur - ul)/dx; dv = (vr - vl)/dx; dz = (zr - zl)/dx; } else { du = (ur - ul); dv = (vr - vl); dz = (zr - zl); } if(x1 < nMinClipX) { dx = nMinClipX-x1; ui+=dx * du; vi+=dx * dv; zi+=dx * dz; x1 = nMinClipX; } if(x1 == 0 && x2 == 0) return; if(x2> nMaxClipX) x2 = 799; int indx = x1 * 4; for (int xi=x1; xi<x2; xi++) { float z = 1.0/zi; float u = ui * z; float v = vi * z; int t = (int)u + (((int)v) << 6); t= t*3; screen_ptr[indx] = pRes[t]; indx++; screen_ptr[indx] = pRes[t+1]; indx++; screen_ptr[indx] = pRes[t+2]; indx++; screen_ptr[indx] = 0; indx++; ui+=du; vi+=dv; zi+=dz; } xl+=dxdyl; ul+=dudyl; vl+=dvdyl; zl+=dzdyl; xr+=dxdyr; ur+=dudyr; vr+=dvdyr; zr+=dzdyr; screen_ptr+=mem_pitch; } }   Run time error occurs in code:   int t = (int)u + (((int)v) << 6); t= t*3; screen_ptr[indx] = pRes[t]; // HERE ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!!!! indx++; screen_ptr[indx] = pRes[t+1]; indx++; screen_ptr[indx] = pRes[t+2]; indx++; screen_ptr[indx] = 0; indx++;   And another screenshot. When I move whole cube behind left edge of screen appears this screenshot and next runtime error:     And in normal state without error (no moving, no rotation) cube render fine:    
  2. I try apply software rendering to draw simple cube. I have matrix World, View, Projection:   My3DMatrix4x4 mWorld( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); My3DMatrix4x4 mView = m_pCamera->GetViewMatrix(); float fFov = 3.1415926f/4.0f; float fAspect = 4.0f/3.0f; float fZFar = 500.0; float fZNear = 5.0f; float h, w, Q; w = (1.0f/tan(fFov*0.5f))/fAspect; h = 1.0f/tan(fFov*0.5f); Q = fZFar/(fZFar - fZNear); My3DMatrix4x4 mProj( w, 0, 0, 0, 0, h, 0, 0, 0, 0, Q, 1, 0, 0, -Q*fZNear, 0);     Then I muptiply all this matrix and multiply all vert of my cube on this result matrix. For multiplication matrix I use DirectX func, and for vertices I use DirectX func D3DXTransformNormal(). Also my camera class use DirectX func for calculation and under original DirectX program my camera class works fine. In normal state my program rendering 3D cube. Problem appears when I move camera closer to cube and try rotate camera left, right, up, down - error occur when angle > 45 degree. When I have distant from cube and rotate camera - all fine. But when I move camera closer to cube and try rotate it more then 45 degree - program fault. Sorry my English.     This is screenshot #1 when I rotate cube left:   This is scrennshot #2 when cube had rotatet more that 45 degree:   Also I am use back face culling and frustum clipping (its works fine in my native DirectX program).   My camera class works fine in native DirectX program:   void CFirstPersonCamera::FrameMove(float fTime, int delta) { POINT mousePos; GetCursorPos(&mousePos); SetCursorPos(nScreenWidth/2, nScreenHeight/2); int nDeltaX=nScreenWidth/2-mousePos.x; int nDeltaY=nScreenHeight/2-mousePos.y; float m_fRotationScalerX = 0.04f; float m_fRotationScalerY = 0.04f; /* if(nDeltaY<0) m_fRotationScalerY = m_fRotationScalerY; else if(nDeltaY>0) m_fRotationScalerY = -m_fRotationScalerY; else if(nDeltaY==0) m_fRotationScalerY = 0; My3DMatrix4x4 matRotRight = My3DMatrixRotationAxis(vRight , m_fRotationScalerY); //My3DMatrix4x4 matRotY = My3DMatrixRotationX(m_fRotationScalerY); vRight = My3DVec3TransformNormal(vRight, matRotRight); vUp = My3DVec3TransformNormal(vUp, matRotRight); vLook = My3DVec3TransformNormal(vLook, matRotRight); */ if(nDeltaX<0) m_fRotationScalerX = m_fRotationScalerX; else if(nDeltaX>0) m_fRotationScalerX = -m_fRotationScalerX; else if(nDeltaX==0) m_fRotationScalerX = 0; /* //My3DVector3 vUpTemp = My3DVector3( 0.0f, 1.0f, 0.0f ); //My3DMatrix4x4 matRotUp = My3DMatrixRotationAxis(vUpTemp , m_fRotationScalerX); My3DMatrix4x4 matRotUp = My3DMatrixRotationY(m_fRotationScalerX); vRight = My3DVec3TransformNormal(vRight, matRotUp); vUp = My3DVec3TransformNormal(vUp, matRotUp); vLook = My3DVec3TransformNormal(vLook, matRotUp); */ D3DXMATRIX matRotUp; D3DXMatrixRotationY(&matRotUp, m_fRotationScalerX); D3DXVECTOR3 vR, vU, vL; vR = D3DXVECTOR3(vRight.x, vRight.y, vRight.z); vU = D3DXVECTOR3(vUp.x, vUp.y, vUp.z); vL = D3DXVECTOR3(vLook.x, vLook.y, vLook.z); D3DXVECTOR3 vOutR, vOutU, vOutL; D3DXVec3TransformNormal(&vOutR, &vR, &matRotUp); D3DXVec3TransformNormal(&vOutU, &vU, &matRotUp); D3DXVec3TransformNormal(&vOutL, &vL, &matRotUp); vRight = My3DVector3(vOutR.x, vOutR.y, vOutR.z); vUp = My3DVector3(vOutU.x, vOutU.y, vOutU.z); vLook = My3DVector3(vOutL.x, vOutL.y, vOutL.z); float ratioMove = 150; My3DVector3 temp = My3DVector3(0,0,0);; My3DVector3 vAccel = My3DVector3(0,0,0); if(GetAsyncKeyState('W')& 0xFF00) { temp = My3DVector3(vLook.x,0,vLook.z); temp = My3DVec3Dot(temp, ratioMove); vAccel = My3DVec3Dot(temp, fTime); vAccel.y = 0.0; } if(GetAsyncKeyState('S')& 0xFF00) { temp = My3DVector3(vLook.x,0,vLook.z); temp = My3DVec3Dot(temp, -ratioMove); vAccel = My3DVec3Dot(temp, fTime); } if(GetAsyncKeyState('D')& 0xFF00) { temp = My3DVector3(vRight.x,0,vRight.z); temp = My3DVec3Dot(temp, ratioMove); vAccel = My3DVec3Dot(temp, fTime); } if(GetAsyncKeyState('A')& 0xFF00) { temp = My3DVector3(vRight.x,0,vRight.z); temp = My3DVec3Dot(temp, -ratioMove); vAccel = My3DVec3Dot(temp, fTime); } vAccel.y = 0.0; vPos = My3DVec3Add(vPos,vAccel); vRight = My3DVec3Normalize(vRight); vLook = My3DVec3Normalize(vLook); vUp = My3DVec3Cross(vLook,vRight); vUp = My3DVec3Normalize(vUp); vRight = My3DVec3Cross(vUp,vLook); vRight = My3DVec3Normalize(vRight); matView.r1c1 = vRight.x; matView.r2c1 = vRight.y; matView.r3c1 = vRight.z; matView.r1c2 = vUp.x; matView.r2c2 = vUp.y; matView.r3c2 = vUp.z; matView.r1c3 = vLook.x; matView.r2c3 = vLook.y; matView.r3c3 = vLook.z; matView.r1c4 = 0.0; matView.r2c4 = 0.0; matView.r3c4 = 0.0; matView.r4c1 =- My3DVec3Dot( vPos, vRight ); matView.r4c2 =- My3DVec3Dot( vPos, vUp ); matView.r4c3 =- My3DVec3Dot( vPos, vLook ); matView.r4c4 = 1.0; }   My3DMatrix4x4 mRes( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); mRes = My3DMatrixMultiply(mRes, mView); mRes = My3DMatrixMultiply(mRes, mProj); for( int i = 0; i < 12; i++) { pMy3DTriangle_Transformed[i].v1.tu = pMy3DTriangle_Original[i].v1.tu; pMy3DTriangle_Transformed[i].v1.tv = pMy3DTriangle_Original[i].v1.tv; pMy3DTriangle_Transformed[i].v2.tu = pMy3DTriangle_Original[i].v2.tu; pMy3DTriangle_Transformed[i].v2.tv = pMy3DTriangle_Original[i].v2.tv; pMy3DTriangle_Transformed[i].v3.tu = pMy3DTriangle_Original[i].v3.tu; pMy3DTriangle_Transformed[i].v3.tv = pMy3DTriangle_Original[i].v3.tv; D3DXMATRIX mResDX = D3DXMATRIX(mRes.r1c1, mRes.r1c2,mRes.r1c3,mRes.r1c4, mRes.r2c1, mRes.r2c2,mRes.r2c3,mRes.r2c4, mRes.r3c1, mRes.r3c2,mRes.r3c3,mRes.r3c4, mRes.r4c1, mRes.r4c2,mRes.r4c3,mRes.r4c4); D3DXVECTOR3 vt1 = D3DXVECTOR3(pMy3DTriangle_Original[i].v1.x, pMy3DTriangle_Original[i].v1.y, pMy3DTriangle_Original[i].v1.z); D3DXVECTOR3 vt1_Out; D3DXVec3TransformNormal(&vt1_Out, &vt1, &mResDX); D3DXVECTOR3 vt2 = D3DXVECTOR3(pMy3DTriangle_Original[i].v2.x, pMy3DTriangle_Original[i].v2.y, pMy3DTriangle_Original[i].v2.z); D3DXVECTOR3 vt2_Out; D3DXVec3TransformNormal(&vt2_Out, &vt2, &mResDX); D3DXVECTOR3 vt3 = D3DXVECTOR3(pMy3DTriangle_Original[i].v3.x, pMy3DTriangle_Original[i].v3.y, pMy3DTriangle_Original[i].v3.z); D3DXVECTOR3 vt3_Out; D3DXVec3TransformNormal(&vt3_Out, &vt3, &mResDX); pMy3DTriangle_Transformed[i].v1.x = vt1_Out.x / vt1_Out.z; pMy3DTriangle_Transformed[i].v1.y = vt1_Out.y / vt1_Out.z; pMy3DTriangle_Transformed[i].v1.z = vt1_Out.z; pMy3DTriangle_Transformed[i].v2.x = vt2_Out.x / vt2_Out.z; pMy3DTriangle_Transformed[i].v2.y = vt2_Out.y / vt2_Out.z; pMy3DTriangle_Transformed[i].v2.z = vt2_Out.z; pMy3DTriangle_Transformed[i].v3.x = vt3_Out.x / vt3_Out.z; pMy3DTriangle_Transformed[i].v3.y = vt3_Out.y / vt3_Out.z; pMy3DTriangle_Transformed[i].v3.z = vt3_Out.z; }   Please assist me. Thanks in advance.    
  3. When I set hook, and run exe file of game, my hook procedure LoadLibrary() load: C:\WINDOWS\system32\ole32.dll user32.dll dsound.dll WINTRUST.dll advapi32.dll kernel32.dll advapi32.dll WINTRUST.dll WINTRUST.dll WINTRUST.dll WINTRUST.dll CLBCATQ.DLL CLBCATQ.DLL WINTRUST.dll xinput9_1_0.dll xinput9_1_0.dll user32.dll C:\WINDOWS\system32\ole32.dll UxTheme.dll IMM32.dll Hook proc LoadLibrary() wrote log.txt. And in log.txt not present any d3d9_xxxx.dll. Why?
  4. Hi guys! I have some peculiar questions. So... Under Win7. I wrote program that hooking LoadLibrary() from EXE file of game. It works fine- hook LoadLibrary(), then catch loading "d3d9.dll", then call my function LoadLibrary(), then call my Direct3DCreate9() and the end I get access to screen of game. Under WinXP. My hook dont work. LoadLibrary() catch some DLL from EXE file of game, but no one of them I can not seen in disassemble code of game and my hook procedure LoadLibrary() dont catch "d3d.dll" load, In one word d3d9.dll do not load at all, and hook do not works at all. My question. How creates Device of DirectX9 in EXE file of game in case WinXP? Game name Tomb Raider Anniversary. Thanks.
  5. I know DirectDraw, DirectDraw2, DirectDraw4, DirectDraw7. And my question is - what version DirectDraw we get use DirectDrawCreate()?
  6. All is fine. One function was predetermined wrong (wrong parameters). Thank you.
  7. Thank you for your interest. I trying to write FPS counter for DirectDraw game. I want set hook on DirectDrawCreate() and IDirectDraw, IDirectDrawSurface. Furthermore I run my Launcher.exe, and run my DLL hook procedure, then run my DirectDraw game. And the end - my hook procedure from DLL will itercept Flip() and show FPS in game window.
  8. The program inherit IDirectDrawSurface (Hook write.) Override all interface classes IDirectDrawSurface. But when compile all the same error: error C2259: 'MyDirectDrawSurface': cannot instantiate abstract class What should I do?
  9. I am trying to hook Direct3DCreate9 function. I wrote some code (short variant). [CODE] SDLLHook D3DHook = { "D3D9.DLL", false, NULL, { { "Direct3DCreate9", MyDirect3DCreate9}, { NULL, NULL } } }; // Hook function. IDirect3D9* WINAPI MyDirect3DCreate9(UINT sdk_version) { // Let the world know we're working. MessageBeep(MB_ICONINFORMATION); MessageBox(NULL, "MyDirect3DCreate9", "Info", MB_OK); OutputDebugString( "Direct3D-Hook: MyDirect3DCreate9 called.\n" ); Direct3DCreate9_t old_func = (Direct3DCreate9_t) D3DHook.Functions[D3DFN_Direct3DCreate9].OrigFn; IDirect3D9* d3d = old_func(sdk_version); return d3d? new MyDirect3D9(d3d) : 0; } ..................................... bool res = HookAPICalls(&D3DHook); [/CODE] I trying to use Launcher and DLL. In some programs my hook works fine, and in other programs it fail. In others program even not entry in func MyDirect3DCreate9() (see above). What is the matter? Thanks in advance.
  10. I am interested how to texture 3D cube in DirectDraw? It is possible to use the DirectDraw functions for texturing the 3D cube?
  11. I am trying load game level from level file. Suppose I have a array of verts, array of rectangles, array of triangles. This is whole mesh. At first I am copy verts: [code] struct FACE_MATMAP { UINT face; UINT mat; UINT OrigMat; }; [/code] [code] pTR2RoomMesh = new MY_TR2_ROOM[Level->NumRooms]; ZeroMemory(pTR2RoomMesh, sizeof(MY_TR2_ROOM) * Level->NumRooms); for (int i = 0; i < Level->NumRooms; i++) { pTR2RoomMesh[i].nNumVerts = Level->Rooms[i].RoomData.NumVertices; pTR2RoomMesh[i].pVertsArray = new MY_VERTEX[Level->Rooms[i].RoomData.NumVertices]; ZeroMemory(pTR2RoomMesh[i].pVertsArray, sizeof(MY_VERTEX)*Level->Rooms[i].RoomData.NumVertices); for(int j = 0; j < Level->Rooms[i].RoomData.NumVertices; j++) { pTR2RoomMesh[i].pVertsArray[j].p.x = Level->Rooms[i].RoomData.Vertices[j].Vertex.x; pTR2RoomMesh[i].pVertsArray[j].p.y = -Level->Rooms[i].RoomData.Vertices[j].Vertex.y; pTR2RoomMesh[i].pVertsArray[j].p.z = Level->Rooms[i].RoomData.Vertices[j].Vertex.z; } } [/code] Furthemore I am copy rectangles: [code] DWORD dwNumIndices = Level->Rooms[i].RoomData.NumRectangles * 2 * 3 + Level->Rooms[i].RoomData.NumTriangles *3; pTR2RoomMesh[i].pIndicesArray = new WORD[dwNumIndices]; DWORD dwCurrIndices = 0; UINT nNumMatInMapMat = Level->Rooms[i].RoomData.NumRectangles * 2 + Level->Rooms[i].RoomData.NumTriangles; pTR2RoomMesh[i].pFaceMatArray = new FACE_MATMAP[nNumMatInMapMat]; ZeroMemory(pTR2RoomMesh[i].pFaceMatArray, sizeof(FACE_MATMAP) * nNumMatInMapMat); UINT nCurrMat = 0; set <UINT> texture; for( int j = 0; j < Level->Rooms[i].RoomData.NumRectangles; j++) { //first triagnle pTR2RoomMesh[i].pIndicesArray[dwCurrIndices] = Level->Rooms[i].RoomData.Rectangles[j].Vertices[0]; dwCurrIndices++; pTR2RoomMesh[i].pIndicesArray[dwCurrIndices] = Level->Rooms[i].RoomData.Rectangles[j].Vertices[1]; dwCurrIndices++; pTR2RoomMesh[i].pIndicesArray[dwCurrIndices] = Level->Rooms[i].RoomData.Rectangles[j].Vertices[2]; dwCurrIndices++; pTR2RoomMesh[i].pFaceMatArray[nCurrMat].face = nCurrMat; pTR2RoomMesh[i].pFaceMatArray[nCurrMat].mat = Level->Rooms[i].RoomData.Rectangles[j].Texture; nCurrMat++; //second tirangle pTR2RoomMesh[i].pIndicesArray[dwCurrIndices] = Level->Rooms[i].RoomData.Rectangles[j].Vertices[0]; dwCurrIndices++; pTR2RoomMesh[i].pIndicesArray[dwCurrIndices] = Level->Rooms[i].RoomData.Rectangles[j].Vertices[2]; dwCurrIndices++; pTR2RoomMesh[i].pIndicesArray[dwCurrIndices] = Level->Rooms[i].RoomData.Rectangles[j].Vertices[3]; dwCurrIndices++; pTR2RoomMesh[i].pFaceMatArray[nCurrMat].face = nCurrMat; pTR2RoomMesh[i].pFaceMatArray[nCurrMat].mat = Level->Rooms[i].RoomData.Rectangles[j].Texture; nCurrMat++; texture.insert(Level->Rooms[i].RoomData.Rectangles[j].Texture); } [/code] Copy of triangle of mesh: [code] for( int j = 0; j < Level->Rooms[i].RoomData.NumTriangles; j++) { pTR2RoomMesh[i].pIndicesArray[dwCurrIndices] = Level->Rooms[i].RoomData.Triangles[j].Vertices[0]; dwCurrIndices++; pTR2RoomMesh[i].pIndicesArray[dwCurrIndices] = Level->Rooms[i].RoomData.Triangles[j].Vertices[1]; dwCurrIndices++; pTR2RoomMesh[i].pIndicesArray[dwCurrIndices] = Level->Rooms[i].RoomData.Triangles[j].Vertices[2]; dwCurrIndices++; pTR2RoomMesh[i].pFaceMatArray[nCurrMat].face = nCurrMat; pTR2RoomMesh[i].pFaceMatArray[nCurrMat].mat = Level->Rooms[i].RoomData.Triangles[j].Texture; nCurrMat++; texture.insert(Level->Rooms[i].RoomData.Triangles[j].Texture); } [/code] Now re-arrange indices and build attribute table: [code] pTR2RoomMesh[i].nNumMatFaceMap = nCurrMat; pTR2RoomMesh[i].nNumFaces = Level->Rooms[i].RoomData.NumRectangles * 2 + Level->Rooms[i].RoomData.NumTriangles; vector< vector <FACE_MATMAP> > v; v.resize(texture.size()); nCurrMat = 0; set<UINT>::iterator it; int test = 0; for(it = texture.begin(); it!=texture.end(); it++) { for(UINT j=0; j<pTR2RoomMesh[i].nNumMatFaceMap; j++) { UINT mat = pTR2RoomMesh[i].pFaceMatArray[j].mat; if(mat == static_cast<UINT> (*it) ) { FACE_MATMAP fm; fm.face = j; fm.OrigMat = mat; fm.mat = nCurrMat; v[nCurrMat].push_back(fm); } } nCurrMat++; } pTR2RoomMesh[i].nNumMat = v.size(); vector< vector <FACE_MATMAP> > vn; vn.resize(pTR2RoomMesh[i].nNumMat); pTR2RoomMesh[i].pIndicesArrayNew = new WORD[dwNumIndices]; ZeroMemory(pTR2RoomMesh[i].pIndicesArrayNew, sizeof(WORD) * dwNumIndices); int k=0; int l=0; for(UINT r=0; r<pTR2RoomMesh[i].nNumMat; r++) { for(UINT j=0; j<v[r].size(); j++) { UINT f = v[r][j].face; UINT v1 = pTR2RoomMesh[i].pIndicesArray[f*3]; UINT v2 = pTR2RoomMesh[i].pIndicesArray[(f*3)+1]; UINT v3 = pTR2RoomMesh[i].pIndicesArray[(f*3)+2]; pTR2RoomMesh[i].pIndicesArrayNew[k] = v1; pTR2RoomMesh[i].pIndicesArrayNew[k+1] = v2; pTR2RoomMesh[i].pIndicesArrayNew[k+2] = v3; k+=3; FACE_MATMAP fm; fm.face = l; l++; fm.mat = r; fm.OrigMat = v[r][j].OrigMat; vn[r].push_back(fm); } } pTR2RoomMesh[i].pAttr = new D3DXATTRIBUTERANGE[pTR2RoomMesh[i].nNumMat]; for(UINT k=0; k<pTR2RoomMesh[i].nNumMat; k++) { pTR2RoomMesh[i].pAttr[k].AttribId = k; pTR2RoomMesh[i].pAttr[k].VertexStart = pTR2RoomMesh[i].pIndicesArrayNew[vn[k][0].face*3]; pTR2RoomMesh[i].pAttr[k].VertexCount=vn[k].size() *3; pTR2RoomMesh[i].pAttr[k].FaceStart = vn[k][0].face; pTR2RoomMesh[i].pAttr[k].FaceCount = (DWORD) vn[k].size(); } m_pD3DDevice->CreateVertexBuffer( pTR2RoomMesh[i].nNumVerts * sizeof(LEVEL_VERTEX), D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1, D3DPOOL_MANAGED, &pTR2RoomMesh[i].pVB, NULL ); LEVEL_VERTEX* pDstV; pTR2RoomMesh[i].pVB->Lock( 0, 0, (void**)&pDstV, 0 ); for( UINT j = 0; j < pTR2RoomMesh[i].nNumVerts; j++) { pDstV[j].p.x = pTR2RoomMesh[i].pVertsArray[j].p.x; pDstV[j].p.y = pTR2RoomMesh[i].pVertsArray[j].p.y; pDstV[j].p.z = pTR2RoomMesh[i].pVertsArray[j].p.z; } pTR2RoomMesh[i].pVB->Unlock(); WORD *pDstI=0; m_pD3DDevice->CreateIndexBuffer( pTR2RoomMesh[i].nNumFaces * 3 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &pTR2RoomMesh[i].pIB, NULL ); pTR2RoomMesh[i].pIB->Lock( 0, 0, (void**)&pDstI, 0 ); for(UINT j = 0; j < pTR2RoomMesh[i].nNumFaces * 3; j++) { pDstI[j] = pTR2RoomMesh[i].pIndicesArrayNew[j]; } pTR2RoomMesh[i].pIB->Unlock(); [/code] And draw: [code] for (int i = 0; i < Level->NumRooms; i++) { for(UINT k = 0; k < pTR2RoomMesh[i].nNumMat; k++) { m_pD3DDevice->SetMaterial(&Material); m_pD3DDevice->SetTexture( 0, pTR2RoomMesh[0].m_TextureArray.g_pRoomTextures ); // Draw the mesh subset m_pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1); m_pD3DDevice->SetStreamSource( 0, pTR2RoomMesh[i].pVB, 0, sizeof(LEVEL_VERTEX) ); m_pD3DDevice->SetIndices( pTR2RoomMesh[i].pIB ); m_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, //BaseVertexIndex pTR2RoomMesh[i].pAttr[k].VertexStart, //MinIndex pTR2RoomMesh[i].pAttr[k].VertexCount, //NumVertices pTR2RoomMesh[i].pAttr[k].FaceStart*3, //StartIndex pTR2RoomMesh[i].pAttr[k].FaceCount ); //NumPrimitives } } [/code] When I draw my vert and index buffer DrawIndexedPrimitive() without atribute buffer - its all right. But if I use atribute buffer - draw of mesh is wrong. That is building indices in pIndicesArrayNew is right, but atribute table is wrong. What is the matter? Thanks in advance.
  12. I am confused with DrawIndexedPrimitive() DX9. I am myself create Attribute Buffer, create Vert Buffer and Index Buffer. But 3D model don`t render properly. What is the matter? What I draw my model of room without attribute buffer- it draw properly. But if I use my attribute buffer its draw not correct. Indices Array arranged by material. That is for example: Mat #1 - > face 1, face 2, face 3 Mat #2 -> face 4, face 5, face 6 etc. And indices array contain: 1, 2, 3, 4, 5, 6 etc. My code: [CODE] pTR2RoomMesh[i].pAttr = new D3DXATTRIBUTERANGE[pTR2RoomMesh[i].nNumMat]; for(UINT k=0; k<pTR2RoomMesh[i].nNumMat; k++) { set <int> myset; for(UINT j=0; j< v[k].size(); j++) { //calculate count of vertex in attribute buffer k UINT v1, v2, v3; UINT face = v[k][j].face; v1 = pTR2RoomMesh[i].pIndicesArrayNew[face*3]; v2 = pTR2RoomMesh[i].pIndicesArrayNew[face*3 + 1]; v3 = pTR2RoomMesh[i].pIndicesArrayNew[face*3 + 2]; myset.insert(v1); myset.insert(v2); myset.insert(v3); } pTR2RoomMesh[i].pAttr[k].AttribId = k; pTR2RoomMesh[i].pAttr[k].VertexStart = pTR2RoomMesh[i].pIndicesArrayNew[vn[k][0].face*3]; pTR2RoomMesh[i].pAttr[k].VertexCount = vn[k].size() * 3 ;// (DWORD) myset.size(); pTR2RoomMesh[i].pAttr[k].FaceStart = vn[k][0].face; pTR2RoomMesh[i].pAttr[k].FaceCount = (DWORD) vn[k].size(); } //draw room for (int i = 0; i < Level->NumRooms; i++) { for(int k = 0; k < pTR2RoomMesh[i].nNumMat; k++) { .......................... m_pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1); m_pD3DDevice->SetStreamSource( 0, pTR2RoomMesh[i].pVB, 0, sizeof(LEVEL_VERTEX) ); m_pD3DDevice->SetIndices( pTR2RoomMesh[i].pIB ); m_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, pTR2RoomMesh[i].pAttr[k].VertexStart, //MinIndex pTR2RoomMesh[i].pAttr[k].VertexCount, //NumVertices pTR2RoomMesh[i].pAttr[k].FaceStart*3, //StartIndex pTR2RoomMesh[i].pAttr[k].FaceCount ); //NumPrimitives ................... [/CODE] Thanks in advance!
  13. I found that the vert of my model need to multiple with SkinTM matrix. I rewrote the code: [source lang="cpp"] struct FatVertAll { int origVert; //index of vertex Point3 pos; //position of vert Point3 normal; Point2 uv[4]; }; ISkin *skin = GetSkin(node); ISkinContextData *skinData; Matrix3 initTM; if(skin) { skinData = skin->GetContextInterface(node); skin->GetSkinInitTM(node, initTM); } ................. FatVertAll fv; for (int i = 0; i < numFace; i++) { Point3 p; for (int k = 0; k < 3; k++) { fv.origVert = TObj->mesh.faces[i].getVert(k); p = TObj->mesh.getVert(fv.origVert); if(skin) { p = initTM.PointTransform(p); } AdjustPoint(p); fv.pos =p; .................. [/source] This is screenshot: http://img534.imageshack.us/img534/917/10208485.jpg Here is a screenshot of what should be a model: http://img803.imageshack.us/img803/319/39207539.jpg What I am doing wrong? P.S. numMax - this is number maximum of afected bones.
  14. Yes, order of matrix multiplication have sence. You are rigth: V = v*m3*m2*m1. This is in practice. But in the book say transformation is applied from top to bottom- that is vice versa- it just say so. This is mean took Root_Frame and from Root_Frame in the bottom hierarchy does multiplication recursively. That is: [source lang="cpp"] void CModel::UpdateFrameMatrices(LPFRAME pFrame, LPD3DXMATRIX pParentMatrix) { if (pParentMatrix) { D3DXMatrixMultiply(&pFrame->matCombined, &pFrame->TransformationMatrix, pParentMatrix); } else pFrame->matCombined = pFrame->TransformationMatrix; if (pFrame->pFrameSibling) { UpdateFrameMatrices((LPFRAME)pFrame->pFrameSibling, pParentMatrix); } if (pFrame->pFrameFirstChild) { UpdateFrameMatrices((LPFRAME)pFrame->pFrameFirstChild, &pFrame->matCombined); } } [/source] For example Update(pRootFrame); - from pRootFrame - top hiearachy- to bttom ierarchy. But multiplication inside function do vise versa: [source land="cpp"] if (pParentMatrix) { D3DXMatrixMultiply(&pFrame->matCombined, //m2 &pFrame->TransformationMatrix, //m2 pParentMatrix); // m1 } [/source] that is Step1 Update() ------->m2 = m2*m1 Step2 Update() ------->m3=m3*m2; Step3 Update() ------->m=v*m3; So only in the books say - from top to bottom update ieararchy. But inside function update first multiple m2 then m1, m= m2*m1 and so on.
  15. According Cam3Person theory you must have a model and camera (camera move around and follow a model). You need create class model and class camera. Class model Update func (update model move according movement keys left, right, up, down and mouse input): [source lang="cpp"] void CModel::FrameMove(float fTime) { //mouse move POINT mousePos; GetCursorPos(&mousePos); //return mouse in center screen SetCursorPos(nScreenWidth/2, nScreenHeight/2); //how many pix mouse move int nDeltaX=nScreenWidth/2-mousePos.x; int nDeltaY=nScreenHeight/2-mousePos.y; D3DXVECTOR2 m_vRotVelocity = m_vMouseDelta * m_fRotationScaler; if(nDeltaX<0) { //move right D3DXMATRIX matRot; D3DXVECTOR3 vUpTemp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); D3DXMatrixRotationAxis(&matRot,&vUpTemp,D3DXToRadian(m_vRotVelocity.x)); D3DXVec3TransformNormal(&vRight,&vRight,&matRot); D3DXVec3TransformNormal(&vUp,&vUp,&matRot); D3DXVec3TransformNormal(&vLook,&vLook,&matRot); //D3DXVec3TransformCoord( &vPos, &vPos, &matRot ); } if(nDeltaX>0) { //move left D3DXMATRIX matRot; D3DXVECTOR3 vUpTemp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); D3DXMatrixRotationAxis(&matRot,&vUpTemp,D3DXToRadian(-m_vRotVelocity.x)); D3DXVec3TransformNormal(&vRight,&vRight,&matRot); D3DXVec3TransformNormal(&vUp,&vUp,&matRot); D3DXVec3TransformNormal(&vLook,&vLook,&matRot); } if(nDeltaY<0) { //move down D3DXMATRIX matRot; D3DXMatrixRotationAxis(&matRot,&vRight,D3DXToRadian(m_vRotVelocity.y)); D3DXVec3TransformNormal(&vUp,&vUp,&matRot); D3DXVec3TransformNormal(&vLook,&vLook,&matRot); } if(nDeltaY>0) { //move up D3DXMATRIX matRot; D3DXMatrixRotationAxis(&matRot,&vRight,D3DXToRadian(-m_vRotVelocity.y)); D3DXVec3TransformNormal(&vUp,&vUp,&matRot); D3DXVec3TransformNormal(&vLook,&vLook,&matRot); } //keyboard move if(GetAsyncKeyState('D')& 0xFF00) { //move right D3DXMATRIX matRot; D3DXVECTOR3 vUpTemp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); D3DXMatrixRotationAxis(&matRot,&vUpTemp,D3DXToRadian(m_vRotVelocity.x/15)); D3DXVec3TransformNormal(&vRight,&vRight,&matRot); D3DXVec3TransformNormal(&vUp,&vUp,&matRot); D3DXVec3TransformNormal(&vLook,&vLook,&matRot); } if(GetAsyncKeyState('A')& 0xFF00) { //move left D3DXMATRIX matRot; D3DXVECTOR3 vUpTemp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); D3DXMatrixRotationAxis(&matRot,&vUpTemp,D3DXToRadian(-m_vRotVelocity.x/15)); D3DXVec3TransformNormal(&vRight,&vRight,&matRot); D3DXVec3TransformNormal(&vUp,&vUp,&matRot); D3DXVec3TransformNormal(&vLook,&vLook,&matRot); } float ratioMove = 50; D3DXVECTOR3 vAccel = D3DXVECTOR3(0,0,0); if(GetAsyncKeyState('W')& 0xFF00) { vAccel = D3DXVECTOR3(vLook.x, 0.0f, vLook.z) * ratioMove * fTime; } if(GetAsyncKeyState('S')& 0xFF00) { vAccel = D3DXVECTOR3(vLook.x, 0.0f, vLook.z) * -ratioMove * fTime; } //change position vPos+=vAccel; //makes all vectors of camera perpendicular each other D3DXVec3Normalize( &vLook, &vLook ); D3DXVec3Cross( &vRight, &vUp, &vLook ); D3DXVec3Normalize( &vRight, &vRight ); D3DXVec3Cross( &vUp, &vLook, &vRight ); D3DXVec3Normalize( &vUp, &vUp ); } void CFirstPersonCamera::Update(float TimeScale) { //move camera follow and around model D3DXMATRIX mtxRotate; D3DXMatrixIdentity( &mtxRotate ); D3DXVECTOR3 vecRight = m_pModel->GetRight(), vecUp = m_pModel->GetUp(), vecLook = m_pModel->GetLook(); mtxRotate._11 = vecRight.x; mtxRotate._21 = vecUp.x; mtxRotate._31 = vecLook.x; mtxRotate._12 = vecRight.y; mtxRotate._22 = vecUp.y; mtxRotate._32 = vecLook.y; mtxRotate._13 = vecRight.z; mtxRotate._23 = vecUp.z; mtxRotate._33 = vecLook.z; //camera is 15 unit up model, and -50 unit from back of model D3DXVECTOR3 vOffset(0,15,-50); D3DXVECTOR3 vecOffset(0,0,0); // Calculate our rotated offset vector D3DXVec3TransformCoord( &vecOffset, &vOffset, &mtxRotate ); // vecOffset now contains information to calculate where our camera position SHOULD be. D3DXVECTOR3 vecPosition = m_pModel->GetPosition() + vecOffset; if(vPos.y<0.0f) vPos.y = 0.0f; //calculate view matrix matView._11 = vecRight.x; matView._21 = vecRight.y; matView._31 = vecRight.z; matView._12 = vecUp.x; matView._22 = vecUp.y; matView._32 = vecUp.z; matView._13 = vecLook.x; matView._23 = vecLook.y; matView._33 = vecLook.z; matView._41 =- D3DXVec3Dot( &vecPosition , &vecRight ); matView._42 =- D3DXVec3Dot( &vecPosition , &vecUp ); matView._43 =- D3DXVec3Dot( &vecPosition , &vecLook ); } class CModel{ D3DXVECTOR3 GetRight(){return vRight;}; D3DXVECTOR3 GetUp(){return vUp;}; D3DXVECTOR3 GetLook() {return vLook;}; D3DXVECTOR3 GetPosition(){return vPos;}; }; [/source] My source code you can download http://www.rapidshare.ru/2665660