void RenderingDevice::SetAntiAliasing(bool enable) { if (mAntiAliasing != enable) { mAntiAliasing = enable; SetRenderSize(mRenderWidth, mRenderHeight); } }
// initialize buffer coordinates // parm1=NumStrings // parm2=PixelsPerString // parm3=StrandsPerString void ModelClass::InitHMatrix() { int y,x,idx,stringnum,segmentnum,xincr; int NumStrands=parm1*parm3; int PixelsPerStrand=parm2/parm3; int PixelsPerString=PixelsPerStrand*parm3; SetBufferSize(NumStrands,PixelsPerStrand); SetNodeCount(parm1,PixelsPerString); SetRenderSize(NumStrands,PixelsPerStrand); // create output mapping if (SingleNode) { y=0; for (size_t n=0; n<Nodes.size(); n++) { Nodes[n]->ActChan = stringStartChan[n]; x=0; xincr=1; for (size_t c=0; c<PixelsPerString; c++) { Nodes[n]->Coords[c].bufX=x; Nodes[n]->Coords[c].bufY=isBotToTop ? y :NumStrands-y-1; x+=xincr; if (x < 0 || x >= PixelsPerStrand) { xincr=-xincr; x+=xincr; y++; } } } } else { for (y=0; y < NumStrands; y++) { stringnum=y / parm3; segmentnum=y % parm3; for(x=0; x<PixelsPerStrand; x++) { idx=stringnum * PixelsPerString + segmentnum * PixelsPerStrand + x; Nodes[idx]->ActChan = stringStartChan[stringnum] + segmentnum * PixelsPerStrand*3 + x*3; Nodes[idx]->Coords[0].bufX=IsLtoR != (segmentnum % 2 == 0) ? PixelsPerStrand-x-1 : x; Nodes[idx]->Coords[0].bufY= isBotToTop ? y :NumStrands-y-1; Nodes[idx]->StringNum=stringnum; } } } }
// initialize buffer coordinates // parm1=NumStrings // parm2=PixelsPerString // parm3=StrandsPerString void ModelClass::InitVMatrix() { int y,x,idx,stringnum,segmentnum,yincr; int NumStrands=parm1*parm3; int PixelsPerStrand=parm2/parm3; int PixelsPerString=PixelsPerStrand*parm3; SetBufferSize(PixelsPerStrand,NumStrands); SetNodeCount(parm1,PixelsPerString); SetRenderSize(PixelsPerStrand,NumStrands); // create output mapping if (SingleNode) { x=0; for (size_t n=0; n<Nodes.size(); n++) { Nodes[n]->ActChan = stringStartChan[n]; y=0; yincr=1; for (size_t c=0; c<PixelsPerString; c++) { Nodes[n]->Coords[c].bufX=IsLtoR ? x : NumStrands-x-1; Nodes[n]->Coords[c].bufY=y; y+=yincr; if (y < 0 || y >= PixelsPerStrand) { yincr=-yincr; y+=yincr; x++; } } } } else { for (x=0; x < NumStrands; x++) { stringnum=x / parm3; segmentnum=x % parm3; for(y=0; y < PixelsPerStrand; y++) { idx=stringnum * PixelsPerString + segmentnum * PixelsPerStrand + y; Nodes[idx]->ActChan = stringStartChan[stringnum] + segmentnum * PixelsPerStrand*3 + y*3; Nodes[idx]->Coords[0].bufX=IsLtoR ? x : NumStrands-x-1; Nodes[idx]->Coords[0].bufY= isBotToTop == (segmentnum % 2 == 0) ? y:PixelsPerStrand-y-1; Nodes[idx]->StringNum=stringnum; } } } }
// initialize screen coordinates void ModelClass::CopyBufCoord2ScreenCoord() { size_t NodeCount=GetNodeCount(); int xoffset=BufferWi/2; for(size_t n=0; n<NodeCount; n++) { size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { Nodes[n]->Coords[c].screenX = Nodes[n]->Coords[c].bufX - xoffset; Nodes[n]->Coords[c].screenY = Nodes[n]->Coords[c].bufY; } } SetRenderSize(BufferHt,BufferWi); }
// Set screen coordinates for arches void ModelClass::SetArchCoord() { int xoffset,x,y; int numlights=parm1*parm2; size_t NodeCount=GetNodeCount(); SetRenderSize(parm2,numlights*2); double midpt=parm2; for(size_t n=0; n<NodeCount; n++) { xoffset=Nodes[n]->StringNum*parm2*2 - numlights; size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { double angle=-M_PI/2.0 + M_PI * (double)Nodes[n]->Coords[c].bufX/midpt; x=xoffset + (int)floor(midpt*sin(angle)+midpt); y=(int)floor(midpt*cos(angle)+0.5); Nodes[n]->Coords[c].screenX=x; Nodes[n]->Coords[c].screenY=y; } } }
// initialize screen coordinates // parm1=Number of Strings/Arches // parm2=Pixels Per String/Arch void ModelClass::SetLineCoord() { int x,y; int idx=0; size_t NodeCount=GetNodeCount(); int numlights=parm1*parm2; int half=numlights/2; SetRenderSize(numlights*2,numlights); double radians=toRadians(PreviewRotation); for(size_t n=0; n<NodeCount; n++) { size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { x=cos(radians)*idx; x=IsLtoR ? x - half : half - x; y=sin(radians)*idx; Nodes[n]->Coords[c].screenX=x; Nodes[n]->Coords[c].screenY=y + numlights; idx++; } } }
RenderingDevice::RenderingDevice(HWND windowHandle, int renderWidth, int renderHeight, bool antiAliasing) : mWindowHandle(windowHandle), mRenderWidth(renderWidth), mRenderHeight(renderHeight), mShaders(*this), mTextures(*this, 128 * 1024 * 1024), mAntiAliasing(antiAliasing) { Expects(!renderingDevice); renderingDevice = this; HRESULT status; status = D3DLOG(Direct3DCreate9Ex(D3D_SDK_VERSION, &mDirect3d9)); if (status != D3D_OK) { throw TempleException("Unable to create Direct3D9Ex interface."); } // At this point we only do a GetDisplayMode to check the resolution. We could also do this elsewhere D3DDISPLAYMODE displayMode; status = D3DLOG(mDirect3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)); if (status != D3D_OK) { throw TempleException("Unable to query display mode for primary adapter."); } D3DMULTISAMPLE_TYPE aaTypes[] = { D3DMULTISAMPLE_2_SAMPLES, D3DMULTISAMPLE_3_SAMPLES, D3DMULTISAMPLE_4_SAMPLES, D3DMULTISAMPLE_5_SAMPLES, D3DMULTISAMPLE_6_SAMPLES, D3DMULTISAMPLE_7_SAMPLES, D3DMULTISAMPLE_8_SAMPLES, D3DMULTISAMPLE_9_SAMPLES, D3DMULTISAMPLE_10_SAMPLES, D3DMULTISAMPLE_11_SAMPLES, D3DMULTISAMPLE_12_SAMPLES, D3DMULTISAMPLE_13_SAMPLES, D3DMULTISAMPLE_14_SAMPLES, D3DMULTISAMPLE_15_SAMPLES, D3DMULTISAMPLE_16_SAMPLES }; for (auto type : aaTypes) { status = mDirect3d9->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, type, nullptr); if (status == D3D_OK) { logger->trace("AA method {} is available", type); mSupportedAaSamples.push_back(type); } } // We need at least 1024x768 if (displayMode.Width < 1024 || displayMode.Height < 768) { throw TempleException("You need at least a display resolution of 1024x768."); } CreatePresentParams(); status = D3DLOG(mDirect3d9->CreateDeviceEx( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandle, D3DCREATE_HARDWARE_VERTEXPROCESSING, &mPresentParams, nullptr, &mDevice)); if (status != D3D_OK) { throw TempleException("Unable to create Direct3D9 device!"); } // TODO: color bullshit is not yet done (tig_d3d_init_handleformat et al) // Get the device caps for real this time. ReadCaps(); // Get the currently attached backbuffer if (D3DLOG(mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer)) != D3D_OK) { throw TempleException("Unable to retrieve the back buffer"); } if (D3DLOG(mDevice->GetDepthStencilSurface(&mBackBufferDepth)) != D3D_OK) { throw TempleException("Unable to retrieve depth/stencil surface from device"); } memset(&mBackBufferDesc, 0, sizeof(mBackBufferDesc)); if (D3DLOG(mBackBuffer->GetDesc(&mBackBufferDesc)) != D3D_OK) { throw TempleException("Unable to retrieve back buffer description"); } SetRenderSize(renderWidth, renderHeight); for (auto &listener : mResourcesListeners) { listener->CreateResources(*this); } mResourcesCreated = true; }
// initialize buffer coordinates // parm1=Nodes on Top // parm2=Nodes left and right // parm3=Nodes on Bottom void ModelClass::InitFrame() { int x,y,newx,newy; SetNodeCount(1,parm1+2*parm2+parm3); int FrameWidth=std::max(parm1,parm3)+2; SetBufferSize(parm2,FrameWidth); // treat as outside of matrix //SetBufferSize(1,Nodes.size()); // treat as single string SetRenderSize(parm2,FrameWidth); int chan=stringStartChan[0]; int ChanIncr=SingleChannel ? 1 : 3; int xincr[4]= {0,1,0,-1}; // indexed by side int yincr[4]= {1,0,-1,0}; x=IsLtoR ? 0 : FrameWidth-1; y=isBotToTop ? 0 : parm2-1; int dir=1; // 1=clockwise int side=x>0 ? 2 : 0; // 0=left, 1=top, 2=right, 3=bottom int SideIncr=1; // 1=clockwise if ((parm1 > parm3 && x>0) || (parm3 > parm1 && x==0)) { // counter-clockwise dir=-1; SideIncr=3; } // determine starting position if (parm1 > parm3) { // more nodes on top, must start at bottom y=0; } else if (parm3 > parm1) { // more nodes on bottom, must start at top y=parm2-1; } else { // equal top and bottom, can start in any corner // assume clockwise numbering if (x>0 && y==0) { // starting in lower right side=3; } else if (x==0 && y>0) { // starting in upper left side=1; } } size_t NodeCount=GetNodeCount(); for(size_t n=0; n<NodeCount; n++) { Nodes[n]->ActChan=chan; chan+=ChanIncr; size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { Nodes[n]->Coords[c].bufX=x; Nodes[n]->Coords[c].bufY=y; newx=x+xincr[side]*dir; newy=y+yincr[side]*dir; if (newx < 0 || newx >= FrameWidth || newy < 0 || newy >= parm2) { // move to the next side side=(side+SideIncr) % 4; newx=x+xincr[side]*dir; newy=y+yincr[side]*dir; } x=newx; y=newy; } } }