I have a sfml window container, and it appears to be working, however the glViewPorts are the wrong size, which I assume is because the wrong sf::Window is being passed.
Here is a function which adds to the window: It takes some information about the sfml window.
int WindowContainer::PushBack(WindowData& data)
{
if(data.WindowSettingsOK() && data.VideoModeOK()){
mWindowVector.resize(mWindowVector.size() + 1);
mDisplayFuncVector.resize(mWindowVector.size());
mInputFuncVector.resize(mWindowVector.size());
mWindowVector.at(mWindowVector.size() - 1) = new sf::Window();
mWindowVector.at(mWindowVector.size() - 1)->Create(data.VideoMode(), data.Title(), data.Style(), data.Settings());
mWindowVector.at(mWindowVector.size() - 1)->SetPosition(data.PositionX(), data.PositionY());
mDisplayFuncVector.at(mWindowVector.size() - 1) = nullptr;
mInputFuncVector.at(mWindowVector.size() - 1) = nullptr;
return 0;
}
else{
PrintError(ErrorMessageType::BadSettings);
return 1;
}
}
Alternatively, this function may be called to setup the display and input function callbacks:
int WindowContainer::PushBack(WindowData& data, function_p displayFunc, function_p inputFunc)
{
int return_val = PushBack(data);
mDisplayFuncVector.at(mWindowVector.size() - 1) = displayFunc;
mInputFuncVector.at(mWindowVector.size() - 1) = inputFunc;
return return_val;
}
Then, when the window needs .Display()'ing, this function is called:
void WindowContainer::ProcessDisplay()
{
for(unsigned int i = 0; i < mWindowVector.size(); i ++){
if(mDisplayFuncVector.at(i) != nullptr){
mDisplayFuncVector.at(i)(*mWindowVector.at(i), mClock, (const void*&)mExternalDrawingDataPointer);
}
mWindowVector.at(i)->Display();
}
}
... This is all good, until the result on the screen is that resizing one window affects the viewport of both windows. This suggests that calling the callback function: mDisplayFuncVector.at(i)(*mWindowVector.at(i), mClock, (const void*&)mExternalDrawingDataPointer); gives the argument of *mWindowVector.at(0) each time, instead of each window individually. (As in *mWindowVector.at(i))
Can anyone help with this problem?
The main loop contains this code:
while(container.Access(0)->IsOpened()){
container.ProcessInput();
container.ProcessDisplay();
}
Container.Access(int) is this function:
const sf::Window*& WindowContainer::Access(unsigned int index)
{
if(index > mWindowVector.size()){
PrintError(ErrorMessageType::IndexOutOfRange);
}
else{
return (const sf::Window*&)mWindowVector.at(index);
}
return (const sf::Window*&)mWindowVector.at(0);
}
Thanks again, I'm sure I have made a mistake somewhere but cannot spot it.
I have been thinking about this question and suspect openGL becomes confused with which window is it drawing to if more than one object is pushed back without a call to Display() to sync everything.
I am yet to test this and confirm.
EDIT The window container now works. It has nothing to do with the callback functions argument.
Related
I am new to C++. I've wrote code in C# and PHP.Since I am using Unreal engine I am trying to learn C++. For my project I need to make a screenshot in-game and show it immediately so I want to get it as a texture.
I made a blueprint node which calls this function i've made:
void UMyBlueprintFunctionLibrary::TakeScreenshot()
{
FScreenshotRequest::RequestScreenshot(true);
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Tried to take screenshot");
}
When I hover my mouse above RequestScreenshot I see the following pop-up:
"Screenshot can be read from memory by subscribing to the viewsport OnScreenshopCaptured delegate"
So that is what I try to do but I have no idea how I looked up this:
https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/Engine/UGameViewportClient/OnScreenshotCaptured/
Can someone tell me how to implement this and how you see/know how to implement it?
I have an alternative, no delegate, but FRenderTarget::ReadPixel() to some buffer you allocated, by implementing your own UGameViewportClient (inherit it), and overriding Draw() function.
I'll show the essential codes, but not complete.
void UMyGameViewportClient::Draw(FViewport* Viewport, FCanvas* SceneCanvas)
{
Super::Draw(Viewport, SceneCanvas);
if (any_condition_you_need) {
CaptureFrame();
}
}
void UMyGameViewportClient::CaptureFrame()
{
if (!Viewport) {
return;
}
if (ViewportSize.X == 0 || ViewportSize.Y == 0) {
return;
}
ColorBuffer.Empty(); // Declare this in header as TArray<FColor>
if (!Viewport->ReadPixels(ColorBuffer, FReadSurfaceDataFlags(),
FIntRect(0, 0, ViewportSize.X, ViewportSize.Y)))
{
return;
}
SaveThumbnailImage();
}
void UMyGameViewportClient::SaveThumbnailImage()
{
IImageWrapperModule& wrappermodule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
auto wrapper_ptr = wrappermodule.CreateImageWrapper(EImageFormat::PNG);
for (int i = 0; i < ColorBuffer.Num(); i++)
{
auto ptr = &ColorBuffer[i];
auto r = ptr->R;
auto b = ptr->B;
ptr->R = b;
ptr->B = r;
ptr->A = 255;
} // not necessary, if you like bgra, just change the following function argument to ERGBFormat::BGRA
wrapper_ptr->SetRaw(&ColorBuffer[0], ColorBuffer.Num() * 4,
ViewportSize.X, ViewportSize.Y, ERGBFormat::RGBA, 8);
FFileHelper::SaveArrayToFile(wrapper_ptr->GetCompressed(), *ThumbnailFile);
}
Sorry, but I have to repeat the same question as I asked before "C++, Adding conditions in class vars".
I am using SDL2 here.
In obj.h: (excluding preprocessor commands)
class obj {
public:
SDL_Rect clip;
void addCollideWith( SDL_Rect rect );
void hasCollide();
void clearCollideWith();
private:
std::list<bool *> collideWith;
};
In obj.cpp: (excluding preprocessor commands)
void obj::addCollideWith( SDL_Rect rect )
{
collideWith.push_back(SDL_HasIntersection(obj.clip, rect));
}
void obj::hasCollide()
{
bool retval = true;
for (std::list<bool *>::iterator it = collideWith.begin(); it != collideWith.end(); it++)
{
retval = retval && **it;
}
return retval;
}
void clearCollideWith()
{
collideWith.clear();
}
Inside main function, I am saying that the object moves by one pixel and every time when it moves by one pixel, it checks for collision with other objects. I cleared the pointer thing '*' as I am not putting in variables as you can see: collideWith.push_back(SDL_HasIntersection(obj.clip, rect));. What I do is to make it move a pixel, clear collideWith and add collideWith condition again for updating whether it is true or false.
Now, whats the problem?
Its making the program really really slow! If I remove collideWith thing and then, starts the program, it gets a lot more smoother. Now, what I want, is to store the statement rather than true or false. std::list takes:
collideWith.pushBack(true /*OR*/ false);
But what I want is:
collideWith.pushBack(/*statement determining whether it is true or false*/ var1 > var2);
Please do complain if context is missing or the question is somehow, not understandable!
(NOTE: Context related to moving the object and declaring obj clip sub-vars is not mentioned as they are not a part of question.)
You could try to replace
std::list<bool *> collideWith;
with
std::list<SDL_Rect> collideWith;
in order to track of the rectangles that you want to considere.
The implementation could be :
void obj::addCollideWith( SDL_Rect rect )
{
collideWith.push_back(rect);
}
// to test if it collides with at least one rectangle
bool obj::hasCollide()
{
bool retval = false;
for (std::list<SDL_Rect>::iterator it = collideWith.begin(); it != collideWith.end(); it++)
{
retval = retval || SDL_HasIntersection(obj.clip, *it);
}
return retval;
}
// to test if it collides with all rectangles
/* bool obj::hasCollide()
{
bool retval = true;
for (std::list<SDL_Rect>::iterator it = collideWith.begin(); it != collideWith.end(); it++)
{
retval = retval && SDL_HasIntersection(obj.clip, *it);
}
return retval;
} */
EDIT: by not working I mean that in my main array mA in main doesn't show any change to the elements within the array.
I have been checking my functions as I develop the headers and they have been working perfectly: Until I got to the final header MonitorArray.h.
mA.getScreen(i).checkScreen();
Didn't work and I couldn't work out why. So I created a new function within MonitorArray to do a similar job using the same function, and to my surprise it worked.
mA.pollScreens();
Which uses (Inside MonitorArray.h):
monitorArray[i].checkScreen();
Function getScreen:
ScreenArray MonitorArray::getScreen(int arrayPointer)
{
if (arrayPointer<0 || arrayPointer>=monitors)
{
return false;
}
else
{
return monitorArray[arrayPointer];
}
}
Function checkScreen and addArray:
void ScreenArray::checkScreen()
{
HDC dMonitor;
PixelArray pArray;
int lenX = 0, lenY = 0;
dMonitor = CreateDC(iMonitor.szDevice, iMonitor.szDevice, NULL, NULL);
lenX = (iMonitor.rcWork.right - iMonitor.rcWork.left) - 1;
lenY = (iMonitor.rcWork.bottom - iMonitor.rcWork.top) - 1;
pArray.setColour(0, GetPixel(dMonitor, 0, 0));
pArray...
...
...
addArray(&pArray);
ReleaseDC(NULL, dMonitor);
}
void ScreenArray::addArray(PixelArray* pA)
{
if (previousCheck(*pA))
{
arrayPosition = 0;
screenArray[arrayPosition] = *pA;
arrayPosition++;
}
else
{
screenArray[arrayPosition] = *pA;
arrayPosition++;
}
if (arrayPosition==11)
{
//Run screen saver on monitor
}
}
Why does running the command within the header file through a new function work but running the functions from main not?
Assuming that "didn't work" means "didn't affect the ScreenArray in my MonitorArray", it's because getScreen returns a copy of the array element
ScreenArray MonitorArray::getScreen(int arrayPointer)
while the new member function most likely works with the array directly.
You'll need to return a pointer to the array element instead:
ScreenArray* MonitorArray::getScreen(int arrayPointer)
{
if (arrayPointer<0 || arrayPointer>=monitors)
{
return NULL;
}
else
{
return &monitorArray[arrayPointer];
}
}
(BTW: the implicit conversion from bool to ScreenArray looks very odd.)
I was able to run this code without getting an error on the iPhone simulator. However, when I run it on my iPhone, I am getting a EXC_BAD_ACCESS error. Here is the code:
CCAnimate * explosionAnimate = CCAnimate::create(explosionAnimation);
CCCallFuncN * callFuncN = CCCallFuncN::create(this,callfuncN_selector(GameLayer::removeChildFromParent));
CCFiniteTimeAction * explosionSequence = CCSequence::create(explosionAnimate, callFuncN);
CCSprite * explosionSprite = CCSprite::createWithSpriteFrameName("explosion_frame_1");
addChild(explosionSprite);
explosionSprite->setPosition(point);
explosionSprite->runAction(explosionSequence);
}
void GameLayer::removeChildFromParent(CCNode * child)
{
child->removeFromParent();
}
The error occurs when CCSequence::create(...) is called. Debugging through CCSequence::create(...)
CCFiniteTimeAction* CCSequence::create(CCFiniteTimeAction *pAction1, va_list args)
{
CCFiniteTimeAction *pNow;
CCFiniteTimeAction *pPrev = pAction1;
while (pAction1)
{
pNow = va_arg(args, CCFiniteTimeAction*);
if (pNow)
{
pPrev = createWithTwoActions(pPrev, pNow);
}
else
{
break;
}
}
return pPrev;
}
I am seeing that "createWithTwoActions" get's called twice. That doesn't seem right. On the 2nd call to "createWithTwoActions". The error occurs within CCFiniteTimeAction, specifically at the getDuration() inline function:
inline float getDuration(void) { return m_fDuration; }
Any ideas why this would be occurring?
I was able to resolve the issue by calling CCSequence::create() like:
CCSequence::create(explosionAnimate, callFuncN, NULL);
instead of:
CCSequence::create(explosionAnimate, callFuncN);
I'm guessing this has to do with the nature of CCFiniteAction pointers and C++ variable length arguments.
How can I find the current depth inside a recursive function in C++ without passing in the previous level? i.e. is it possible to know how many times the function was called without using a parameter to keep track of the level and passing that number in as a parameter each time the function is called?
For example my recursive function looks like this:
DoSomething(int level)
{
print level;
if (level > 10)
return;
DoSomething(++level);
}
main
{
DoSomething(0);
}
Building on the answer already given by JoshD:
void recursive()
{
static int calls = 0;
static int max_calls = 0;
calls++;
if (calls > max_calls)
max_calls = calls;
recursive();
calls--;
}
This resets the counter after the recursive function is complete, but still tracks the maximum depth of the recursion.
I wouldn't use static variables like this for anything but a quick test, to be deleted soon after. If you really need to track this on an ongoing basis there are better methods.
You could use a static variable in the function...
void recursive()
{
static int calls = 0;
calls++;
recursive();
}
Of course, this will keep counting when you start a new originating call....
If you want it to be re-entrant and thread-safe, why not:
void rec(int &level) // reference to your level var
{
// do work
rec(++level); // go down one level
}
main()
{
//and you call it like
int level=0;
rec(level);
cout<<level<<" levels."<<endl;
}
No static/global variables to mess up threading and you can use different variables for different recursive chains for re-entrancy issues.
You can use a local static variable, if you don't care about thread-safety.
Although, this will only give you a proper count the first time you run your recursive routine. A better technique would be a RAII guard-type class which contains an internal static variable. At the start of the recursive routine, construct the guard class. The constructor would increment the internal static variable, and the destructor would decrement it. This way, when you create a new stack-frame the counter increments by one, and when you return from each stack-frame the counter would decrement by one.
struct recursion_guard
{
recursion_guard() { ++counter; }
~recursion_guard() { --counter; }
static int counter;
};
int recursion_guard::counter = 0;
void recurse(int x)
{
recursion_guard rg;
if (x > 10) return;
recurse(x + 1);
}
int main()
{
recurse(0);
recurse(0);
}
Note however, that this is still not thread-safe. If you need thread-safety, you can replace the static-storage variable with a thread-local-storage variable, either using boost::thread_specific_ptr or the C++0x thread local facilities.
You could also pass in the level as a template parameter, if it can be determined at compile-time. You could also use a function object. This is by far and away the best option - less hassle, and static variables should be avoided wherever possible.
struct DoSomething {
DoSomething() {
calls = 0;
}
void operator()() {
std::cout << calls;
calls++;
if (calls < 10)
return operator()();
return;
}
int calls;
};
int main() {
DoSomething()(); // note the double ().
std::cin.get();
}
convert level to an instance variable of a new object (typically a template) capable of containing the arguments and (possibly) the function. then you can reuse the recursion accumulator interface.
You can also try using a global variable to log the depth.
var depth = 0;
DoSomething()
{
print ++depth;
if (depth > 10)
return;
DoSomething();
}
main
{
DoSomething(0);
}
I came here when I sensed that some recursion is required, because I was implementing a function that can validate the chain of trust in a certificate chain. This is not X.509 but instead it is just the basics wherein the issuer key of a certificate must match the public key of the signer.
bool verify_chain(std::vector<Cert>& chain,
Cert* certificate,
unsigned char* pOrigin = nullptr, int depth = 0)
{
bool flag = false;
if (certificate == nullptr) {
// use first element in case parameter is null
certificate = &chain[0];
}
if (pOrigin == nullptr) {
pOrigin = certificate->pubkey;
} else {
if (std::memcmp(pOrigin, certificate->pubkey, 32) == 0) {
return false; // detected circular chain
}
}
if (certificate->hasValidSignature()) {
if (!certificate->isRootCA()) {
Cert* issuerCert = certificate->getIssuer(chain);
if (issuerCert) {
flag = verify_chain(chain, issuerCert, pOrigin, depth+1);
}
} else {
flag = true;
}
}
if (pOrigin && depth == 1) {
pOrigin = nullptr;
}
return flag;
}
I needed to know the recursion depth so that I can correctly clean up pOrigin. at the right stack frame during the unwinding of the call stack.
I used pOrigin to detect a circular chain, without which the recursive call can go on forever. For example,
cert0 signs cert1
cert1 signs cert2
cert2 signs cert0
I later realized that a simple for-loop can do it for simple cases when there is only one common chain.
bool verify_chain2(std::vector<Cert> &chain, Cert& cert)
{
Cert *pCert = &cert;
unsigned char *startkey = cert.pubkey;
while (pCert != nullptr) {
if (pCert->hasValidSignature()) {
if (!pCert->isRootCA()) {
pCert = pCert->getIssuer(chain);
if (pCert == nullptr
|| std::memcmp(pCert->pubkey, startkey, 32) == 0) {
return false;
}
continue;
} else {
return true;
}
} else {
return false;
}
}
return false;
}
But recursion is a must when there is not one common chain but instead the chain is within each certificate. I welcome any comments. Thank you.