Why my code works on RenderDoc but not on Visual Studio? - c++

I'm building drawing project that takes hand drawing from user and draws it with Fourier expansion and epicircles. But I ran project on Visual Studio today again and app is only black screen. I didn't change the code at all. I ran the code on RenderDoc and it's working perfecly in there.
Here is the code that I use for rendering the drawing path:
else if(drawState == DrawState::DRAW) {
// Render objects
if (!circles.empty())
{
for (size_t i = 0; i < circles.size(); i++)
{
circles[i]->render(window);
circles[i]->update(time);
}
path.append(sf::Vertex(circles.back()->lineEnd, sf::Color(237, 34, 93)));
// Update the window
window.draw(path);
}
}
And here is the expected result on RenderDoc.
What I am doing wrong? Is there an error catching method on SFML that I can use?

Related

Saving image of maze

I created a maze generator using sfml and cpp. Once the program is run it creates a maze saves its specs in the format of txt file and then proceed to save a image. Everything works fine, but if i increase the size of the grid or decrease the size of cell dimensions some part of the maze is not saved in the image.
What i see on the screen [dont worry about the not responding part]
vs what is saved
If you want to see the source code you can find it on my github:Github Link
And if you want a walkthrough of the working of the code, you can read it on my blog:Blog link
Note for Mode: My blog is not monetized as of the timing and i am just treating it as a fun archive for projects and challenges.
if(once)
{
cout<<"maze done!!";
ofstream output("maze.txt");
output<<rows<<" "<<cols<<" "<<cellDimensions<<endl;
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
for(int k=0;k<4;k++)
{
output<<grid[i][j].wall[k]<<" ";
}
output<<endl;
}
}
// std::chrono::milliseconds timespan(60000);
// std::this_thread::sleep_for(timespan);
sf::Vector2u windowSize = window.getSize();
sf::Texture texture;
texture.create(windowSize.x, windowSize.y);
texture.update(window);
sf::Image screenshot = texture.copyToImage();
screenshot.saveToFile("sc.png");
once=0;
}
I feel like the last few statements where i try to save the image are the problem.
Thanks You!

Why is my UWP game slower in release than in debug mode?

I'm trying to do an UWP game, and i came accross a problem where my game is much slower in release mode than it is in debug mode.
My game will draw a 3D view (Dungeon master style) and will have an UI part that draws over the 3D view. Because the 3D view can slow down to a small amount of frames per seconds (FPS), i decided to make my game running the UI part always at 60 FPS.
Here is how the main gameloop looks like, in some pseudo code:
Gameloop start
Update game datas
copy actual finished 3D view from buffer to screen
draw UI part
3D view loop start
If no more time to draw more textures on the 3D view exit 3D view loop
Draw one texture to 3D view buffer
3D view loop end --> 3D view loop start
Gameloop end --> Gameloop start
Here are the actual update and render functions:
void Dungeons_of_NargothMain::Update()
{
m_ritonTimer.startTimer(static_cast<int>(E_RITON_TIMER::UI));
m_ritonTimer.frameCountPlusOne((int)E_RITON_TIMER::UI_FRAME_COUNT);
m_ritonTimer.manageFramesPerSecond((int)E_RITON_TIMER::UI_FRAME_COUNT);
m_ritonTimer.manageFramesPerSecond((int)E_RITON_TIMER::LABY_FRAME_COUNT);
if (m_sceneRenderer->m_numberTotalOfTexturesToDraw == 0 ||
m_sceneRenderer->m_numberTotalOfTexturesToDraw <= m_sceneRenderer->m_numberOfTexturesDrawn)
{
m_sceneRenderer->m_numberTotalOfTexturesToDraw = 150000;
m_sceneRenderer->m_numberOfTexturesDrawn = 0;
}
}
// RENDER
bool Dungeons_of_NargothMain::Render()
{
//********************************//
// Render UI part here //
//********************************//
//**********************************//
// Render 3D view to 960X540 screen //
//**********************************//
m_sceneRenderer->setRenderTargetTo960X540Screen(); // 3D view buffer screen
bool screen960GotFullDrawn = false;
bool stillenoughTimeLeft = true;
while (stillenoughTimeLeft && (!screen960GotFullDrawn))
{
stillenoughTimeLeft = m_ritonTimer.enoughTimeForOneMoreTexture((int)E_RITON_TIMER::UI);
screen960GotFullDrawn = m_sceneRenderer->renderNextTextureTo960X540Screen();
}
if (screen960GotFullDrawn)
m_ritonTimer.frameCountPlusOne((int)E_RITON_TIMER::LABY_FRAME_COUNT);
return true;
}
I removed what is not essential.
Here is the timer part (RitonTimer):
#pragma once
#include "pch.h"
#include <wrl.h>
#include "RitonTimer.h"
Dungeons_of_Nargoth::RitonTimer::RitonTimer()
{
initTimer();
if (!QueryPerformanceCounter(&m_qpcGameStartTime))
{
throw ref new Platform::FailureException();
}
}
void Dungeons_of_Nargoth::RitonTimer::startTimer(int timerIndex)
{
if (!QueryPerformanceCounter(&m_qpcNowTime))
{
throw ref new Platform::FailureException();
}
m_qpcStartTime[timerIndex] = m_qpcNowTime.QuadPart;
m_framesPerSecond[timerIndex] = 0;
m_frameCount[timerIndex] = 0;
}
void Dungeons_of_Nargoth::RitonTimer::resetTimer(int timerIndex)
{
if (!QueryPerformanceCounter(&m_qpcNowTime))
{
throw ref new Platform::FailureException();
}
m_qpcStartTime[timerIndex] = m_qpcNowTime.QuadPart;
m_framesPerSecond[timerIndex] = m_frameCount[timerIndex];
m_frameCount[timerIndex] = 0;
}
void Dungeons_of_Nargoth::RitonTimer::frameCountPlusOne(int timerIndex)
{
m_frameCount[timerIndex]++;
}
void Dungeons_of_Nargoth::RitonTimer::manageFramesPerSecond(int timerIndex)
{
if (!QueryPerformanceCounter(&m_qpcNowTime))
{
throw ref new Platform::FailureException();
}
m_qpcDeltaTime = m_qpcNowTime.QuadPart - m_qpcStartTime[timerIndex];
if (m_qpcDeltaTime >= m_qpcFrequency.QuadPart)
{
m_framesPerSecond[timerIndex] = m_frameCount[timerIndex];
m_frameCount[timerIndex] = 0;
m_qpcStartTime[timerIndex] += m_qpcFrequency.QuadPart;
if ((m_qpcStartTime[timerIndex] + m_qpcFrequency.QuadPart) < m_qpcNowTime.QuadPart)
m_qpcStartTime[timerIndex] = m_qpcNowTime.QuadPart - m_qpcFrequency.QuadPart;
}
}
void Dungeons_of_Nargoth::RitonTimer::initTimer()
{
if (!QueryPerformanceFrequency(&m_qpcFrequency))
{
throw ref new Platform::FailureException();
}
m_qpcOneFrameTime = m_qpcFrequency.QuadPart / 60;
m_qpc5PercentOfOneFrameTime = m_qpcOneFrameTime / 20;
m_qpc10PercentOfOneFrameTime = m_qpcOneFrameTime / 10;
m_qpc95PercentOfOneFrameTime = m_qpcOneFrameTime - m_qpc5PercentOfOneFrameTime;
m_qpc90PercentOfOneFrameTime = m_qpcOneFrameTime - m_qpc10PercentOfOneFrameTime;
m_qpc80PercentOfOneFrameTime = m_qpcOneFrameTime - m_qpc10PercentOfOneFrameTime - m_qpc10PercentOfOneFrameTime;
m_qpc70PercentOfOneFrameTime = m_qpcOneFrameTime - m_qpc10PercentOfOneFrameTime - m_qpc10PercentOfOneFrameTime - m_qpc10PercentOfOneFrameTime;
m_qpc60PercentOfOneFrameTime = m_qpc70PercentOfOneFrameTime - m_qpc10PercentOfOneFrameTime;
m_qpc50PercentOfOneFrameTime = m_qpc60PercentOfOneFrameTime - m_qpc10PercentOfOneFrameTime;
m_qpc45PercentOfOneFrameTime = m_qpc50PercentOfOneFrameTime - m_qpc5PercentOfOneFrameTime;
}
bool Dungeons_of_Nargoth::RitonTimer::enoughTimeForOneMoreTexture(int timerIndex)
{
while (!QueryPerformanceCounter(&m_qpcNowTime));
m_qpcDeltaTime = m_qpcNowTime.QuadPart - m_qpcStartTime[timerIndex];
if (m_qpcDeltaTime < m_qpc45PercentOfOneFrameTime)
return true;
else
return false;
}
In debug mode the game's UI works at 60 FPS, and the 3D view is about 1 FPS on my PC. But even there i'm not sure why i have to stop my texture drawing at 45% of one game time and call present, to get the 60 FPS, if i wait longer i only get 30 FPS. (this valor is set in "enoughTimeForOneMoreTexture()" in RitonTimer.
In Release mode it drops dramatically, having like 10 FPS for the UI part, 1 FPS for the 3D part. I tried to find why for the last 2 days, didn't find it.
Also i have another small question: How do i tell visual studio that my game is actually a game and not an app ? Or does Microsoft do the "switch" when i send my game to their store ?
Here i have put my game on my OneDrive so everyone can download the source files and try to compile it, and see if you get the same results as me:
OneDrive link: https://1drv.ms/f/s!Aj7wxGmZTdftgZAZT5YAbLDxbtMNVg
compile in either x64 Debug, or x64 Release mode.
UPDATE:
I think i found the explanation why my game is slower in release mode.
The CPU is probably not waiting for the drawing instruction to be done, but simply adds it to a list which will be forward to the GPU at it's own pace in a separate task (or maybe the GPU does that cache himself). That would explain it all.
My plan was to draw the UI first and then to draw as many textures from the 3D view as possible till 95% of a 1/60th second frame time passed and then present it to the swapchain. The UI would always be at 60 FPS and the 3D view would be as fast as the system allows it (also at 60FPS if it can all be drawn in 95% of the frame time).
This didn't work because it probbably cached all the instructions my 3D view had (i was testing with 150000 BIG texture draw instructions for the 3D view) in one frame time, and so of course the UI was as slow as the 3D view at the end, or close to.
That is also why even in debug mode i didn't get 60FPS when i waited for 95% of a frame time, i had to wait for 45% of a frame time to get my 60 FPS i wanted for the UI.
I tested it with a lower value in release mode to verify that theory, and indeed i also get 60 FPS for the UI when i stop the Drawings at only 15% of a frame time.
I tought it worked like this only in DirectX12.
"How do i tell visual studio that my game is actually a game and not an app" - there's no difference, a game is an app.
I have your code running at 300-400 FPS now in debug mode.
Firstly I commented out your code that checks if you've got time to render another texture. Don't do that. Everything the player sees should render within a single frame. If your frame is taking more than 16ms (with 60fps target) look for expensive operations, or calls that are made repeatedly, possibly adding up to some unexpected cost. Look for code that might be doing something repeatedly when it only needs to do it once per frame or per resize. etc
So the issue is that you were rendering very large textures and a lot of them. You want to avoid overdraw (rendering a pixel where you've already rendered a pixel). You can have a bit of overdraw and that's sometimes preferable to being pedantic. But you were drawing 1000x2000 textures over and over again. So you were absolutely killing the pixel shader. It just can't render that many pixels. I didn't bother looking at the code that tries to control texture rendering based on frame time remaining. For what you're trying to do, that's not helpful.
Inside your render method comment out the while and if/else sections and use this to draw an array of your textures ..
// set sprite dimensions
int w = 64, h = 64;
for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 16; x++)
{
m_sceneRenderer->renderNextTextureTo960X540Screen(x*64, y*64, w, h);
}
}
and in RenderNextTextureToScreen(int x, int y, int w, int h) ..
m_squareBuffer.sizeX = w; // 1000;
m_squareBuffer.sizeY = h; // 2000;
m_squareBuffer.posX = x; // (float)(rand() % 1920);
m_squareBuffer.posY = y; // (float)(rand() % 1080);
See how this code renders much smaller textures, the textures are 64x64 and there's no overdraw.
And just be aware that the GPU isn't all powerful, it can do a lot if you use it right, but if you just throw crazy operations at it, you can grind it to a halt, just like with the CPU. So try to render things that 'look normal', that you can imagine being in a game. You'll learn in time what's sensible and what isn't.
The most likely explanation for the code running slower in release mode is that your timing and rendering limiter code was broken. It wasn't working properly because the 3d view was running at 1fps, so then who knows what it's behaviour is. With the changes I've made, the program seems to run faster in release mode as expected. Your clock code is showing 600-1600fps in release mode now for me.

CImageList and CComboBoxEx limited to 16 transparent icons

It seems that there is a limitation to 16 transparent icons you can use in a CComboBoxEx. I have the following pseudo code:
m_ImageList.Create(16,16,ILC_COLOR32,TF_COUNT,1);
for (int nImage = 0; nImage < TF_COUNT; nImage++)
{
m_ImageList.Add(phIcons[nImage]);
DestroyIcon(phIcons[nImage]);
}
m_cmbAction.SetImageList(&m_ImageList);
The first 16 icons are OK - the following ones all have a black background instead of the transparency. The same code and Image list associated to a CTreeCtrl or a CListCtrl works beautifully. Any ideas?
EDIT: I am using Visual Studio 2013
Author posted his code in a ZIP file:
m_ImageList.Create(16, 16, ILC_COLOR32, TF_COUNT, 1);
for (int nIcon=0; nIcon < TF_COUNT; nIcon++)
{
m_ImageList.Add(m_hIcon);
}
m_ComboBox.SetImageList(&m_ImageList);
COMBOBOXEXITEM cbi;
cbi.mask = CBEIF_IMAGE | CBEIF_INDENT | CBEIF_OVERLAY |
CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM;
int nItemCount = 0;
for (int nText = 0; nText < TF_COUNT; nText++)
{
CString strItem;
strItem.Format(_T("Item %d"),nText);
cbi.iItem = nItemCount;
cbi.pszText = (LPTSTR)(LPCTSTR)strItem;
cbi.cchTextMax = strItem.GetLength();
cbi.iImage = nText;
cbi.iSelectedImage = nText;
cbi.iOverlay = nText;
cbi.iIndent = 0;
cbi.lParam = nText;
m_ComboBox.InsertItem(&cbi);
nItemCount++;
}
In this code, the error is CBEIF_OVERLAY and cbi.iOverlay = nText. Overlay image is an image drawn transparently over another image (this way, you can combine two icons). In the author's code, that is obviously not the intent.
Finally, image lists allow only up to 15 overlay icons. That explains the magic 16.
Solution 1
If you want to use transparency, you need to create image list with a mask:
m_ImageList.Create(16, 16, ILC_COLOR32 | ILC_MASK, TF_COUNT, 1)
Solution 2
Another (worse) approach is to set the desired background color (after creating the imagelist, but before adding the icons):
m_ImageList.SetBkColor(RGB(0xFF, 0xFF, 0xFF))
The problem about the background color is that you will have to figure which background color to use.
The magic number of 16
I don't think your problem is about CComboBoxEx somehow having problems with the number 16. Instead, I think your icons are a bit different, for example some truly 32-bit, and some in other format. You can test it like that:
m_ImageList.Create(16,16,ILC_COLOR32,TF_COUNT,1);
for (int nImage = 0; nImage < TF_COUNT; nImage++)
{
m_ImageList.Add(phIcons[0]);
}
m_cmbAction.SetImageList(&m_ImageList);
This code adds the same icon multiple times. I bet you won't have any issues with that. Now, you can also try this:
m_ImageList.Create(16,16,ILC_COLOR32,TF_COUNT,1);
for (int nImage = 0; nImage < TF_COUNT; nImage++)
{
m_ImageList.Add(phIcons[16]);
}
m_cmbAction.SetImageList(&m_ImageList);
And you will likely have all icons wrong.
Update 1
I do not have any issues with 16+ transparent icons on my Win8.1, so it's time to suspect that third-party software or your own code is the root of the problem. You need to prepare a minimal example of the code still containing the problem, then try it on another computer. It will be best to try on a virtual machine (you can download prebuilt one here) to reduce all possible risks of whatever software you have installed on many machines at once. If your minimal example still shows the problem on virtual machine, zip it and share with us.

Cocos2D - Collision detection getTileGIDAt

I been stuck on this issue for a few days now. I am hoping you guys can help me. I am creating a simple game following this tutorial: http://discuss.cocos2d-x.org/t/tutorial-series-use-the-cocos2d-x-3-0-game-engine-write-a-tile-map-game-part02/12991
and I got stuck on the collision detection part. The method getTileGIDAt() is ALWAYS returning 0, most likely I have found out that this is a Tiled related problem (maybe the tiles are not there, etc), but the problem is that the tiles are completely fine. Everything runs and loads smoothly, with this exception.
Thanks!
here is the code:
void HelloWorld::setPlayerPosition(Point position)
{
Point tileCoord = this->tileCoordForPosition(position);
int tileGid = _blockage->getTileGIDAt(tileCoord);
if (tileGid) {
auto properties = _tileMap->getPropertiesForGID(tileGid).asValueMap();
if (!properties.empty()) {
auto collision = properties["Blockage"].asString();
if ("True" == collision) {
return;
}
}
}
_player->setPosition(position);
}
I would try this tutorial and see how your code matches. I guess the main thing is to check that you have Tiled setup correctly for the different layers.
http://www.raywenderlich.com/29458/how-to-make-a-tile-based-game-with-cocos2d-2-x

Win7 64bits Professional. GDI doesn't work normally occasionally until resize the window

In our project, we use GDI to draw waveform and any other graphics, however, we meet a special problem, the situations are:
The waveform stop drawing, just like not response.
The buttons in toolbar also stop updating its background while mouse hots it or clicks it, however, it is very mystical, the button could respond event and open the relevant dialog.
The dialog opened from toolbar could draw normally, any figures could work well.
While resize the window, double click the title of application, anything works normally again.
So, I hope to know whether there is any bug or driven problem in Win7 64bits Pro version which have been reported.
The similar problems in stack-overflow see this link:
What could cause redraw issues on 64-bit vista but not in 32-bit in .NET WInForms?
The code of drawing waveform and graphics, and
void CZMultiPatientView::UpdateDisplay(int ThisSecondCount, int ThisMillisecondCount)
{
CClientDC dc(this);
CDC *pDC = &dc;
//
// Draw waveforms
//
DrawPatientViewWaveforms(pDC);
//
// Update parameters
//
if ((GetElapsedMilliseconds(mLastAlarmMillisecondCount, ThisMillisecondCount) >= 500) || (mForceRedraw))
{
//
// !!! SHOULD NOT DO THIS IN HERE !!!
//
if (mSetupParameterDialogDisplayed)
{
//mParameterDataDialog.UpdateCurrentParameterValues() ;
m_pParamDlg->SendMessage(WM_UPDATE_VALUE); // Kevin
}
}
if ((GetElapsedSeconds(mLastAlarmsecondCount, ThisSecondCount) >= 1) || (mForceRedraw))
{
//Update messages (once a second)
UpdateMessages(pDC);
mLastAlarmsecondCount=ThisSecondCount;
}
if (GetElapsedMilliseconds(mLastDrawParametersCount, ThisMillisecondCount) >= 200 || (mForceRedraw))
{
PostMessage(APP_UPDATE_VIEWS, (WPARAM)ThisMillisecondCount, (LPARAM)mForceRedraw);
mLastDrawParametersCount = ThisMillisecondCount;
}
//
// Update alarms
//
if (GetElapsedMilliseconds(mLastAlarmMillisecondCount, ThisMillisecondCount) >= 500)
{
mLastAlarmMillisecondCount = ThisMillisecondCount ;
DoSoundAlarmTone();
}
mForceRedraw = 0 ;
}