Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - T.T.H.

Pages: [1] 2 3 ... 8
1
General / Re: SFML 2.0 multi thread rendering demo
« on: September 14, 2012, 03:17:29 pm »
In a multi-threaded application, you can react to the resize in real-time (but with a tiny lag), that's why the results are so bad.
Yes, I now think it's that "tiny lag", because the the call of sf::RenderWindow::getSize() within the rendering thread does not return the precisely current size of the window. The "wobbling" seems to be a result of that.

A solution would be to handle the resize event (instead of checking the size at every frame), so that you process it only when the resize is finished. Just like in single-threaded applications.
Doing so looks like this: rotating line still rotates (which means it's still rendering), no "wobbling" but instead those borders.  Hmpf.

Is there any way not to block the main thread while resizing a window?

2
General / Re: SFML 2.0 multi thread rendering demo
« on: September 12, 2012, 06:47:23 pm »
Regarding my problem with resizing the window I already opened a thread 4,5 years ago. My current solution is to check the size of the window in every render loop and set the view again in case the size is different. In a single-threaded application I can prevent any visible stretching that way but in a multi-thread application the stretching is visible for a short amount of time and results in some nasty "wobbling".

The following code is a minimal example of a single-threaded application to demonstrate it.  I want to have a rectangle which is 100x100 pixel in size and absolutely never ever changes its visual size on the monitor.

#include <SFML/Graphics.hpp>

int main(int argc, char** argv)
{
  sf::RenderWindow renderWindow(sf::VideoMode(300, 300), "resize this window!");

  sf::RectangleShape rectangle;
  rectangle.setPosition(sf::Vector2f(100.0f, 100.0f));
  rectangle.setSize(sf::Vector2f(100.0f, 100.0f));
  rectangle.setFillColor(sf::Color(0, 0, 255));
  rectangle.setOutlineColor(sf::Color(255, 0, 0));
  rectangle.setOutlineThickness(1.0f);

  sf::Event event;
  while (renderWindow.isOpen())
  {
    while (renderWindow.pollEvent(event))
    {
      if (event.type == sf::Event::Closed) renderWindow.close();
    }
    // my current solution: renderWindow.setView(sf::View(sf::FloatRect(0.0f, 0.0f, (float) renderWindow.getSize().x, (float) renderWindow.getSize().y)));
    renderWindow.clear(sf::Color(0, 255, 0));
    renderWindow.draw(rectangle);
    renderWindow.display();
  }
  return 0;
}
 

3
General / Re: SFML 2.0 multi thread rendering demo
« on: September 12, 2012, 01:16:49 pm »
1. Is the sf::Context at the beginning of main() really necessary? What happens if you don't declare it?

I've taken this code from another application of mine where it is needed to run without errors because there is a special thread rendering to images without having a render window.

In this demo it seems not to be necessary so I removed it.

2. There's no need to test if the window is open after creating it, it is always open.

Ok. I removed it. But what happens if SFML cannot open the window?

3. The renderWindow.close() "just to be sure" is not necessary, the destructor takes care of that.

I want the render window to be closed before the message box eventually appears. I've changed the code comment accordingly to make that clear.

4. The event list optimization makes your code more complicated for really little gain, I don't think you need it (and you should generally not optimize anything before profiling it and making sure that it's worth it).

I admit I haven't profiled it but in my opinion the desire to use the mutex as rarely as possible and lock it as short is possible is worth the additional code complexity.

5. You probably don't need the beganToRun() test, a thread cannot be launched a second time if it's not finished first.

I want to make it impossible for the user to use the interface wrong (and create nasty multi-threading bugs). Mistakes like those:

// create and launch render thread
RenderThread renderThread(renderWindow);
sf::Thread thread(&RenderThread::run, &renderThread);
thread.launch();

// outch :(
sf::Thread thread2(&RenderThread::run, &renderThread);
thread2.launch();

// outch :(
renderThread.run();
 

To me there's a lot of unnecessary complexity in this code. If some tricks are indeed required, you'd better point to the corresponding issue in the tracker if it exists, or create a new one if not. A "perfect" code is supposed to be what the tutorials and documentation describe, without all these hacks. Anything else that you have to add must be reported as a bug.

I've written my demo because I haven't found a tutorial on multi-threaded rendering yet.

In addition everybody has a different definition of "perfect". I think one of the main reasons for multi-threaded rendering is not to block the rendering for of other tasks, e.x. loading resources. Nevertheless it needs to be locked once in a while - which my code does as rarely and as shortly as possible - yes, fully accepting the additional code complexity.

To be honest I hope somebody else considers my demo helpful. Based on my experience blocking threads (using mutexes) too often and too long is one of the typical beginner mistakes in multi-threaded programming.

You shouldn't get 100% with v-sync on. What is the framerate like when you activate it?
And what CPU load do you get with framerate limit alone?
Please see the screenshots in my post above for CPU loads with different settings.

Another strange observation: in my extended demo (code attached) one can toggle the vertical sync and the frame rate limit independently and on my PC I see different CPU loads based on which setting I enable before the other setting. Huh?!


Thanks for the comments to far! But what about the last of my three initial questions: there still is some visible stretching of the viewport while resizing the window - is there any way to prevent that?


[attachment deleted by admin]

4
General / Re: SFML 2.0 multi thread rendering demo
« on: September 12, 2012, 12:09:14 pm »
Regarding VerticalSync(true) and FramerateLimit(60) vs FramerateLimit(0): It seems my observation was wrong because after letting the demo run for some time the CPU load is approximately the same no matter the framerate limit.

Here are screenshots of the taskmanager with the CPU load. And another one.

5
General / SFML 2.0 multi thread rendering demo
« on: September 11, 2012, 01:53:26 pm »
I've written a short, fully functional and well documented SFML 2.0 multi thread rendering demo (see attachment) and have a couple of questions now:

Am I doing everything "right", especially regarding thread-safety and performance?

There still is some visible stretching of the viewport while resizing the window - is there any way to prevent that?

The documentation says never to use setVerticalSyncEnabled and setFramerateLimit at the same time but my demo actually has a lower CPU load (about 60% of one core) when using both setVerticalSyncEnabled(true) and setFramerateLimit(60) compared to a higher CPU load (about 100% of one core) when using only setVerticalSyncEnabled(true) - do I trust the documentation or my own tests now?

P.S.: the demo was made with Visual Studio 2010 on Windows 7 and the used font file and image file can simply be exchanged with others.

[attachment deleted by admin]

6
Graphics / problem with render images and threads
« on: July 13, 2010, 10:36:32 am »
Thank you, that change in RenderImages.cpp does solve the issue.

It is even not necessary to call...
Code: [Select]
g_pRenderImage->SetActive(false);
...then.

7
Graphics / problem with render images and threads
« on: July 12, 2010, 06:07:57 pm »
Quote from: "Laurent"
Forget about your example, it won't work anyway. You would have to use a mutex (at least) to make sure that a thread can complete a frame without being interrupted by another one.

In my example is a...
Code: [Select]
WaitForSingleObject(TempThreadHandle, INFINITE);
...which ensures that no thread runs in parallel.

In my actual project it's a bit different but even there I already ensure that the very same thread renders a complete frame.


Quote from: "Laurent"
You have to call this function when you're done using a render-image in one thread, and before another thread starts using it.


This would be here then...
Code: [Select]
<snip>
    // display (finish) render image
    g_pRenderImage->Display();

    // save render image
    std::cout << "  saving image '" << Label.str() << ".png'" << std::endl;
    g_pRenderImage->GetImage().SaveToFile(Label.str() + ".png");
  }

  // fix?
  g_pRenderImage->SetActive(false); // <<<<<< NEW <<<<<<<

  std::cout << "  done" << std::endl;
  return 0;
}

// main function
int main(int argc, char** argv)
{
<snip>

...but this does not fix the issue.

8
Graphics / problem with render images and threads
« on: July 12, 2010, 04:32:38 pm »
Thanks for the hint, but where exactly in my code do I have to put this statement? (sorry, can't get it to work myself)

9
Graphics / problem with render images and threads
« on: July 12, 2010, 03:54:07 pm »
I've ran into the following problem: when a render image is created in one thread it cannot be modified anymore in another thread. The render image is still there and it can e.x. be saved, but whatever modification (clear, draw, etc.) I throw at it the image won't change. Please note that I already do allocate an sf::Context in every thread.

The following minimalistic code example demonstrates the problem:
Code: [Select]
// include SFML
#include <SFML/Graphics.hpp>

// include STD
#include <iostream>
#include <fstream>
#include <sstream>

// include threads
#include <windows.h>
#include <process.h>

// global variable (for simplicity)
sf::RenderImage* g_pRenderImage = NULL;

// thread function
unsigned int _stdcall ThreadFunction(void* pParam)
{
  // create SFML context in every thread
  sf::Context MyContext;

  // get and output thread index
  int* pThreadIndex = (int*) pParam;
  std::cout << "thread " << *pThreadIndex << " started" << std::endl;

  // create or reuse render image
  if (g_pRenderImage == NULL) {
    std::cout << "  creating render image" << std::endl;
    g_pRenderImage = new sf::RenderImage;
    g_pRenderImage->Create(300, 100);
  } else {
    std::cout << "  reusing render image" << std::endl;
  }

  // loop
  int ImageIndex;
  for (ImageIndex = 0; ImageIndex < 2; ++ImageIndex) {

    // clear render image
    g_pRenderImage->Clear(sf::Color(200, 200, 200));

    // create label
    std::stringstream Label;
    Label << "thread" << *pThreadIndex << "image" << ImageIndex;

    // create SFML text from label
    sf::Text MyText(Label.str());
    MyText.SetColor(sf::Color(255, 0, 0));
    MyText.SetPosition(20.0f, 20.0f);

    // draw SFML text
    g_pRenderImage->Draw(MyText);

    // display (finish) render image
    g_pRenderImage->Display();

    // save render image
    std::cout << "  saving image '" << Label.str() << ".png'" << std::endl;
    g_pRenderImage->GetImage().SaveToFile(Label.str() + ".png");
  }

  std::cout << "  done" << std::endl;
  return 0;
}

// main function
int main(int argc, char** argv)
{
  // create SFML context in main thread
  sf::Context MyContext;

  // loop over threads
  int ThreadIndex;
  for (ThreadIndex = 0; ThreadIndex < 2; ++ThreadIndex) {

    // create thread
    unsigned int TempThreadID = 0;
    HANDLE TempThreadHandle = (HANDLE) _beginthreadex(
        NULL,           // no security attributes
        0,              // use default stack size
        ThreadFunction, // thread function
        &ThreadIndex,   // argument to thread function
        0,              // use default creation flags
        &TempThreadID); // returns the thread identifier

    // handle thread creation error
    if (TempThreadHandle == NULL) {
      std::cout << "failed to create thread " << ThreadIndex << std::endl;
      return 1;
    }

    // wait till thread finishes
    WaitForSingleObject(TempThreadHandle, INFINITE);
  }

  return 0;
}

This code was made with Visual C++ 2003 .NET on Windows XP 32 Bit using https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2 revision 1523.

After running this code there will be 4 image files:

"thread0image0.png" containing the text "thread0image0" which is correct.
"thread0image1.png" containing the text "thread0image1" which is correct.
"thread1image0.png" containing the text "thread0image1" which is wrong.
"thread1image1.png" containing the text "thread0image1" which is wrong.

Based on my actual, big project using multiple threads seems to work for render windows, but as the example above shows it does not work for render images.

I'd like to know whether I'm doing something wrong, whether this is intended/expected behaviour or whether this is a bug, thanks.

10
General / SFML2 and Visual C++ 2003 - possible!
« on: June 11, 2010, 06:02:11 pm »
Just made an update to my tutorial in the first post after updating SFML2 to the latest revision. After making a small modification due to a linker issue regarding external libraries and SSE2 it seems that SFML2 is actually still working in Visual C++ 2003.

11
General discussions / SFML Firefox Plugin like Flash Plugin
« on: March 23, 2010, 10:15:56 am »
1. I can't help you as I don't have experience with Firefox plugins.
2. Such a plugin would totally rock, thought about making one myself.
3. List of eventually helpful links:

http://code.google.com/p/firebreath/
Python script based generation of C++ based plugins for Firefox and IE on Windows, including VS2008 project file generation, plenty repository activity in 2010

http://code.google.com/p/nixysa/
Python script based generation of C++ based plugins for Firefox/NPAPI, used for Google's O3D

http://www.codeproject.com/KB/openGL/FirefoxOpenGL.aspx
An OpenGL Sample as Firefox Plugin - CodeProject (Sept. 2007)

http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/
series of blog posts about Firefox plugin coding, probably from one of the Firebreath coders

http://mxr.mozilla.org/seamonkey/source/modules/plugin/tools/sdk/
Some Mozilla Plugin SDK repository with quite old plugin code for Firefox but including windowless plugin

12
General discussions / [Windows-x64] Building SFML?
« on: March 23, 2010, 10:09:55 am »
I'm compiling the windows and graphics related parts of SFML2 with their default settings in VC++2008 Express on Windows Vista 64 bit and all seems fine. I assume this creates 32 bit executables and I have never tried to create 64 bit executables.

13
SFML projects / [Utility] Stroke
« on: February 18, 2010, 12:23:13 pm »
I didn't have a look at it yet but in case it's only 4 files you could even put them into SFML's wiki.

14
Network / How can i encrypt my network traffic
« on: February 16, 2010, 05:49:48 pm »
Ok, way better now. My suggestion is the following (and please note that I'm not an expert in cryptography, just a guy who solved a very similar problem like you have):

-----

1. generate good (pseudo) random numbers (at the client)

Forget rand(). Now. Instantly. Ignore that it ever existed. It's just plain bad for anything involving cryptography.

SFML's Randomizer::Random uses rand(). You've been warned.

Here is a list of decent random number generators:
http://en.wikipedia.org/wiki/List_of_pseudorandom_number_generators

Here is a nice, short paper describing a couple of algorithms:
http://www.lomont.org/Math/Papers/2008/Lomont_PRNG_2008.pdf

Several libraries already include decent pseudo random number generators, e.x. Boost has Boost.Random.

Linux has /dev/random

Windows has CryptGenRandom


preview for 3. use a random number as key for symmetric encryption

Coming later...


2. exchange the random number securely

You must get your random number securely(!) from the client to the server. You can use asymmetric encryption (public key cryptography) to do that.

One choice would be the Diffie-Hellman key exchange:
http://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange

Another choice would be to use the famous asymmetric encryption algorithm RSA:
http://en.wikipedia.org/wiki/RSA

In that case of RSA you would simply use the OpenSSL command line tool to generate a public key / private key pair. Hardcode the public key in the client code (and give the client to your users) and hardcode the private key in the server (and never, ever give out the server or the private key to anybody). Then you could include the OpenSSL library in both your client and your server to send a piece of encrypted data from the client to the server. This piece of encrypted data includes the aforementioned random number and e.x. login credentials like username and password. On Linux using OpenSSL is simple, on Windows using OpenSSL is a pain in the ass.

Unfortunately most libraries including asymmetric encryption algorithms are huge bloatware - but the topic is a quite difficult one, not to be solved simple.

Please note that asymmetric encryption does a lot of number crunching on the CPU so it's used rarely, e.x. only once during login for each connection, while the rest of the transmission of the connection is done with the way "cheaper" (CPU load wise) symmetric encryption.


3. use a random number as key for symmetric encryption

After both the client and the server known your random number -and nobody else does since you transmitted the key securely- you can use that random number as a key for a symmetric encryption (block ciphers).

Like Wikipedia says AES, Blowfish and Twofish are commonly used algorithms which should have plenty implementations flying around. Interesting is the TEA/XTEA family of block ciphers as they are meant to be very small, very simple, very fast but still secure enough. The whole C code for XTEA is on it's Wikipedia page.


-----

Rakknet, another well known UDP based network library, includes a very similar mechanism to what I explained above. The documentation for its so called "secure connections" can be found below, maybe this will help your understanding:
http://www.jenkinssoftware.com/raknet/manual/secureconnections.html

Finally I want to say that it will take you a lot of time to do it "right". And afterwards you will find out that what you considered "right" has some flaws. And then it will take you even more time to fix the flaws. Sorry if that sounds pessimistic, but I've spent my fair share of time on it and I made my fair share of mistakes. Maybe I just want to encourage you to check your priorities: how important is the encryption currently in comparison with other features of your project?

One way or the other good luck with your efforts!

15
Network / How can i encrypt my network traffic
« on: February 15, 2010, 10:47:41 am »
Do you have a client-server-model or a peer-to-peer-model?
What is the underlying network protocol?
- HTTP over TCP
- TCP
- UDP
- etc.
Which side wants to send encrypted data first?
- client to server
- server to client
- somebody to somebody
Does the other side want to send encrypted data back?
How much encrypted data do you want to send?
How "strong" must the encryption be?
- "just being able to detect network transmission errors"
- "just prevent my little brother from reading my network traffic"
- "just prevent some person with a plain text network sniffer from reading my traffic"
- "just prevent some dedicated person with cryptography knowledge from reading my network traffic"
- "just prevent a group of hackers from penetrating my network"
- "just prevent the CIA from stealing my pr0n"

Sorry, without some answers on those question I can't really give you a meaningful suggestion.

Pages: [1] 2 3 ... 8
anything