//-------------------------------------------------------------------------------- void CPUTGuiController::Update() { if (mActiveControlPanelSlotID == CPUT_CONTROL_ID_INVALID) return; if(mRecalculate) { RecalculateLayout(); mRecalculate = false; } if(!mUpdateBuffers) return; mUpdateBuffers = false; HEAPCHECK; static double timeSinceLastFPSUpdate = 0; static int framesSinceLastFPSUpdate = 0; static double avgFPS = 0; static CPUT_RECT windowRect = {0, 0, 0, 0}; static int lastControlsInPanel = 0; int controlsInPanel = GetNumberOfControlsInPanel(); if( 0 == controlsInPanel && lastControlsInPanel == controlsInPanel) { lastControlsInPanel = controlsInPanel; return; } lastControlsInPanel = controlsInPanel; // check and see if any of the controls resized themselves int ControlCount=GetNumberOfControlsInPanel(); // 'clear' the buffer by resetting the pointer to the head mUberBufferIndex = 0; int ii=0; while(ii<ControlCount) { CPUTControl *pControl = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[ii]; // don't draw the focus control - draw it last so it stays on 'top' if(mpFocusControl != pControl) { pControl->Draw(mpMirrorBuffer, &mUberBufferIndex, mBufferSize); } ii++; HEAPCHECK } // do the 'focused' control last so it stays on top (i.e. dropdowns) if(mpFocusControl) { mpFocusControl->Draw(mpMirrorBuffer, &mUberBufferIndex, mBufferSize); } //API Specific UpdateUberBuffers(); HEAPCHECK return; }
// Draw - must be positioned after all the controls are defined //-------------------------------------------------------------------------------- void CPUTGuiControllerDX11::Draw(ID3D11DeviceContext *pImmediateContext) { HEAPCHECK; if( 0 != GetNumberOfControlsInPanel()) { SetGUIDrawingState(pImmediateContext); } else { return; } ID3D11VertexShader *pVertexShader = mpGUIVertexShader->GetNativeVertexShader(); ID3D11PixelShader *pPixelShader = mpGUIPixelShader->GetNativePixelShader(); // if any of the controls have announced they are dirty, then rebuild the mirror buffer and rebind if(mUberBufferDirty) { // if a resize was flagged, do it now. if(mRecalculateLayout) { RecalculateLayout(); } // 'clear' the buffer by resetting the pointer to the head mUberBufferIndex = 0; mTextUberBufferIndex = 0; mFocusedControlBufferIndex = 0; mFocusedControlTextBufferIndex = 0; int ii=0; while(ii<GetNumberOfControlsInPanel()) { CPUTControl *pControl = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[ii]; // don't draw the focus control - draw it last so it stays on 'top' if(mpFocusControl != pControl) { switch(pControl->GetType()) { case CPUT_BUTTON: ((CPUTButton*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_CHECKBOX: ((CPUTCheckbox*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_SLIDER: ((CPUTSlider*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_DROPDOWN: ((CPUTDropdown*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_STATIC: ((CPUTText*)pControl)->DrawIntoBuffer(mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; } } ii++; HEAPCHECK } // do the 'focused' control last so it stays on top (i.e. dropdowns) if(mpFocusControl) { switch(mpFocusControl->GetType()) { case CPUT_BUTTON: ((CPUTButton*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_CHECKBOX: ((CPUTCheckbox*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_SLIDER: ((CPUTSlider*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_DROPDOWN: ((CPUTDropdown*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_STATIC: ((CPUTText*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; } } // update the uber-buffers with the control graphics UpdateUberBuffers(pImmediateContext); // Clear dirty flag on uberbuffer mUberBufferDirty = false; } HEAPCHECK // calculate the fps double elapsed = mpFPSTimer->GetElapsedTime(); double fps = 1.0 / elapsed; mLastFPS = (float) fps; mFPSAvg[mFPSInst] = (float) fps; mFPSInst++; if(mFPSInst == AVG_FRAMES) mFPSInst = 0; float total = 0.0f; for(int i = 0; i < AVG_FRAMES; i++) { total += mFPSAvg[i]; } int windowWidth, windowHeight; CPUTOSServices *pServices = CPUTOSServices::GetOSServices( ); pServices->GetClientDimensions( &windowWidth, &windowHeight ); // if we're drawing the FPS counter - update that // We do this independently of uber-buffer updates since we'll have FPS updates every frame, // but likely not have control updates every frame if(mbDrawFPS) { // calculate the time elapsed since last frame bool UberBufferWasDirty = mUberBufferDirty; cString Data; { wchar_t wcstring[CPUT_MAX_STRING_LENGTH]; float avgFps = total/(float)AVG_FRAMES; swprintf_s(&wcstring[0], CPUT_MAX_STRING_LENGTH, _L("Window res: %d x %d, AVG FPS:%.2f \t(FPS:%.2f) "), windowWidth, windowHeight, avgFps, fps); Data=wcstring; } // build the FPS string cString FPS = Data; mpFPSCounter->SetText(FPS); // 'draw' the string into the buffer mFPSBufferIndex = 0; mpFPSCounter->DrawIntoBuffer(mpFPSMirrorBuffer, &mFPSBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); // update the DirectX vertex buffer ASSERT(CPUT_GUI_BUFFER_STRING_SIZE > mFocusedControlTextBufferIndex, _L("CPUT GUI: Too many strings for default-sized uber-buffer. Increase CPUT_GUI_BUFFER_STRING_SIZE")); pImmediateContext->UpdateSubresource(mpFPSDirectXBuffer, 0, NULL, mpFPSMirrorBuffer, mFPSBufferIndex*sizeof(CPUTGUIVertex), 0); // start next frame timer mpFPSTimer->StartTimer(); if(false == UberBufferWasDirty) { mUberBufferDirty = false; } } // set up orthographic display GUIConstantBufferVS ConstantBufferMatrices; float znear = 0.1f; float zfar = 100.0f; DirectX::XMMATRIX m; m = DirectX::XMMatrixOrthographicOffCenterLH(0, (float)windowWidth, (float)windowHeight, 0, znear, zfar); ConstantBufferMatrices.Projection = XMMatrixTranspose( m ); // set the vertex shader pImmediateContext->VSSetShader( pVertexShader, NULL, 0 ); UINT VertexStride = sizeof(CPUTGUIVertex); UINT VertexOffset = 0; pImmediateContext->IASetVertexBuffers( 0, 1, &mpUberBuffer, &VertexStride, &VertexOffset ); m = DirectX::XMMatrixIdentity(); ConstantBufferMatrices.Model = XMMatrixTranspose( m ); pImmediateContext->UpdateSubresource( mpConstantBufferVS, 0, NULL, &ConstantBufferMatrices, 0, 0 ); pImmediateContext->VSSetConstantBuffers( 0, 1, &mpConstantBufferVS ); // -- draw the normal controls -- // draw the control graphics pImmediateContext->PSSetShader( pPixelShader, NULL, 0 ); pImmediateContext->PSSetShaderResources( 0, 1, &mpControlTextureAtlasView ); pImmediateContext->Draw(mUberBufferIndex,0); // draw the control's text pImmediateContext->PSSetShaderResources( 0, 1, &mpTextTextureAtlasView ); pImmediateContext->IASetVertexBuffers( 0, 1, &mpTextUberBuffer, &VertexStride, &VertexOffset ); // draw the text uber-buffer pImmediateContext->Draw(mTextUberBufferIndex,0); // draw the FPS counter if(mbDrawFPS) { pImmediateContext->IASetVertexBuffers( 0, 1, &mpFPSDirectXBuffer, &VertexStride, &VertexOffset ); pImmediateContext->Draw(mFPSBufferIndex, 0); } // -- draw the focused control -- // Draw the focused control's graphics pImmediateContext->PSSetShader( pPixelShader, NULL, 0 ); pImmediateContext->PSSetShaderResources( 0, 1, &mpControlTextureAtlasView ); pImmediateContext->IASetVertexBuffers( 0, 1, &mpFocusedControlBuffer, &VertexStride, &VertexOffset ); // draw the uber-buffer pImmediateContext->Draw(mFocusedControlBufferIndex,0); // Draw the focused control's text pImmediateContext->PSSetShaderResources( 0, 1, &mpTextTextureAtlasView ); pImmediateContext->IASetVertexBuffers( 0, 1, &mpFocusedControlTextBuffer, &VertexStride, &VertexOffset ); // draw the text uber-buffer pImmediateContext->Draw(mFocusedControlTextBufferIndex,0); // restore the drawing state ClearGUIDrawingState(pImmediateContext); HEAPCHECK; }
// Draw - must be positioned after all the controls are defined //-------------------------------------------------------------------------------- void CPUTGuiControllerOGL::Draw() { HEAPCHECK; static double timeSinceLastFPSUpdate = 0; static int framesSinceLastFPSUpdate = 0; static double avgFPS = 0; static double minFrameTime = 999; static double maxFrameTime = 0; static CPUT_RECT windowRect = {0, 0, 0, 0}; if( 0 == GetNumberOfControlsInPanel()) { return; } // check and see if any of the controls resized themselves int ControlCount=GetNumberOfControlsInPanel(); bool ResizingNeeded = false; for(int ii=0; ii<ControlCount; ii++) { CPUTControl *pControl = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[ii]; if(true == pControl->ControlResizedItself()) { ResizingNeeded = true; pControl->ControlResizingHandled(); } } // if any of the controls resized, then re-do the autoarrangment if(true == ResizingNeeded) { this->Resize(); } // Now check to see if any controls' graphics are dirty for(int ii=0; ii<ControlCount; ii++) { CPUTControl *pControl = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[ii]; if(true == pControl->ControlGraphicsDirty()) { mUberBufferDirty = true; break; } } // if any of the controls have announced they are dirty, then rebuild the mirror buffer and update the GFX buffer if(mUberBufferDirty) { // if a resize was flagged, do it now. if(mRecalculateLayout) { RecalculateLayout(); mRecalculateLayout = false; } // 'clear' the buffer by resetting the pointer to the head mUberBufferIndex = 0; mTextUberBufferIndex = 0; mFocusedControlBufferIndex = 0; mFocusedControlTextBufferIndex = 0; int ii=0; while(ii<GetNumberOfControlsInPanel()) { CPUTControl *pControl = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[ii]; // don't draw the focus control - draw it last so it stays on 'top' if(mpFocusControl != pControl) { switch(pControl->GetType()) { case CPUT_BUTTON: ((CPUTButton*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_CHECKBOX: ((CPUTCheckbox*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_SLIDER: ((CPUTSlider*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_DROPDOWN: ((CPUTDropdown*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_STATIC: ((CPUTText*)pControl)->DrawIntoBuffer(mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; } } ii++; HEAPCHECK } // do the 'focused' control last so it stays on top (i.e. dropdowns) if(mpFocusControl) { switch(mpFocusControl->GetType()) { case CPUT_BUTTON: ((CPUTButton*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_CHECKBOX: ((CPUTCheckbox*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_SLIDER: ((CPUTSlider*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_DROPDOWN: ((CPUTDropdown*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; case CPUT_STATIC: ((CPUTText*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE); break; } } // update the uber-buffers with the control graphics UpdateUberBuffers(); // Clear dirty flag on uberbuffer mUberBufferDirty = false; } HEAPCHECK if( mpConstantBufferVS ) { // set up orthographic display int windowWidth, windowHeight; float znear = 0.1f; float zfar = 100.0f; float4x4 m; pWindow->GetClientDimensions( &windowWidth, &windowHeight ); m = float4x4OrthographicOffCenterLH(0, (float)windowWidth, (float)windowHeight, 0, znear, zfar); GUIConstantBufferVS ConstantBufferMatrices; ConstantBufferMatrices.Projection = m; m = float4x4Identity(); ConstantBufferMatrices.Model = m; GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, mpConstantBufferVS->GetBufferID())); GL_CHECK(glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GUIConstantBufferVS), &ConstantBufferMatrices)); GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, 0)); } CPUTRenderParameters params; mpControlMaterial->GetMaterialEffects()[0]->SetRenderStates(params); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); // draw the control graphics CPUTRenderParameters p; mpUberBuffer->Draw(p, NULL); mpTextMaterial->GetMaterialEffects()[0]->SetRenderStates(params); // draw text things here // draw the FPS counter mpTextUberBuffer->Draw(p, NULL); mpControlMaterial->GetMaterialEffects()[0]->SetRenderStates(params); mpFocusedControlBuffer->Draw(p, NULL); // draw focused control mpTextMaterial->GetMaterialEffects()[0]->SetRenderStates(params); mpFocusedControlTextBuffer->Draw(p, NULL); glEnable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, 0)); HEAPCHECK; }