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

Author Topic: Is there a way to just pass in .png or .jpg data into sf::Texture(); ?  (Read 3134 times)

0 Members and 1 Guest are viewing this topic.

Ragbot

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Email
Like when we have the data stored in a char[] or std::string?

and is the same possible for sf::Music with .wav and .ogg files?

I tried this.... but...
I kinda regret it now...

That was hell...

#include <iostream>
#include <fstream>
#include <ios>
#include <SFML/Audio.hpp>


int main()
{
        std::string str = "";
        std::string file = "";
        std::ifstream fileStream("audio.wav", std::ios::binary);
        while(getline(fileStream, str))
        {
                file += str;
        }

        sf::Music audio;
        audio.openFromMemory(file.data(), file.length());
        audio.play();

        while(audio.getStatus() != sf::SoundSource::Stopped){}


        return 0;
}
 
« Last Edit: May 27, 2021, 05:57:19 pm by Ragbot »

kojack

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
That loop is corrupting the data.
Wav files are binary data, they don't have lines as such. The getline function looks for end of line characters (which will be coincidental, since there's no lines to end) and strips them away. So the result in file will be missing bytes.
Wav is just waveform data, so you probably won't notice, but more complex formats like compressed textures will be corrupted.

Anyway, Texture has loadFromMemory, which is the equivalent of Music's openFromMemory.

Ragbot

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Email
so what should I use to get the binary without corrupting the data?

Stauricus

  • Sr. Member
  • ****
  • Posts: 299
    • View Profile
    • Email
why are you trying to open from memory the file that you just did read? why don't you simply use 'openFromFile'?
anyway, if you really want to have the resource included in your executable, this is how you do it.

kojack

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
so what should I use to get the binary without corrupting the data?
As Stauricus said, the easiest way to get stuff into SFML is to use the open/load functions. Music::openFromFile can load wav, ogg and flac. Texture::loadFromFile can load bmp, png, tga, jpg, gif, psd, hdr and pic.

But if you do want to open a binary file yourself (handy for things not part of SFML like save files, maps, etc), here's an quick example.
#include <fstream>
#include <filesystem>

int main()
{
    // Path to file
    std::filesystem::path p = "raw.dat";
    std::error_code ec;
    // Get the size of the file
    auto size = std::filesystem::file_size(p,ec);
    // Make sure no errors happened when getting the size
    if (!ec)
    {
        // Allocate enough memory for it
        char* data = new char[size];
        // Open the file for binary reading
        std::fstream in("raw.dat", std::ios::binary | std::ios::in);
        // If it opened...
        if (in.good())
        {
            // Read in the file
            in.read(data, size);
            // You now have the entire file sitting in data
        }
        // Release memory now that we are done
        delete[] data;
    }
    return 0;
}
 
This is using C++17, it added the file system stuff that can check the size of a file.
Also some may prefer to use a vector or something for the data, but I just stick to simple new/delete (yeah, I learned C++ long before std existed)

Ragbot

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Email
why are you trying to open from memory the file that you just did read? why don't you simply use 'openFromFile'?
anyway, if you really want to have the resource included in your executable, this is how you do it.

I was just using it as an example, in my app ill try to download the data from the internet  ;)

and thanks @kojack that's exactly what I wanted