Return to “Technical”

Post

SFML::Texturing

#1
Hello everyone!
As my understanding goes Josh textures with SFML(maybe) and he most likely uses the sequence generating image->object rather than generating image-> saving -> object and I would like to know how are you able to texture objects proceduraly, do you create 3 arrays with colors and create a texture object with it, or how ever you do it, all help is appreciated!

~Sly
IVE BEEN OUT OF MY MIND A LONG TIME
Post

Re: SFML::Texturing

#2
It's is highly unlikely Josh uses sfml's texture object for anything at all.

In sfml you would generate your desired pixel data with whatever procedural method you like then create an sf::Image with sf::Image.create
If you wanted an sf::Texture object from that then you would just add the step of constructing one from the Image you have made.
This isn't an answer to your whole question, but I'm short on time just now.

Code: Select all

sf::Image tempImage;
sf::Texture myTexture;
sf::Uint8 *pixelData = perlinNoiseMaker();

tempImage.create(desiredWidth, desiredHeight, pixelData);
myTexture.loadFromImage(tempImage);
woops, my bad, everything & anything actually means specific and conformed
Post

Re: SFML::Texturing

#3
Katawa wrote:It's is highly unlikely Josh uses sfml's texture object for anything at all.

In sfml you would generate your desired pixel data with whatever procedural method you like then create an sf::Image with sf::Image.create
If you wanted an sf::Texture object from that then you would just add the step of constructing one from the Image you have made.
This isn't an answer to your whole question, but I'm short on time just now.

Code: Select all

sf::Image tempImage;
sf::Texture myTexture;
sf::Uint8 *pixelData = perlinNoiseMaker();

tempImage.create(desiredWidth, desiredHeight, pixelData);
myTexture.loadFromImage(tempImage);
This is quite helpful! Thanks!

~Sly
IVE BEEN OUT OF MY MIND A LONG TIME
Post

Re: SFML::Texturing

#4
Note Katawa's response can also be applied to updating the texture every few ticks to give an animated texture!

But yeah I seem to recall reading Josh mostly uses SFML as an easy way to get a window and OpenGL context going, as well as their text rendering features (because he found a significant speed boost and posted it in the SFML forums). Maybe he also uses it for the UI? Only one man knows! :D But he's a huge graphics nerd so I imagine he dives in deep at least as much to have good nerd vibes as to make systems do precisely what he wants.
Post

Re: SFML::Texturing

#5
Kektain wrote:Note Katawa's response can also be applied to updating the texture every few ticks to give an animated texture!

But yeah I seem to recall reading Josh mostly uses SFML as an easy way to get a window and OpenGL context going, as well as their text rendering features (because he found a significant speed boost and posted it in the SFML forums). Maybe he also uses it for the UI? Only one man knows! :D But he's a huge graphics nerd so I imagine he dives in deep at least as much to have good nerd vibes as to make systems do precisely what he wants.
Can I just say how much I like the concept of "good nerd vibes" :lol:

Yes, I use my own texture class so I can't give you any advice on SFML textures / images.

Procedural texturing is a tricky subject. Generating the texture and then applying to an object are totally orthogonal concepts, though. Generating uses one bag of tricks (noise functions, color gradients, etc.), applying to an object uses another bag (triplanar mapping, UV unwrap, cylindrical mapping, etc.). Both are hard :problem:

Good luck may the good nerd vibes be with you :geek:
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford
Post

Re: SFML::Texturing

#6
Well I have this code, but it doesn't seem to like having to output sf::Texture*, but that is the format I need to star.setTexture

Code: Select all

sf::Texture* CreateTexture(int w, int h){
sf::Image tempImage;
sf::Texture* Tex;
sf::Uint8 *pixelData = GeneratePNoise(w,h);

tempImage.create(w, h, pixelData);
Tex.loadFromImage(tempImage);
return Tex;
}
sf::Uint8* GeneratePNoise(int w,int h){
	sf::Uint8 *Data[1];
	for (int i=0;i<w*h*4;i++){
		*Data[i]=128;
	}
	return *Data;
}
hmm

~Sly
IVE BEEN OUT OF MY MIND A LONG TIME
Post

Re: SFML::Texturing

#7
The compile issues with your code are as follows:

generatePNoise should be declared before CreateTexture.

You define an array that almost immediately breaks its bounds:
sf::Uint8 *Data[1]; Only allocates space for one item but you immediately iterate over w*h*4 of them.
Consider using a std::vector instead of a basic array.


sf::Texture* Tex; needs to be
sf::Texture* Tex = new sf::Texture();
Because you try to use it later, and while the compiler knows it's a pointer to a sf::Texture, there is no sf::Texture object in memory to use unless you 'new' one.

Tex.loadFromImage(tempImage); should be
Tex->loadFromImage(tempImage); since it's a pointer

Because you 'new' data inside a function you need to clean it up later, by using 'delete' on it or it's a memory leak. I recommend not using a pointer to a texture, but make a real texture object and pass it by reference where you need to use it. There is also something called RAII that you can google, it's a pattern of making objects that clean up their own resources when they go out of scope you should learn about. Alternatively look into smart pointers, which are pointers with bonuses such as cleaning up the data they point to when they are no longer needed.


I'm very suspicious of creating the data with a pointer inside a function, and returning a pointer to that data, it seems like an easy recipe for dangling or null pointers. I highly recommend you accomplish your goal with objects instead of pointers until you know more about the nitty gritty of the language.
woops, my bad, everything & anything actually means specific and conformed
Post

Re: SFML::Texturing

#9
Alright, that by itself though is a memory leak, be sure to take the time to learn about memory management in c++, most of the code you used is old 'c-style' c++ and there's newer safer ways to do things now.
woops, my bad, everything & anything actually means specific and conformed
Post

Re: SFML::Texturing

#10
Katawa wrote:Alright, that by itself though is a memory leak, be sure to take the time to learn about memory management in c++, most of the code you used is old 'c-style' c++ and there's newer safer ways to do things now.
Yeah, I'm more of a java coder, and the java port isn't that great.
but also is there a better way of doing this function

Code: Select all

sf::Uint8* GeneratePNoise(int w,int h){
	sf::Uint8* Data[(w*h*4)];
	for (int i=0;i<w*h*4;i++){
		
		*Data[i]=128;
	}
	return *Data;
}
the sf::Uint8* Data doesn't like the w*h*4, says that it needs a constant, but I can't seem to find a resize method. :think:


~Sly
IVE BEEN OUT OF MY MIND A LONG TIME
Post

Re: SFML::Texturing

#11
Slymodi wrote:
Katawa wrote:Alright, that by itself though is a memory leak, be sure to take the time to learn about memory management in c++, most of the code you used is old 'c-style' c++ and there's newer safer ways to do things now.
Yeah, I'm more of a java coder, and the java port isn't that great.
but also is there a better way of doing this function

Code: Select all

sf::Uint8* GeneratePNoise(int w,int h){
	sf::Uint8* Data[(w*h*4)];
	for (int i=0;i<w*h*4;i++){
		
		*Data[i]=128;
	}
	return *Data;
}
the sf::Uint8* Data doesn't like the w*h*4, says that it needs a constant, but I can't seem to find a resize method. :think:


~Sly

Code: Select all

std::vector<sf::Uint8> GeneratePNoise(int w, int h){
	std::vector<sf::Uint8> data(w*h*4);
	for (int i = 0; i < w*h*4; i++) {
		data[i] = 128;
	}
	return data;
}
Although in your particular case of setting the whole thing to 128, you could write this all in one line:

Code: Select all

std::vector<sf::Uint8> GeneratePNoise(int w, int h) {
	return std::vector<sf::Uint8> data(w*h*4, 128);
}
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford
Post

Re: SFML::Texturing

#12
You can't dynamically change the size of a basic array in c++ or define an array's size at runtime, array's must be known at compile time. That's why I suggested a vector, which is essentially a dynamic array.

Code: Select all

sf::Uint8* GeneratePNoise(int w,int h){
   std::vector<sf::Uint8> data(w*h*4);

   for (int i=0;i<w*h*4;i++){
	  data[i]=128;
   }

   return data.data();
}
This is still incorrect however, as you're making data inside a function and that data is not guaranteed to be there when the function ends.
This is more correct but could be a lot better:

Code: Select all

void GeneratePNoise(int w,int h, std::vector<sf::Uint8> &data){
   
	std::vector<sf::Uint8> data(w*h*4);

   for (int i=0;i<w*h*4;i++){
	  data[i]=128;
   }
}

int main()
{
   //calling code example
   std::vector<sf::Uint8> myData; //create your vector where you'll use it
   GeneratePNoise(myData); //give GeneratePNoise a reference to myData and populate the vector with it
   //the data is safe because the object isn't created inside GeneratePNoise
}
Edit: Josh wrote a response while I was writing this, his is another (and much more elegant) example of safe data passing, his function returns a copy of the data it works with instead of defining the object before calling, allowing it to safely leave the function. On modern compilers this copy incurs no extra cost because the compiler can see that you're making an object and then later returning it, and can automatically create that object as the thing it's returning. This is called compiler eliding and is related to return value optimization.

As a side note, I highly recommend joining the stackoverflow community, most any question you can have about programming anything at all can quickly answered there with a simple search.
woops, my bad, everything & anything actually means specific and conformed
Post

Re: SFML::Texturing

#13
I give thanks to these answers
JoshParnell wrote:
Slymodi wrote:
Katawa wrote:Alright, that by itself though is a memory leak, be sure to take the time to learn about memory management in c++, most of the code you used is old 'c-style' c++ and there's newer safer ways to do things now.
Yeah, I'm more of a java coder, and the java port isn't that great.
but also is there a better way of doing this function

Code: Select all

sf::Uint8* GeneratePNoise(int w,int h){
	sf::Uint8* Data[(w*h*4)];
	for (int i=0;i<w*h*4;i++){
		
		*Data[i]=128;
	}
	return *Data;
}
the sf::Uint8* Data doesn't like the w*h*4, says that it needs a constant, but I can't seem to find a resize method. :think:


~Sly

Code: Select all

std::vector<sf::Uint8> GeneratePNoise(int w, int h){
	std::vector<sf::Uint8> data(w*h*4);
	for (int i = 0; i < w*h*4; i++) {
		data[i] = 128;
	}
	return data;
}
Although in your particular case of setting the whole thing to 128, you could write this all in one line:

Code: Select all

std::vector<sf::Uint8> GeneratePNoise(int w, int h) {
	return std::vector<sf::Uint8> data(w*h*4, 128);
}
the thing is that is a place holder, for now :think:
Katawa wrote:You can't dynamically change the size of a basic array in c++ or define an array's size at runtime, array's must be known at compile time. That's why I suggested a vector, which is essentially a dynamic array.

Code: Select all

sf::Uint8* GeneratePNoise(int w,int h){
   std::vector<sf::Uint8> data(w*h*4);

   for (int i=0;i<w*h*4;i++){
	  data[i]=128;
   }

   return data.data();
}
This is still incorrect however, as you're making data inside a function and that data is not guaranteed to be there when the function ends.
This is more correct but could be a lot better:

Code: Select all

void GeneratePNoise(int w,int h, std::vector<sf::Uint8> &data){
   
	std::vector<sf::Uint8> data(w*h*4);

   for (int i=0;i<w*h*4;i++){
	  data[i]=128;
   }
}

int main()
{
   //calling code example
   std::vector<sf::Uint8> myData; //create your vector where you'll use it
   GeneratePNoise(myData); //give GeneratePNoise a reference to myData and populate the vector with it
   //the data is safe because the object isn't created inside GeneratePNoise
}
Edit: Josh wrote a response while I was writing this, his is another (and much more elegant) example of safe data passing, his function returns a copy of the data it works with instead of defining the object before calling, allowing it to safely leave the function.

As a side note, I highly recommend joining the stackoverflow community, most any question you can have about programming anything at all can quickly answered there with a simple search.
I may join, but for my somewhat more simple questions, LT forums will do.

~Sly
IVE BEEN OUT OF MY MIND A LONG TIME
Post

Re: SFML::Texturing

#14
This is actually a forum for discussing LT related technical questions, it's not very busy though and Josh doesn't seem to mind :D

The reason I bring up stackoverflow isn't to send you away though, it's that most questions will have many people looking at them and generally they're as close to experts as you can get, be sure to check it out.
woops, my bad, everything & anything actually means specific and conformed
Post

Re: SFML::Texturing

#15
Katawa wrote:This is actually a forum for discussing LT related technical questions, it's not very busy though and Josh doesn't seem to mind :D

The reason I bring up stackoverflow isn't to send you away though, it's that most questions will have many people looking at them and generally they're as close to experts as you can get, be sure to check it out.
I've caved, here is the topic: http://stackoverflow.com/questions/1730 ... ng-in-sfml
IVE BEEN OUT OF MY MIND A LONG TIME

Online Now

Users browsing this forum: No registered users and 5 guests

cron