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

Author Topic: sf::Texture load from memory  (Read 22690 times)

0 Members and 1 Guest are viewing this topic.

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: sf::Texture load from memory
« Reply #15 on: January 25, 2015, 11:06:55 pm »
So how would I reference the image in the resource file? I should say I have very little experience with resource files so I don't know how to write them or reference the images within them, though I have been using SFML for quite a while.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: sf::Texture load from memory
« Reply #16 on: January 25, 2015, 11:15:40 pm »
To my knowledge resource files are a Windows-specific thing; at least I was never able to find any evidence that Mac and/or Linux support anything similar.  So you'll have to look at Windows documentation and tools to figure that out. SFML definitely doesn't support it directly.  Of course, that would make your code no longer cross-platform.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10049
    • View Profile
    • development blog
    • Email
Re: sf::Texture load from memory
« Reply #17 on: January 25, 2015, 11:41:19 pm »
Yes, resource files are Windows specific and I'm not sure how easily you can pass them on to SFML classes.

What we've here been talking about however, is converting an image into C++ code data, which you directly link/include into your application. This also works for any C++ compiler on any platform.

The main confusion on this thread was about the format you'd convert the image into. If you want to use the loadFromMemory function, your data must be a conversion from the binary file. If you want to use the create function, your data must be in the RGBA format.

In my small application I've used GIMP to generate the header file and then created an image out of it.

Incomplete example:

logo.hpp
#pragma once

#include <SFML/Config.hpp>

static const struct {
        sf::Uint32      width;
        sf::Uint32      height;
        sf::Uint32      bytes_per_pixel; // 2:RGB16, 3:RGB, 4:RGBA
        sf::Uint8       data[250 * 43 * 4 + 1];
} IMG_LOGO = {
    250, 43, 4,
    "\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31"
    "\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33"
    "\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377"
    "\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31"
    "\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33\32\31\377\33"
        // etc.

Application.cpp
#include "logo.hpp"

Application::Application()
{
        sf::Image img;
        img.create(IMG_LOGO.width, IMG_LOGO.height, IMG_LOGO.data);
        m_tex_logo.loadFromImage(img);
        // etc.
Official FAQ: https://www.sfml-dev.org/faq.php
Nightly Builds: https://www.nightlybuilds.ch/
——————————————————————
Dev Blog: https://dev.my-gate.net/
Thor: http://www.bromeon.ch/libraries/thor/

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: sf::Texture load from memory
« Reply #18 on: January 26, 2015, 09:29:25 pm »
Thanks, that's been working really well with my 4x4, 8x8 and 16x16 images. However I now need to include my 500x100 images into my code and when I export them from Gimp, the code is literally 10800 lines long, per image, and c++ doesn't allow strings that long. Is there any way around that?

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: sf::Texture load from memory
« Reply #19 on: January 26, 2015, 09:31:48 pm »
Sure. Split it into multiple parts in the source, combine into one in memory and load. If you insist on building them into the executable. But, to be honest, I don't really see the point. Why not keep the resources in a seperate resource file?
« Last Edit: January 26, 2015, 09:34:49 pm by Jesper Juhl »

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: sf::Texture load from memory
« Reply #20 on: January 26, 2015, 09:36:22 pm »
I'm already doing that, I have several images that are about 500 x 1000 and I was already splitting each into 10. I read on stack overflow that you can convert it into a hex array, but I don't know how to do that or how to use it with sfml. Is this where I'd use Laurent's earlier post about a converter? I must confess when I first read it I didn't understand it and I hadn't been back through this discussion.
« Last Edit: January 26, 2015, 10:11:47 pm by shadowmouse »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: sf::Texture load from memory
« Reply #21 on: January 26, 2015, 10:54:22 pm »
Quote
Is this where I'd use Laurent's earlier post about a converter?
Yes, using a byte array instead of a string should remove any compiler limitation.
Laurent Gomila - SFML developer

M74

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: sf::Texture load from memory
« Reply #22 on: January 26, 2015, 11:55:46 pm »
Here`s how i load Textures which are stored as Resources in Visual Studio 2013 on Windows:

1. Add the images to resource.rc file:
IDR_TEXTURE0    RCDATA  ".\\..\\Graphics\\Texture0.png"
IDR_TEXTURE1    RCDATA  ".\\..\\Graphics\\Texture1.png"
IDR_TEXTURE2    RCDATA  ".\\..\\Graphics\\Texture2.png"
IDR_TEXTURE3    RCDATA  ".\\..\\Graphics\\Texture3.png"
 

2. Add them to resource.h file:
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif

#define IDI_ICON1 101
#define IDI_TEXTURE0 102
#define IDI_TEXTURE1 103
#define IDI_TEXTURE2 104
#define IDI_TEXTURE3 105
#define IDI_FONT0 106
#define IDI_FONT1 107
 

3. Load them in code:
        const int TEXTURES_COUNT = 4;
        sf::Texture textures[TEXTURES_COUNT];
        sf::Sprite sprites[TEXTURES_COUNT];
        for (int i = 0; i < TEXTURES_COUNT; i++)
        {
                std::wstring numString = L"IDR_TEXTURE" + std::to_wstring(i);
                HRSRC rsrcData = FindResource(NULL, numString.c_str(), RT_RCDATA);
                LPVOID firstByte = LockResource(LoadResource(NULL, rsrcData));
                textures[i].loadFromMemory(firstByte, SizeofResource(NULL, rsrcData));
                sprites[i].setTexture(textures[i]);
                textures[i].setSmooth(true);
        }
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: sf::Texture load from memory
« Reply #23 on: January 27, 2015, 07:39:49 am »
What's the advantage of using a platform-specific solution when there's a simple and portable way to embed resources in the executable?
Laurent Gomila - SFML developer

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: sf::Texture load from memory
« Reply #24 on: January 27, 2015, 07:56:18 am »
I was not advocating Windows/VS resource files. Just that using a seperate  data file (in whatever format) is usually more managable than adding resources to the executable.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: sf::Texture load from memory
« Reply #25 on: January 27, 2015, 08:44:41 am »
Win32 resource files are compiled into the executable ;)
Laurent Gomila - SFML developer

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: sf::Texture load from memory
« Reply #26 on: January 27, 2015, 05:38:12 pm »
Just been using the converter to convert the images into const char arrays and I'm getting lots of warnings of narrowing conversion from 'int to 'const char' is ill-formed in c++ 11. Is there any way around that? I've tried converting the array into int but then img.create doesn't work.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10049
    • View Profile
    • development blog
    • Email
Re: sf::Texture load from memory
« Reply #27 on: January 27, 2015, 05:56:02 pm »
Where do these warnings get raised and what is "lots of"?
Have you taken a look at the header file generated?

Laurent's code add an extra "0xffffffff" at the end of the array (not sure why). I think you can safely remove that.
Official FAQ: https://www.sfml-dev.org/faq.php
Nightly Builds: https://www.nightlybuilds.ch/
——————————————————————
Dev Blog: https://dev.my-gate.net/
Thor: http://www.bromeon.ch/libraries/thor/

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: sf::Texture load from memory
« Reply #28 on: January 27, 2015, 05:59:37 pm »
Just tried removing the 0xfffffff and it hasn't helped, yes I've looked at the header because I've taken the code out of it and put in in my own header alongside some other image code. Lots of warnings is 750. The compiler log says that the warnings are all on the line of the curly brace that closes the array.

EDIT: I've realised that I was using img.create rather than loadFromMemory and changing that has got rid of the errors. I'm not sure why that gets rid of errors in the header file containing the image data, not the one with the img.loadFromMemory but it seems to have done.

EDIT2: No, it turns out my compiler was just not warning me about things it had warned me about before. When I added another image with exactly the same syntax as before it came out with another 1000 warnings.
« Last Edit: January 27, 2015, 06:47:22 pm by shadowmouse »

Hapax

  • Hero Member
  • *****
  • Posts: 3047
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: sf::Texture load from memory
« Reply #29 on: January 27, 2015, 06:38:33 pm »
image.create() wants pixel data whereas image.loadFromMemory() requires the data to still be in a recognisable file format.
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter