SDL blit surface: Segmentation fault - c++

Every time I run this program I got a this error:
Segmentation fault
testing.cpp
#include <iostream>
#include <cstdint>
#include <SDL.h>
#include <SDL_image.h>
#include "Surface.h"
#include "Point2D.h"
int main() {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
std::cerr << "Can not init SDL" << std::endl;
return -1;
}
SDL_Surface *scr = SDL_SetVideoMode(800, 600, 0, SDL_HWSURFACE | SDL_DOUBLEBUF);
if ( scr == NULL ) {
std::cerr << "Can not open window" << std::endl;
return -1;
}
SDL_WM_SetCaption("Test Surface class", NULL);
Surface screen;
Surface image;
screen.set(SDL_GetVideoSurface());
if (image.load("./data/images/logo.png") == false) {
std::cerr << "Can not open file" << std::endl;
return -1;
}
bool run = true;
uint32_t sticks = SDL_GetTicks();
while(run) {
if (screen.draw(image, Rectangle(0, 0, image.getWidth(), image.getHeight()), Point2D(0, 0)) == false) {
std::cerr << "Can not draw to window" << std::endl;
return -1;
}
if ((SDL_GetTicks() - sticks)/1000 > 5) {
std::cerr << "End of time" << std::endl;
run = false;
}
SDL_Flip(screen.sdlSurface());
}
std::cerr << "Done" << std::endl;
SDL_Quit();
return 0;
}
There is the source code of class Surface
#include "Surface.h"
#include "Color.h"
Surface::Surface() {
this->surface = NULL;
}
Surface::~Surface() {
SDL_FreeSurface(this->surface);
this->surface = NULL;
}
bool Surface::draw(Surface source, Rectangle source_area, Point2D position) {
SDL_Rect sr = source_area.sdlRect();
SDL_Rect tr = {position.getX(), position.getY(), 0, 0};
std::cout << sr.x << "," << sr.y << "," << sr.w << "," << sr.h << std::endl;
std::cout << tr.x << "," << tr.y << "," << tr.w << "," << tr.h << std::endl;
std::cout << source.sdlSurface() << std::endl;
std::cout << this->surface << std::endl;
// TR and SR are currently unused. Just for case of testing
if (SDL_BlitSurface(source.sdlSurface(), NULL, this->surface, NULL) != 0) {
return false;
}
return true;
}
bool Surface::fill(Color color, Rectangle area) {
SDL_Rect tr = area.sdlRect();
std::cout << tr.x << "," << tr.y << "," << tr.w << "," << tr.h << std::endl;
std::cout << (int)color.sdlColor() << std::endl;
if ( SDL_FillRect(this->surface, &tr, color.sdlColor()) != 0) {
return false;
}
return true;
}
Rectangle Surface::getSize() {
return Rectangle(0, 0, this->getWidth(), this->getHeight());
}
bool Surface::load(std::string file) {
SDL_Surface *src = IMG_Load(file.c_str());
if (src == NULL) {
std::cout << "cyh" << std::endl;
std::cout << IMG_GetError() << std::endl;
return false;
}
this->surface = SDL_DisplayFormatAlpha(src);
if (this->surface == NULL) {
std::cout << "cyh1" << std::endl;
std::cout << SDL_GetError() << std::endl;
return false;
}
SDL_FreeSurface(src);
src = NULL;
return true;
}
void Surface::set(SDL_Surface *surface) {
this->surface = surface;
}
void Surface::set(Surface surface) {
this->surface = surface.sdlSurface();
}
The problem is probably in the draw function. If I change this line:
if (SDL_BlitSurface(source.sdlSurface(), NULL, this->surface, NULL) != 0) {
to:
if (SDL_BlitSurface(IMG_Load("./data/images/logo.png"), NULL, this->surface, NULL) != 0) {
everything seems to be ok. Could you give me a suggestion where should be the problem?

You're violating The Rule of 3.
You need to define a copy constructor and a copy assignment operator for this to work properly.
When you're passing the Surface in to the draw method, you're making a copy of it. Since you're managing a resource inside the Surface class (the SDL_Surface*), you'll have multiple instances of the class pointing at the same surface, so when the destructors are called, you'd be freeing the same SDL_Surface* more than once.
Edit: I would recommend passing your arguments by const reference. You don't need to make copies of the Surface objects when you want to draw them.
This:
bool Surface::draw(Surface source, Rectangle source_area, Point2D position);
Would become this:
bool Surface::draw(const Surface &source, const Rectangle &source_area, const Point2D &position);
And this can be applied to your other functions too.

Related

Streams API For Fast-RTPS

I want to use fast-rtps to publish video(streams data) to subscriber. While I publish ten consecutive jpg file successfully, every picture received by subscriber wastes a lot of time to processing because I use function get_byte_value get a pixel one by one.
Do anyone know how to publish and subscribe more efficiently by fast-rtps midleware? (Create a new type? other?)
Below is my publisher's and subscriber's code:
Publisher.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file PicturePublisher.cpp
*
*/
#include "Publisher.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/PublisherAttributes.h>
#include <fastrtps/publisher/Publisher.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <thread>
#include <time.h>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PicturePublisher::PicturePublisher()
: mp_participant(nullptr)
, mp_publisher(nullptr)
, m_DynType(DynamicType_ptr(nullptr))
{
}
bool PicturePublisher::init()
{
cv::Mat image = cv::imread("drone.jpg", 1);
std::vector<unsigned char> buffer;
cv::imencode(".jpg", image, buffer);
// Create basic builders
DynamicTypeBuilder_ptr struct_type_builder(DynamicTypeBuilderFactory::get_instance()->create_struct_builder());
DynamicType_ptr octet_type(DynamicTypeBuilderFactory::get_instance()->create_byte_type());
DynamicTypeBuilder_ptr sequence_type_builder(DynamicTypeBuilderFactory::get_instance()->create_sequence_builder(octet_type, 3873715));
DynamicType_ptr sequence_type = sequence_type_builder->build();
// Add members to the struct. By the way, id must be consecutive starting by zero.
struct_type_builder->add_member(0, "index", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(1, "size", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(2, "Picture", sequence_type);
struct_type_builder->set_name("Picture"); // Need to be same with topic data type
DynamicType_ptr dynType = struct_type_builder->build();
m_DynType.SetDynamicType(dynType);
m_DynHello = DynamicDataFactory::get_instance()->create_data(dynType);
m_DynHello->set_uint32_value(0, 0);
m_DynHello->set_uint32_value(buffer.size(), 1);
MemberId id;
// std::cout << "init: " << id << std::endl;
DynamicData* sequence_data = m_DynHello->loan_value(2);
for (int i = 0; i < buffer.size(); i++) {
if (i == buffer.size() - 1) {
std::cout << "Total Size: " << i + 1 << std::endl;
}
sequence_data->insert_byte_value(buffer[i], id);
}
m_DynHello->return_loaned_value(sequence_data);
ParticipantAttributes PParam;
PParam.rtps.setName("DynPicture_pub");
mp_participant = Domain::createParticipant(PParam, (ParticipantListener*)&m_part_list);
if (mp_participant == nullptr)
{
return false;
}
//REGISTER THE TYPE
Domain::registerDynamicType(mp_participant, &m_DynType);
//CREATE THE PUBLISHER
PublisherAttributes Wparam;
Wparam.topic.topicKind = NO_KEY;
Wparam.topic.topicDataType = "Picture";
Wparam.topic.topicName = "PictureTopic";
mp_publisher = Domain::createPublisher(mp_participant, Wparam, (PublisherListener*)&m_listener);
if (mp_publisher == nullptr)
{
return false;
}
return true;
}
PicturePublisher::~PicturePublisher()
{
Domain::removeParticipant(mp_participant);
DynamicDataFactory::get_instance()->delete_data(m_DynHello);
Domain::stopAll();
}
void PicturePublisher::PubListener::onPublicationMatched(
Publisher* /*pub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
firstConnected = true;
std::cout << "Publisher matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Publisher unmatched" << std::endl;
}
}
void PicturePublisher::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PicturePublisher::runThread(
uint32_t samples,
uint32_t sleep)
{
uint32_t i = 0;
while (!stop && (i < samples || samples == 0))
{
if (publish(samples != 0))
{
uint32_t index;
m_DynHello->get_uint32_value(index, 0);
std::cout << "runThreading...; \tSample Index: " << index << "; \t";
uint32_t size;
m_DynHello->get_uint32_value(size, 1);
std::cout << "size: " << size << std::endl;
if (i == 9){
std::cout << "Structure message" << " with index: " << i + 1 << " SENT" << std::endl;
// Avoid unmatched condition impact subscriber receiving message
std::cout << "Wait within twenty second..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
}
++i;
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
}
}
void PicturePublisher::run(
uint32_t samples,
uint32_t sleep)
{
stop = false;
std::thread thread(&PicturePublisher::runThread, this, samples, sleep);
if (samples == 0)
{
std::cout << "Publisher running. Please press enter to stop the Publisher at any time." << std::endl;
std::cin.ignore();
stop = true;
}
else
{
std::cout << "Publisher running " << samples << " samples." << std::endl;
}
thread.join();
}
bool PicturePublisher::publish(
bool waitForListener)
{
// std::cout << "m_listener.n_matched: " << m_listener.n_matched << std::endl;
if (m_listener.firstConnected || !waitForListener || m_listener.n_matched > 0)
{
uint32_t index;
m_DynHello->get_uint32_value(index, 0);
m_DynHello->set_uint32_value(index + 1, 0);
mp_publisher->write((void*)m_DynHello);
return true;
}
return false;
}
In PicturePublisher::init() function
Subsciber.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file Subscriber.cpp
*
*/
#include "Subscriber.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/SubscriberAttributes.h>
#include <fastrtps/subscriber/Subscriber.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PictureSubscriber::PictureSubscriber()
: mp_participant(nullptr)
, mp_subscriber(nullptr)
, m_DynType(DynamicType_ptr(nullptr))
{
}
struct timespec begin, end;
double elapsed;
std::vector<unsigned char> buffer;
bool PictureSubscriber::init()
{
ParticipantAttributes PParam;
PParam.rtps.setName("DynPicture_sub");
mp_participant = Domain::createParticipant(PParam, (ParticipantListener*)&m_part_list);
if (mp_participant == nullptr)
{
return false;
}
// Create basic builders
DynamicTypeBuilder_ptr struct_type_builder(DynamicTypeBuilderFactory::get_instance()->create_struct_builder());
DynamicTypeBuilder_ptr octet_builder(DynamicTypeBuilderFactory::get_instance()->create_byte_builder());
DynamicTypeBuilder_ptr sequence_type_builder(DynamicTypeBuilderFactory::get_instance()->create_sequence_builder(octet_builder.get(), 3873715));
DynamicType_ptr sequence_type = sequence_type_builder->build();
// Add members to the struct.
struct_type_builder->add_member(0, "index", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(1, "size", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(2, "Picture", sequence_type);
struct_type_builder->set_name("Picture");
DynamicType_ptr dynType = struct_type_builder->build();
m_DynType.SetDynamicType(dynType);
m_listener.m_DynHello = DynamicDataFactory::get_instance()->create_data(dynType);
//REGISTER THE TYPE
Domain::registerDynamicType(mp_participant, &m_DynType);
//CREATE THE SUBSCRIBER
SubscriberAttributes Rparam;
Rparam.topic.topicKind = NO_KEY;
Rparam.topic.topicDataType = "Picture";
Rparam.topic.topicName = "PictureTopic";
mp_subscriber = Domain::createSubscriber(mp_participant, Rparam, (SubscriberListener*)&m_listener);
if (mp_subscriber == nullptr)
{
return false;
}
return true;
}
PictureSubscriber::~PictureSubscriber()
{
Domain::removeParticipant(mp_participant);
DynamicDataFactory::get_instance()->delete_data(m_listener.m_DynHello);
Domain::stopAll();
}
void PictureSubscriber::SubListener::onSubscriptionMatched(
Subscriber* /*sub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
std::cout << "Subscriber matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Subscriber unmatched" << std::endl;
}
}
void PictureSubscriber::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PictureSubscriber::SubListener::onNewDataMessage(
Subscriber* sub)
{
if (sub->takeNextData((void*)m_DynHello, &m_info))
{
if (m_info.sampleKind == ALIVE)
{
this->n_samples++;
// Print your structure data here.
uint32_t index;
m_DynHello->get_uint32_value(index, 0);
std::cout << "index: " << index << "; \t";
uint32_t size;
m_DynHello->get_uint32_value(size, 1);
std::cout << "size: " << size << std::endl;
DynamicType_ptr octet_type_temp(DynamicTypeBuilderFactory::get_instance()->create_byte_type());
DynamicTypeBuilder_ptr sequence_type_builder_temp(DynamicTypeBuilderFactory::get_instance()->create_sequence_builder(octet_type_temp, 3873715));
DynamicType_ptr sequence_type_temp = sequence_type_builder_temp->build();
DynamicData* sequence_data_temp = m_DynHello->loan_value(2);
for (int i = 0; i < size; i++) {
buffer.push_back(sequence_data_temp->get_byte_value(i));
}
m_DynHello->return_loaned_value(sequence_data_temp);
cv::Mat imageDecoded = cv::imdecode(buffer, 1);
cv::imwrite(std::to_string(index) + "_droneNew.jpg", imageDecoded);
}
}
}
void PictureSubscriber::run()
{
std::cout << "Subscriber running. Please press enter to stop the Subscriber" << std::endl;
std::cin.ignore();
}
void PictureSubscriber::run(
uint32_t number)
{
std::cout << "Subscriber running until " << number << "samples have been received" << std::endl;
while (number > this->m_listener.n_samples)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
In PictureSubscriber::SubListener::onNewDataMessage(Subscriber* sub) function
Here at eProsima, we have found some solutions to the problem you point out.
Firstly, please note that you don't need to use Dynamic Types to define the type that contains the image you are going to transmit. The easiest thing to do in your case is to define your type through an IDL file. Using the IDL file and the Fast-DDS-Gen tool you can generate the code for access to the data type elements, as well as automatically generate the data serialization and deserialization functions. In the Picture.idl file you will find the type defined in IDL format that best suits the data type you have created with dynamic types. Here you can find a guide on how to use the Fast-DDS-Gen tool. In this documentation you will also find a complete example of how an IDL file can be used to generate a complete DDS publisher/subscriber application, as well as the supported formats for the data. Also below are the files Publisher.cpp and Subscriber.cpp which have been modified according to the new data type.
We also recommend you to take a look at the example HelloWorldExample, as it is the one that best suits your needs. In this example you can also discover the new DDS API, included in the latest version of Fast DDS (2.1.0).
As an additional comment, we recommend that, instead of transmitting an octet vector, you encode the image in string base64 format before transmitting it since it's one of the most widespread formats for image transmission.
Picture.idl
struct Picture
{
unsigned long index;
unsigned long size;
sequence<octet> picture;
};
Publisher.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file PicturePublisher.cpp
*
*/
#include "PicturePublisher.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/PublisherAttributes.h>
#include <fastrtps/publisher/Publisher.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <thread>
#include <time.h>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PicturePublisher::PicturePublisher()
: mp_participant(nullptr)
, mp_publisher(nullptr)
{
}
bool PicturePublisher::init()
{
cv::Mat image = cv::imread("dog.jpg", cv::IMREAD_COLOR);
if(image.empty())
{
std::cout << "Could not read the image." << std::endl;
return false;
}
cv::imshow("Display window", image);
int k = cv::waitKey(0);
std::vector<unsigned char> buffer;
if(!cv::imencode(".jpg", image, buffer)){
printf("Image encoding failed");
}
m_Picture.index(0);
m_Picture.size(buffer.size());
m_Picture.picture(buffer);
ParticipantAttributes PParam;
PParam.rtps.setName("Picture_pub");
mp_participant = Domain::createParticipant(PParam, &m_part_list);
if (mp_participant == nullptr)
{
return false;
}
//REGISTER THE TYPE
Domain::registerType(mp_participant, &m_type);
// Domain::registerDynamicType(mp_participant, &m_DynType);
//CREATE THE PUBLISHER
PublisherAttributes Wparam;
Wparam.topic.topicKind = NO_KEY;
Wparam.topic.topicDataType = "Picture";
Wparam.topic.topicName = "PictureTopic";
mp_publisher = Domain::createPublisher(mp_participant, Wparam, (PublisherListener*)&m_listener);
if (mp_publisher == nullptr)
{
return false;
}
return true;
}
PicturePublisher::~PicturePublisher()
{
Domain::removeParticipant(mp_participant);
}
void PicturePublisher::PubListener::onPublicationMatched(
Publisher* /*pub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
firstConnected = true;
std::cout << "Publisher matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Publisher unmatched" << std::endl;
}
}
void PicturePublisher::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PicturePublisher::runThread(
uint32_t samples,
uint32_t sleep)
{
uint32_t i = 0;
while (!stop && (i < samples || samples == 0))
{
if (publish(samples != 0))
{
std::cout << "runThreading...; \tSample Index: " << m_Picture.index() << "; \t";
std::cout << "size: " << m_Picture.size() << std::endl;
if (i == 9){
std::cout << "Structure message" << " with index: " << i + 1 << " SENT" << std::endl;
// Avoid unmatched condition impact subscriber receiving message
std::cout << "Wait within twenty second..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
}
++i;
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
}
}
void PicturePublisher::run(
uint32_t samples,
uint32_t sleep)
{
stop = false;
std::thread thread(&PicturePublisher::runThread, this, samples, sleep);
if (samples == 0)
{
std::cout << "Publisher running. Please press enter to stop the Publisher at any time." << std::endl;
std::cin.ignore();
stop = true;
}
else
{
std::cout << "Publisher running " << samples << " samples." << std::endl;
}
thread.join();
}
bool PicturePublisher::publish(
bool waitForListener)
{
// std::cout << "m_listener.n_matched: " << m_listener.n_matched << std::endl;
if (m_listener.firstConnected || !waitForListener || m_listener.n_matched > 0)
{
m_Picture.index(m_Picture.index() + 1);
mp_publisher->write((void*)&m_Picture);
return true;
}
return false;
}
Subscriber.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file Subscriber.cpp
*
*/
#include "PictureSubscriber.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/SubscriberAttributes.h>
#include <fastrtps/subscriber/Subscriber.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PictureSubscriber::PictureSubscriber()
: mp_participant(nullptr)
, mp_subscriber(nullptr)
{
}
struct timespec begin, end;
double elapsed;
std::vector<unsigned char> buffer;
bool PictureSubscriber::init()
{
ParticipantAttributes PParam;
PParam.rtps.setName("Picture_sub");
mp_participant = Domain::createParticipant(PParam, &m_part_list);
if (mp_participant == nullptr)
{
return false;
}
//REGISTER THE TYPE
Domain::registerType(mp_participant, &m_type);
//CREATE THE SUBSCRIBER
SubscriberAttributes Rparam;
Rparam.topic.topicKind = NO_KEY;
Rparam.topic.topicDataType = "Picture";
Rparam.topic.topicName = "PictureTopic";
mp_subscriber = Domain::createSubscriber(mp_participant, Rparam, (SubscriberListener*)&m_listener);
if (mp_subscriber == nullptr)
{
return false;
}
return true;
}
PictureSubscriber::~PictureSubscriber()
{
Domain::removeParticipant(mp_participant);
}
void PictureSubscriber::SubListener::onSubscriptionMatched(
Subscriber* /*sub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
std::cout << "Subscriber matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Subscriber unmatched" << std::endl;
}
}
void PictureSubscriber::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PictureSubscriber::SubListener::onNewDataMessage(
Subscriber* sub)
{
std::cout << "Data received." << std::endl;
if (sub->takeNextData((void*)&m_Picture, &m_info))
{
if (m_info.sampleKind == ALIVE)
{
this->n_samples++;
// Print your structure data here.
uint32_t index = m_Picture.index();
std::cout << "index: " << index << "; \t";
std::cout << "size: " << m_Picture.size() << std::endl;
cv::Mat imageDecoded = cv::imdecode(m_Picture.picture(), 1);
cv::imwrite(std::to_string(index) + "_dog_received.jpg", imageDecoded);
}
}
}
void PictureSubscriber::run()
{
std::cout << "Subscriber running. Please press enter to stop the Subscriber" << std::endl;
std::cin.ignore();
}
void PictureSubscriber::run(
uint32_t number)
{
std::cout << "Subscriber running until " << number << "samples have been received" << std::endl;
while (number > this->m_listener.n_samples)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}

SFML Bullet not spawning

So I am using SFML and c++ to create a simple space game. For the life of can't get a bullet to spawn. This is my source... I am just trying to learn how to go about spawning new sprites into a game.
```
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <string>
int main()
{
// Create the main window
sf::RenderWindow app(sf::VideoMode(800, 600), "SFML window");
// Load a sprite to display
sf::Texture texture_sprite;
if (!texture_sprite.loadFromFile("cb.bmp"))
return EXIT_FAILURE;
sf::Sprite sprite(texture_sprite);
sf::Texture texture_background;
if (!texture_background.loadFromFile("space.png"))
return EXIT_FAILURE;
sf::Sprite background(texture_background);
sf::Texture texture_fire;
if (!texture_background.loadFromFile("fire_1.png"))
return EXIT_FAILURE;
sf::Sprite fire_sprite(texture_fire);
fire_sprite.setScale(4.0f, 1.6f);
std::string direction = "";
bool fire = false;
// Start the game loop
while (app.isOpen())
{
// Process events
sf::Event event;
while (app.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
app.close();
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && sprite.getPosition().x > -20)
{
sprite.move(-10,0);
std::cout << "X = " << sprite.getPosition().x << std::endl;
std::cout << "Y = " << sprite.getPosition().y << std::endl;
direction = "Left";
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && sprite.getPosition().x < 670 )
{
sprite.move(10,0);
std::cout << "X = " << sprite.getPosition().x << std::endl;
std::cout << "Y = " << sprite.getPosition().y << std::endl;
direction = "Right";
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && sprite.getPosition().y > 0)
{
sprite.move(0,-10);
std::cout << "X = " << sprite.getPosition().x << std::endl;
std::cout << "Y = " << sprite.getPosition().y << std::endl;
direction = "Up";
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && sprite.getPosition().y < 480 )
{
sprite.move(0,10);
std::cout << "X = " << sprite.getPosition().x << std::endl;
std::cout << "Y = " << sprite.getPosition().y << std::endl;
direction = "Down";
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{
fire = true;
}
else if (event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Space)
{
fire = false;
}
if(fire == true)
{
std::cout << "FIRE!!!" << std::endl;
fire_sprite.setPosition((sprite.getPosition()));
std::cout << "Fire positions is " <<fire_sprite.getPosition().x << " " << fire_sprite.getPosition().y << "The direction is " << direction <<std::endl;
}
}
app.clear();
// Draw the sprite
app.draw(background);
app.draw(sprite);
app.draw(fire_sprite);
// Update the window
app.display();
}
return EXIT_SUCCESS;
}
```
sf::Texture texture_fire;
if (!texture_background.loadFromFile("fire_1.png"))
Instead of loading texture to texture_fire you load again to texture_background. It should be:
if (!texture_fire.loadFromFile("fire_1.png"))

TTF_RenderText_Solid() Crashing Game and Visual Studio [c++][sdl ttf]

Stack Trace :
So, I'm trying to create a 2D game and right now I'm trying to display and move a image, however when I Debug the game/run it, visual studio and the game freezes and can't quit, not even when using the task manager to kill it.
The only way to unfreeze it is by logging off or restarting the pc which forces both of them to close.
I also get some weird error :
Unhandled exception at 0x71002A95 (SDL2_ttf.dll) in SDLGame.exe: 0xC0000005: Access violation reading location 0x00000000.
I have no idea what it means and how to fix it, but I'm guessing it has something to do with my code that I need to change.
Here's my code :
#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
// Macros
#define pause system("PAUSE"); // Works on windows only, removed in alpha / beta versions.
// Pre "init" of functions
void QuitGame();
int InitGame();
void processInput();
void InitRects();
// Variables
int FramesPassed = 0;
int FramesPerSecond = 0; // Not used yet
SDL_Renderer* renderer = nullptr;
SDL_Window* window = nullptr;
SDL_Event evnt;
SDL_Rect sprite1_Rect;
SDL_Rect FPS_Text_Rect;
TTF_Font* Sans = TTF_OpenFont("Fonts/Aaargh.ttf", 40);
SDL_Color Color_White = { 255, 255, 255 };
SDL_Surface* FPS_Text_Surface = nullptr;
SDL_Texture* FPS_Text = nullptr;
SDL_Texture* testImg = nullptr;
static bool isRunning = true;
int SDL_main(int argc, char* argv[])
{
InitGame();
InitRects();
std::cout << "Displaying text on screen using SDL TTF doesn't work" << std::endl;
std::cout << "This happens when the TTF Surface is being rendered on screen" << std::endl;
std::cout << "check line : 123 and 124." << std::endl;
while (isRunning)
{
FramesPassed++;
processInput();
SDL_RenderClear(renderer); // Clears the last/current frame?
// Render testImage on screen. (needs to be between render present and clear.)
SDL_RenderCopy(renderer, testImg, NULL, &sprite1_Rect);
SDL_RenderCopy(renderer, FPS_Text, NULL, &FPS_Text_Rect);
SDL_RenderPresent(renderer); // Pretty much draws everything again.
}
return 0;
QuitGame();
}
int InitGame()
{
std::cout << "Game Initializing..." << std::endl;
std::cout << "TTF SDL Initializing..." << std::endl;
if (TTF_Init() < 0)
{
std::cout << "SDL TTF Failed To Initialize : " << TTF_GetError() << std::endl;
pause
QuitGame();
}
else
{
std::cout << "SDL TTF Initialized Successfully" << std::endl;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cout << "SDL Initialization Failed : " << SDL_GetError() << std::endl;
pause
QuitGame();
}
else
{
std::cout << "SDL Initializing" << std::endl;
window = SDL_CreateWindow("Game Title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1024, 720, SDL_WINDOW_SHOWN);
if (window == NULL)
{
std::cout << "Window Creation Failed : " << SDL_GetError() << std::endl;
pause
QuitGame();
}
else
{
std::cout << "SDL Initialized Successfully" << std::endl;
std::cout << "Renderer Initializing..." << std::endl;
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL)
{
std::cout << "Renderer Creation Failed : " << SDL_GetError() << std::endl;
pause
QuitGame();
}
else
{
std::cout << "Renderer Initialized Successfully" << std::endl;
// This line (under) crashes game, and crashes visual studio...
FPS_Text_Surface = TTF_RenderText_Solid(Sans, "Frames Passed : " + FramesPassed, Color_White);
testImg = IMG_LoadTexture(renderer, "images/test.bmp");
FPS_Text = SDL_CreateTextureFromSurface(renderer, FPS_Text_Surface);
}
}
}
}
std::cout << "Game Has Successfully Initialized!" << std::endl;
return 0;
}
void InitRects()
{
sprite1_Rect.h = 32;
sprite1_Rect.w = 32;
sprite1_Rect.x = 10;
sprite1_Rect.y = 10;
FPS_Text_Rect.h = 100;
FPS_Text_Rect.w = 50;
FPS_Text_Rect.x = 2;
FPS_Text_Rect.y = 2;
}
void processInput()
{
if (SDL_PollEvent(&evnt)) {
switch (evnt.type) {
case SDL_QUIT:
QuitGame();
break;
case SDL_KEYDOWN:
switch (evnt.key.keysym.sym) {
case SDLK_a:
sprite1_Rect.x -= 1;
break;
case SDLK_d:
sprite1_Rect.x += 1;
break;
case SDLK_w:
sprite1_Rect.y-= 1;
break;
case SDLK_s:
sprite1_Rect.y += 1;
break;
}
break;
}
}
}
void QuitGame()
{
isRunning = false;
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
The problem is that you have the font as a global variable and load it straight away!
You need to call TTF_Init() first and load the font after!
By using a global vairable your loading it before initializing SDL_TTF, and this way TTF_OpenFont() will return a nullptr and if you try to read a nullptr gives an Access violation reading location 0x00000000 error!
Just call TTF_OpenFont() in a function and after TTF_Init() and it will work!
Just a tip you should check that Sans isn't a nullptr before using it!

Code::Blocks executable file doesn't have textures

I've made a basic program using the SFML library in Code::Blocks, and now all I want to do is send it to a friend. I've built my program in both debug and release mode, yet whenever I run the .exe file from my bin, it simply will not load the textures. Of course when I run it within the Code::Blocks client, it works perfectly. I'm not sure if I need to package my work or send the files separately or what, but any help would be much appreciated
Here's the code in case it's helpful somehow (I know it's not pretty):
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <string>
#include <iostream>
#include <Windows.h>
int main(){
sf::RenderWindow Window;
Window.create(sf::VideoMode(800, 600), "Enjoy :)");
sf::Clock clock;
int pixelFindX = 0, pixelFindY = 0;
int oldLoc = 0, newLoc = 0;
int changeVal = 1;
int tripleCheck = 0;
int xLoc = 0, yLoc = 100;
double timeChecker = 0;
bool execute = false, secondExecute = false;
bool oldSide = false, newSide = false, changer = true;
bool drawLeft = false, drawRight = false, drawCenter = false;
sf::Texture pTexture;
sf::Sprite playerImage;
if(!pTexture.loadFromFile("Pixel Dude.png")){
std::cout << "Could not load pTexture file" << std::endl;
}
sf::Texture bTexture;
sf:: Sprite backgroundImage;
if(!bTexture.loadFromFile("molester moon background IS DONE.jpg")){
std::cout << "Could not load bTexture file" << std::endl;
}
sf::Texture bridgeTexture;
sf::Sprite bridgeImageL;
sf::Sprite bridgeImageR;
if(!bridgeTexture.loadFromFile("pixel bridge.jpg")){
std::cout << "Could not load bridgeTexture file" << std::endl;
}
sf::Texture trophyTexture;
sf::Sprite trophyImage;
if(trophyTexture.loadFromFile("trophy pixeled.png")){
std::cout << "Could not load trophyTexture file" << std::endl;
}
sf::String stringL = "Move to the Left!", stringR = "Move to the Right!", stringC = "You are currently balanced.";
sf::String stringGo = stringL;
sf::Font font;
if(!font.loadFromFile("arial.ttf")){
std::cout << "Could not load font file" << std::endl;
}
sf::Text text(stringGo, font, 50);
text.setPosition(xLoc, yLoc);
text.setStyle(sf::Text::Bold);
playerImage.setTexture(pTexture);
playerImage.setPosition(336, 355);
playerImage.setScale(4,4);
playerImage.setTextureRect(sf::IntRect(pixelFindX*32, pixelFindY*32, 32, 32));
backgroundImage.setTexture(bTexture);
backgroundImage.setPosition(0,0);
bridgeImageL.setTexture(bridgeTexture);
bridgeImageL.setPosition(0, 450);
bridgeImageL.setScale(4.17,4.68);
bridgeImageR.setTexture(bridgeTexture);
bridgeImageR.setPosition(400,450);
bridgeImageR.setScale(4.17, 4.68);
trophyImage.setTexture(trophyTexture);
trophyImage.setPosition(600, 305);
trophyImage.setScale(2,2);
sf::View view;
sf::View viewReg;
view.reset(sf::FloatRect(0, 0, 800, 600));
view.setViewport(sf::FloatRect(0, 0, 1, 1));
viewReg.reset(sf::FloatRect(0, 0, 800, 600));
viewReg.setViewport(sf::FloatRect(0, 0, 1, 1));
std::cout << "Player Dimensioms: Width = " << playerImage.getGlobalBounds().width << ", Height = " << playerImage.getGlobalBounds().height << std::endl;
while(Window.isOpen()){
clock.restart();
sf::Event Event;
while(Window.pollEvent(Event)){
switch(Event.type){
case sf::Event::Closed:
Window.close();
break;
case sf::Event::KeyPressed:
if(Event.key.code == sf::Keyboard::Escape){
Window.close();
}
break;
}
}
//std::cout << timeChecker << std::endl;
timeChecker += clock.getElapsedTime().asSeconds();
if(timeChecker >= .00025){
execute = true;
timeChecker = 0;
//std::cout << "execute = true" << std::endl;
}
oldLoc = playerImage.getPosition().x;
oldSide = changer;
if(sf::Keyboard::isKeyPressed(sf::Keyboard::D) && execute){
playerImage.move(1, 0);
pixelFindY = 2;
tripleCheck++;
changer = true;
//std::cout << "d called" << std::endl;
} else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A) && execute){
playerImage.move(-1, 0);
pixelFindY = 1;
tripleCheck++;
changer = false;
//std::cout << "a called" << std::endl;
}
if(playerImage.getPosition().x < -96){
playerImage.setPosition(800, playerImage.getPosition().y);
} else if(playerImage.getPosition().x > 800){
playerImage.setPosition(-96, playerImage.getPosition().y);
}
newLoc = playerImage.getPosition().x;
newSide = changer;
pixelFindX += changeVal;
if(pixelFindX > 2){
pixelFindX -= 2;
changeVal = -1;
} else if(pixelFindX < 0){
pixelFindX += 2;
changeVal = 1;
}
if(oldLoc != newLoc && tripleCheck > 40 || oldSide != newSide){
playerImage.setTextureRect(sf::IntRect(pixelFindX*32, pixelFindY*32, 32, 32));
tripleCheck = 0;
//std::cout << "Yes called, pixelFindX = " << pixelFindX << ", tripleCheck = " << tripleCheck << std::endl;
} else {
//std::cout << "-----Not called, pixelFindX = " << pixelFindX << ", tripleCheck = " << tripleCheck << std::endl;
}
execute = false;
/* if(playerImage.getPosition().x + 128 > trophyImage.getPosition().x && playerImage.getPosition().x < trophyImage.getPosition().x + 192){
view.rotate(.0001);
}
*/
if(playerImage.getPosition().x > 500 - 128){
view.rotate(-.01);
drawRight = true;
} else if (playerImage.getPosition().x < 300 - 128){
view.rotate(.01);
drawLeft = true;
} else{
drawCenter = true;
}
//std::cout << "Player X: " << playerImage.getPosition().x + 128 << ", Trophy X: " << trophyImage.getPosition().x << std::endl;
if(drawLeft){
stringGo = stringR;
xLoc = 0;
} else if (drawRight){
stringGo = stringL;
xLoc = 800 - text.getGlobalBounds().width - 10;
} else if(drawCenter){
stringGo = stringC;
xLoc = 400 - text.getGlobalBounds().width / 2;
}
text.setPosition(xLoc, yLoc);
text.setString(stringGo);
Window.setView(viewReg);
Window.draw(backgroundImage);
Window.draw(text);
Window.setView(view);
Window.draw(bridgeImageL);
Window.draw(bridgeImageR);
// Window.draw(trophyImage);
Window.draw(playerImage);
Window.display();
Window.clear();
drawLeft = false;
drawRight = false;
drawCenter = false;
//Sleep(50);
}
}
Copy the compiled executable into a new folder and paste there the textures too. This folder you can send your friend (e.g. in a rar-archive).The textures won't load because probably the textures weren't in the bin/debug or bin/release folder. There are in another place wich is in the debugging mode is set as the working directory.If you want to change that (what I would not recommend) you can go to Project -> Properties -> Build targets -> [name of target] -> Execution working dir and change it to the directory where the compiled executables went.

SDL_BlitSurface() return -1 ... Why?

The SDL documentation say that SDL_BlitSurface() returns -1 when it is not successful, but i can not find why it would fail.
Here is my source code:
main.cpp
#include <iostream>
#include <string>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include "window.cpp"
#include "player.cpp"
int init();
void quit();
int main(int argc,char *args[])
{
if (init() == -1)
{
std::cerr << "Error:init()" << std::endl;
return -1;
}
window main_window("Juego","img/bg.png",800,600,32);
player player1(500,500,0,0,5,5,"img/square.png");
while (!main_window.close)
{
main_window.handle_events();
if ( main_window.draw_background() != true)
{
std::cerr << "ERROR->main_window.draw_background()" << std::endl;
main_window.close = true;
}
player1.update(main_window.screen);
SDL_Flip(main_window.screen);
SDL_Delay(60/1000);
}
quit();
return 0;
}
int init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
std::cerr << "Error while initialising SDL" << std::endl;
return -1;
}
return 0;
}
void quit()
{
SDL_Quit();
}
window.cpp
class window
{
private:
void load_image(std::string source,SDL_Surface *destination);
SDL_Surface *window_bg;
SDL_Event event_queue;
SDL_Rect window_rect;
public:
window(std::string SCREEN_TITLE,std::string SCREEN_BG,int sw,int sh,int sbpp);
void handle_events();
bool draw_background();
SDL_Surface *screen;
bool close;
};
window::window(std::string SCREEN_TITLE,std::string SCREEN_BG,int sw,int sh,int sbpp)
{
window_bg = NULL;
screen = NULL;
close = false;
window_rect.x = 0;
window_rect.y = 0;
window_rect.w = sw;
window_rect.h = sh;
screen = SDL_SetVideoMode(sw,sh,sbpp,SDL_SWSURFACE);
std::cout << "Screen created." << std::endl;
SDL_WM_SetCaption(SCREEN_TITLE.c_str(),NULL);
std::cout << "Window title: " << SCREEN_TITLE << std::endl;
load_image(SCREEN_BG,window_bg);
}
void window::handle_events()
{
while (SDL_PollEvent(&event_queue))
{
if (event_queue.type == SDL_QUIT)
{
close = true;
}
}
}
void window::load_image(std::string source,SDL_Surface *destination)
{
SDL_Surface *tmp_img = IMG_Load(source.c_str());
if (tmp_img != NULL)
{
if ((destination = SDL_DisplayFormat(tmp_img)) == NULL)
{
std::cerr << "ERROR->SDL_DisplayFormat()" << std::endl;
}
std::cout << source << " Loaded." << std::endl;
SDL_FreeSurface(tmp_img);
}
else
{
std::cerr << "Could not load: " << source << std::endl;
}
}
bool window::draw_background()
{
int error_check = SDL_BlitSurface(window_bg,&window_rect,screen,NULL);
if (error_check != 0)
{
std::cerr << "SDL_BlitSurface() == " << error_check << std::endl;
return false;
}
return true;
}
The error is in window.cpp (i think):
bool window::draw_background()
{
int error_check = SDL_BlitSurface(window_bg,NULL,screen,NULL);
if (error_check != 0)
{
std::cerr << "SDL_BlitSurface() == " << error_check << std::endl;
return false;
}
return true;
}
The output of my program is:
Screen created.
Window title: Juego
img/bg.png Loaded.
img/square.png Loaded
SDL_BlitSurface() == -1
ERROR->main_window.draw_background()
load_image(SCREEN_BG,window_bg); in the window constructor loads into a temporary SDL_Surface and never populates the destination, which I assume is an output parameter. Then when draw_background() uses window_bg, it's still NULL.
Anything could be the cause of this (I could not be arsed to look through your code, see http://sscce.org/), you can debug what's wrong by printing out SDL_GetError() on an error return value.