Issues to display Text from sfml - c++

I would like to display text in my Windows thanks to sfml. But I don't arrived to do it, the texte just don't appear in the windows, that's really strange because I can display lines without difficulties !
Can you check my code and tell me what I need to change please ? :)
My main.cpp
int main()
{
bool sortir = false;
// Création de la pile de double
Pile<double> pile_double;
// Création de la pile de string
Pile<string> pile_string;
// Création du map
map<string, function<void()>> _map;
int largeur_fenetre = 300;
int hauteur_fenetre = 400;
// Création de la fenetre
sf::RenderWindow window(sf::VideoMode(largeur_fenetre, hauteur_fenetre), "Interpreteur NPI");
//copie largeur / longueur
push(pile_double, (double) largeur_fenetre);
push(pile_double, (double) hauteur_fenetre);
// on fait tourner le programme tant que la fenêtre n'a pas été fermée
while (window.isOpen())
{
// on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
sf::Event event;
while (window.pollEvent(event))
{
cout << "passage 1er while" << endl;
// fermeture de la fenêtre lorsque l'utilisateur le souhaite
if (event.type == sf::Event::Closed)
window.close();
}
// effacement de la fenêtre en noir
window.clear(sf::Color::Black);
window.display();
cout << "coucou" << endl;
while (sortir == false)
{
cout << "Entrez la commande souhaité >";
string carac;
cin >> carac;
// Recherche du string dans le map
for (map<string, function<void()>>::iterator it = _map.begin(); it != _map.end(); ++it) // Debut recherche de la relation
{
// S'il est trouvé on demarre sa fonction associé
if (carac == it->first)
{
(it->second)();
pile_double.display();
pile_string.display();
window.display();
}
} // Fin de la recherche de la relation string -> fonction | Fin du For
if (carac == "exit")
{
sortir = true;
}
}
}
return 0;
}
fonction.cpp
void drawstr(Pile<double>& nomDeLaPile, sf::RenderWindow& window, Pile<string>& nomDeLaPile2)
{
sf::Text text;
sf::Font font;
text.setFont(font);
text.setString("Hello world");
text.setCharacterSize(24);
text.setColor(sf::Color::Red);
text.setStyle(sf::Text::Bold | sf::Text::Underlined);
window.draw(text);
}
My apologies for very bad English, I hope you understand anyways!

You do:
sf::Font font;
text.setFont(font);
But you don't load any font, you "set" an empty font...
Try something like that before:
if (!font.loadFromFile("arial.ttf"))
{
// error
}
But you shouldn't do that in the drawing function.
Font has to be loaded once when starting the application.

From the SFML tutorial:
Note that SFML won't load your system fonts automatically, i.e.
font.loadFromFile("Courier New") won't work. First because SFML
requires file names, not font names, and secondly because SFML doesn't
have a magic access to your system's font folder. So, if you want to
load a font, you need to have the font file with your application,
like other resources (images, sounds, ...).
SFML does not provide a default font, or an font for that matter.
When you created a Font object using:
sf::Font font;
it is an empty font. What you need to do is download a font from a website, such as http://www.dafont.com/ or find where the font files are on your computer.
Then you should load the font (from the same SFML tutorial):
sf::Font font;
if (!font.loadFromFile("arial.ttf"))
{
// error...
}

Related

Visual studio compiles but no .exe is created

I am trying to make a telemetry software for a college project. I am new to C++ as I am more used to Python. I followed a few tutorials and asked help from GPT3 to make it.
// Importation des librairies
#include "telemetry.h"
#include <QApplication>
#include <QMainWindow>
#include <QTabWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QStandardItemModel>
#include <QTableView>
// Structure pour stocker les données de télémétrie
struct TelemetryData {
double time;
double distance;
double speed;
double acceleration;
double acceleratorPressure;
double brakePressure;
double gpsPositionX;
double gpsPositionY;
};
//----------------------------------------------------------------------------- Main ------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
// ---------- Création des différents affichages, boutons et onglets --------
QApplication app(argc, argv);
// Créer la fenêtre principale de l'application
QMainWindow window;
window.setWindowTitle("Télémétrie");
// Créer le layout principal de la fenêtre
QWidget* centralWidget = new QWidget(&window);
QVBoxLayout* mainLayout = new QVBoxLayout(centralWidget);
window.setCentralWidget(centralWidget);
// Créer le widget QTabWidget et l'ajouter à l'interface utilisateur
QTabWidget* tabWidget = new QTabWidget(centralWidget);
mainLayout->addWidget(tabWidget);
// Créer le premier onglet affichant le graphique de pression d'accélérateur et de frein
QWidget* firstTab = new QWidget();
QVBoxLayout* firstTabLayout = new QVBoxLayout(firstTab);
// Créer le graphe de pression d'accélérateur et de frein
QCustomPlot* pressureGraph = new QCustomPlot(firstTab);
pressureGraph->addGraph();
pressureGraph->addGraph();
pressureGraph->graph(0)->setPen(QPen(Qt::green));
pressureGraph->graph(1)->setPen(QPen(Qt::red));
pressureGraph->xAxis->setLabel("Temps (ms)");
pressureGraph->yAxis->setLabel("Pression (bars)");
pressureGraph->yAxis->setRange(0, 1);
firstTabLayout->addWidget(pressureGraph);
// Créer les boutons de contrôle du graphe de pression d'accélérateur et de frein
QPushButton* pauseButton = new QPushButton("Mettre en pause", firstTab);
QPushButton* nextButton = new QPushButton("Milliseconde suivante", firstTab);
QPushButton* previousButton = new QPushButton("Milliseconde précédente", firstTab);
QPushButton* forwardButton = new QPushButton("Avancer x3", firstTab);
QPushButton* backwardButton = new QPushButton("Reculer x3", firstTab);
firstTabLayout->addWidget(pauseButton);
firstTabLayout->addWidget(nextButton);
firstTabLayout->addWidget(previousButton);
firstTabLayout->addWidget(forwardButton);
firstTabLayout->addWidget(backwardButton);
// Ajouter l'onglet au widget QTabWidget
tabWidget->addTab(firstTab, "Graphique de pression d'accélérateur et de frein");
// Créer le deuxième onglet affichant un tableau de données de télémétrie
QWidget* secondTab = new QWidget();
QVBoxLayout* secondTabLayout = new QVBoxLayout(secondTab);
// Créer le modèle de données et le tableau
QStandardItemModel* model = new QStandardItemModel(0, 9, secondTab);
model->setHeaderData(0, Qt::Horizontal, "Temps (ms)");
model->setHeaderData(1, Qt::Horizontal, "Distance (m)");
model->setHeaderData(2, Qt::Horizontal, "Vitesse (m/s)");
model->setHeaderData(3, Qt::Horizontal, "Accélération (m/s^2)");
model->setHeaderData(4, Qt::Horizontal, "Pression d'accélérateur (bars)");
model->setHeaderData(5, Qt::Horizontal, "Pression de frein (bars)");
model->setHeaderData(6, Qt::Horizontal, "Position GPS X (m)");
model->setHeaderData(7, Qt::Horizontal, "Position GPS Y (m)");
//Créer l'onglet secondaire
QTableView* tableView = new QTableView(secondTab);
tableView->setModel(model);
secondTabLayout->addWidget(tableView);
// Ajouter l'onglet au widget QTabWidget
tabWidget->addTab(secondTab, "Données de télémétrie");
// Créer le bouton permettant de changer d'onglet
QPushButton* switchTabButton = new QPushButton("Changer d'onglet", centralWidget);
mainLayout->addWidget(switchTabButton);
// Connecter le signal clicked() du bouton à un slot qui changera l'onglet sélectionné dans le widget QTabWidget
QObject::connect(switchTabButton, &QPushButton::clicked, [&tabWidget]() {
int currentIndex = tabWidget->currentIndex();
int newIndex = (currentIndex + 1) % tabWidget->count();
tabWidget->setCurrentIndex(newIndex);
});
// --------------------- Ouverture du Fichier -------------------
// Ouvrir le fichier de données de télémétrie en lecture
QFile file("telemetry.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
// Afficher une erreur si le fichier ne peut pas être ouvert
QMessageBox::critical(nullptr, "Erreur", "Impossible d'ouvrir le fichier de données de télémétrie");
return -1;
}
// Collecter les données de télémétrie depuis le fichier
QTextStream in(&file);
QVector<TelemetryData> data;
while (!in.atEnd()) {
QString line = in.readLine();
QStringList fields = line.split("\t");
if (fields.size() != 8) {
// Afficher une erreur si le nombre de champs est incorrect
QMessageBox::critical(nullptr, "Erreur", "Format de données de télémétrie incorrect");
return -1;
}
TelemetryData datum;
datum.time = fields[0].toDouble();
datum.distance = fields[1].toDouble();
datum.speed = fields[2].toDouble();
datum.acceleration = fields[3].toDouble();
datum.acceleratorPressure = fields[4].toDouble();
datum.brakePressure = fields[5].toDouble();
datum.gpsPositionX = fields[6].toDouble();
datum.gpsPositionY = fields[7].toDouble();
data.append(datum);
}
file.close();
// -------------- Affinage des affichages --------------
// Créer un objet gnuplot pour dessiner la gauge de vitesse
Gnuplot gp;
gp << "set terminal qt size 350,200 font ',14'\n";
gp << "set style data line\n";
gp << "set xrange [-1:1]\n";
gp << "set yrange [-1:1]\n";
gp << "set border 0\n";
gp << "set tics out\n";
gp << "set nokey\n";
gp << "unset colorbox\n";
gp << "set object 1 circle at 0,0 size 1.1 fc rgb 'white'\n";
gp << "set object 2 circle at 0,0 size 1 fc rgb 'black'\n";
gp << "set object 3 circle at 0,0 size 0.9 fc rgb 'red'\n";
gp << "set object 4 circle at 0,0 size 0.1 fc rgb 'black'\n";
gp << "set object 5 circle at 0,0 size 0.07 fc rgb 'white'\n";
// Créer une image du circuit vu d'en haut
QImage circuitImage("circuit.png");
QLabel* circuitLabel = new QLabel(centralWidget);
circuitLabel->setPixmap(QPixmap::fromImage(circuitImage));
circuitLabel->setScaledContents(true);
circuitLabel->setFixedSize(500, 500);
mainLayout->addWidget(circuitLabel);
// Dessiner un cercle rouge à la position de la voiture sur l'image du circuit
QGraphicsScene* circuitScene = new QGraphicsScene(circuitLabel);
QGraphicsEllipseItem* car = new QGraphicsEllipseItem(0, 0, 10, 10);
car->setBrush(QBrush(Qt::red));
circuitScene->addItem(car);
QGraphicsView* circuitView = new QGraphicsView(circuitScene, circuitLabel);
circuitView->setRenderHint(QPainter::Antialiasing);
circuitView->setRenderHint(QPainter::SmoothPixmapTransform);
circuitView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
circuitView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
circuitView->setFixedSize(500, 500);
// Créer une jauge de vitesse
QLabel* speedGauge = new QLabel(centralWidget);
speedGauge->setFixedSize(350, 200);
speedGauge->setPixmap(QPixmap::fromImage(gp.plot(QString(""), "", "", "", false).scaled(350, 200)));
mainLayout->addWidget(speedGauge);
// Afficher la fenêtre principale
mainWindow.show();
// ---------------- Fonction Temps réel ---------------
// Initialiser l'index de la donnée de télémétrie actuellement affichée
int dataIndex = 0;
// Initialiser un booléen indiquant si la lecture en temps réel est en pause
bool paused = false;
// Boucle principale de mise à jour de l'affichage en temps réel
while (true) {
// Mettre à jour le graphique de pression d'accélérateur et de frein
pressureGraph->graph(0)->addData(data[dataIndex].time, data[dataIndex].acceleratorPressure);
pressureGraph->graph(1)->addData(data[dataIndex].time, data[dataIndex].brakePressure);
pressureGraph->xAxis->setRange(data[dataIndex].time, 8, Qt::AlignRight);
pressureGraph->replot();
// Mettre à jour la jauge de vitesse
double speedRatio = data[dataIndex].speed / 140.0; // 140 km/h est la vitesse maximale
gp << "set object 4 circle at " << QString::number(speedRatio * std::sin(M_PI / 4)).toStdString()
<< "," << QString::number(-speedRatio * std::cos(M_PI / 4)).toStdString()
<< " size 0.1 fc rgb 'black'\n";
speedGauge->setPixmap(QPixmap::fromImage(gp.plot(QString(""), "", "", "", false).scaled(350, 200)));
// Mettre à jour la position de la voiture sur l'image du circuit
car->setPos(250 + data[dataIndex].gpsPositionX * 3, 250 - data[dataIndex].gpsPositionY * 3); // 250, 250 est le centre de l'image
// Mettre à jour l'affichage du tableau de données de télémétrie
for (int i = 0; i < model->rowCount(); ++i) {
model->setData(model->index(i, 0), data[i].time);
model->setData(model->index(i, 1), data[i].distance);
model->setData(model->index(i, 2), data[i].speed);
model->setData(model->index(i, 3), data[i].acceleration);
model->setData(model->index(i, 4), data[i].acceleratorPressure);
model->setData(model->index(i, 5), data[i].brakePressure);
model->setData(model->index(i, 6), data[i].gpsPositionX);
model->setData(model->index(i, 7), data[i].gpsPositionY);
}
tableView->scrollTo(model->index(dataIndex, 0));
// Attendre 1 milliseconde avant de mettre à jour à nouveau l'affichage
QThread::msleep(1);
// Si la lecture en temps réel n'est pas en pause, passer à la donnée de télémétrie suivante
if (!paused) {
++dataIndex;
}
if (dataIndex >= data.size()) {
dataIndex = 0;
}
}
There is no error and when I build the solution, it works fine, saying the operation was succesful, however when I try to debug it, no .exe is found.
Here is what I get when I build the solution :
Build started...
1>------ Build started: Project: Telemetrie_PITA, Configuration: Debug x64 ------
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
I checked the project files and it is true, there is no .exe in sight.
To verify whether the error would come from my project or my installation, I ran a simple HelloWorld project which worked perfectly fine.
Menu -> Build -> Build Solution perform.
.exe file is default located in C:\Users\DESKTOP NAME\source\repos\PROJECT NANE\PROJECT NAME\bin\Debug path.
.exe can also be forcibly deleted Anti-Virus Program.

SFML how to draw a Sprite(used as a player) on a Sprite(used as map)

I'm not familiar with the SFML environment yet, we started learning it this year at school
I'm struggling to draw a sprite on another sprite using this method
I guess this s.~Drawable(); is used to draw on another windows but i couldn't find any example to implement it anyone could redirect me to a good documentation that is easy to understands for begginers.
Thanks.
PS: I found other methods but I need to load image everytimes to change the player's sprite image and I guess this would slow down the game fps depending on the user drive
int sizeX = 1920, sizeY = 1080;
sf::RenderWindow window(sf::VideoMode(sizeX, sizeY), "Test");
window.setFramerateLimit(60); // max FPS a 60
sf::Vector2f player1(10, 10);
sf::Vector2f player2(590, 10);
sf::Sprite paddle1;
sf::Sprite paddle2;
sf::Texture t;
t.loadFromFile("Background.png");
sf::Sprite s(t);
//s.~Drawable();
// chargement du fichier .jpg dans un objet image de type Texture
sf::Texture imageBack1;
sf::Texture imageBack2;
sf::Texture imageForward1;
sf::Texture imageForward2;
sf::Texture imageLeft;
sf::Texture imageRight;
// PLayer2
sf::Texture imageBack1b;
sf::Texture imageBack2b;
sf::Texture imageForward1b;
sf::Texture imageForward2b;
sf::Texture imageLeftb;
sf::Texture imageRightb;
if (!imageBack1.loadFromFile("Back1.png"))
printf("PB de chargement de l'image !\n");
if (!imageBack2.loadFromFile("Back2.png"))
printf("PB de chargement de l'image !\n");
if (!imageForward1.loadFromFile("Forward1.png"))
printf("PB de chargement de l'image !\n");
if (!imageForward2.loadFromFile("Forward2.png"))
printf("PB de chargement de l'image !\n");
if (!imageLeft.loadFromFile("Left.png"))
printf("PB de chargement de l'image !\n");
if (!imageRight.loadFromFile("Right.png"))
printf("PB de chargement de l'image !\n");
//Player2 I guess this can be removed
if (!imageBack1b.loadFromFile("Back1b.png"))
printf("PB de chargement de l'image !\n");
if (!imageBack2b.loadFromFile("Back2b.png"))
printf("PB de chargement de l'image !\n");
if (!imageForward1b.loadFromFile("Forward1b.png"))
printf("PB de chargement de l'image !\n");
if (!imageForward2b.loadFromFile("Forward2b.png"))
printf("PB de chargement de l'image !\n");
if (!imageLeftb.loadFromFile("Leftb.png"))
printf("PB de chargement de l'image !\n");
if (!imageRightb.loadFromFile("Rightb.png"))
printf("PB de chargement de l'image !\n");
/* L’image doit être associée à un objet de type Sprite (équivalent à un rectangle) pour être dessinée. Ici , le sprite s’appelle bonhomme. Après, on ne travaille plus que sur le sprite… image ne sert plus à rien*/
paddle1.setTexture(imageBack1);
paddle2.setTexture(imageBack1);
// Start the game loop
while (window.isOpen())
{
// Poll for events
sf::Event event;
while (window.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
window.close();
// Escape pressed : exit
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
window.close();
}
window.clear();
// Draw the sprites
window.draw(paddle1);
window.draw(paddle2);
window.draw(s);
window.display();
}
You could draw to a sf::RenderTexture: https://www.sfml-dev.org/documentation/2.5.1/classsf_1_1RenderTexture.php
And have this render texture be the texture of the Sprite.

Show Point cloud progressively

I've got a PCD point cloud and I want it to show progressively in a window inside a MFC application. In my dialog I have some code that opens this viewer, but for some reason, it seems that it isn't working. I am working with the PCL library.
Here's the code of the dialog
// ClavegueresDlg.cpp: archivo de implementación
//
#include "stdafx.h"
#include "Clavegueres.h"
#include "ClavegueresDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
//#define new DEBUG_NEW
#endif
// Cuadro de diálogo CAboutDlg utilizado para el comando Acerca de
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Datos del cuadro de diálogo
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // Compatibilidad con DDX/DDV
// Implementación
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// Cuadro de diálogo de CClavegueresDlg
CClavegueresDlg::CClavegueresDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CClavegueresDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CClavegueresDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CClavegueresDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON2, &CClavegueresDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON1, &CClavegueresDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
// Controladores de mensaje de CClavegueresDlg
BOOL CClavegueresDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Agregar el elemento de menú "Acerca de..." al menú del sistema.
// IDM_ABOUTBOX debe estar en el intervalo de comandos del sistema.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Establecer el icono para este cuadro de diálogo. El marco de trabajo realiza esta operación
// automáticamente cuando la ventana principal de la aplicación no es un cuadro de diálogo
SetIcon(m_hIcon, TRUE); // Establecer icono grande
SetIcon(m_hIcon, FALSE); // Establecer icono pequeño
// TODO: agregar aquí inicialización adicional
return TRUE; // Devuelve TRUE a menos que establezca el foco en un control
}
void CClavegueresDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// Si agrega un botón Minimizar al cuadro de diálogo, necesitará el siguiente código
// para dibujar el icono. Para aplicaciones MFC que utilicen el modelo de documentos y vistas,
// esta operación la realiza automáticamente el marco de trabajo.
void CClavegueresDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // Contexto de dispositivo para dibujo
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Centrar icono en el rectángulo de cliente
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Dibujar el icono
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// El sistema llama a esta función para obtener el cursor que se muestra mientras el usuario arrastra
// la ventana minimizada.
HCURSOR CClavegueresDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CClavegueresDlg::InitPCL()
{
if (io::loadPCDFile<PointXYZ>("C:\\Users\\avilarrubla\\Desktop\\Clavegueres\\configuracio\\InfSup.pcd", original_point_cloud) == -1) //* load the file
{
//error
}
else
{
Eigen::Matrix4f scale_trf = Eigen::Matrix4f::Identity();
float fl_scale = 3;
scale_trf(0, 0) = fl_scale; scale_trf(1, 1) = fl_scale; scale_trf(2, 2) = fl_scale;
transformPointCloud(original_point_cloud, point_cloud, scale_trf);
//color = PointCloud<PointXYZRGB>();
//copyPointCloud(point_cloud, color);
vamos_borrar = point_cloud.begin();
point_cloud_anadir = PointCloud<PointXYZ>::Ptr();
cuantos = point_cloud.points.size();
tenemos = 0;
viewer = visualization::PCLVisualizer("", false);
viewer.setBackgroundColor(0.94, 0.1, 0.1);
VisualiserRenderer = vtkRenderer::New();
InteractionVisualiserWindow = vtkRenderWindowInteractor::New();
VisualiserWindow = viewer.getRenderWindow();
/*
InteractionVisualiserWindow->RemoveObservers(vtkCommand::LeftButtonPressEvent);
InteractionVisualiserWindow->RemoveObservers(vtkCommand::RightButtonPressEvent);
InteractionVisualiserWindow->RemoveObservers(vtkCommand::MiddleButtonPressEvent);
InteractionVisualiserWindow->RemoveObservers(vtkCommand::MouseWheelBackwardEvent);
InteractionVisualiserWindow->RemoveObservers(vtkCommand::MouseWheelForwardEvent);
*/
LPRECT rect = new CRect;
CStatic *pclStatic = new CStatic();
pclStatic = (CStatic*)GetDlgItem(IDC_VISTA3D);
VisualiserWindow->SetParentId(pclStatic->m_hWnd);
//VisualiserWindow->SetSize(rect->right - rect->left, rect->bottom - rect->top);
VisualiserWindow->SetSize(0, 0);
//VisualiserWindow->SetPosition(10, 10);
InteractionVisualiserWindow->SetRenderWindow(VisualiserWindow);
VisualiserWindow->Render();
InteractionVisualiserWindow->Render();
//single_color = visualization::PointCloudColorHandlerCustom<PointXYZ>(point_cloud_anadir, 10, 255, 10);
SetTimer(1, 10, NULL);
}
}
void CClavegueresDlg::OnTimer(UINT_PTR nIDEvent)
{
viewer.removePointCloud("point_cloud_anadir");
viewer.removeAllShapes();
if (point_cloud_anadir->points.size() < cuantos){
point_cloud_anadir->points.resize(point_cloud_anadir->points.size() + 1);
point_cloud_anadir->points[tenemos].x = (*vamos_borrar).x;
point_cloud_anadir->points[tenemos].y = (*vamos_borrar).y;
point_cloud_anadir->points[tenemos].z = (*vamos_borrar).z;
++vamos_borrar;
++tenemos;
}
viewer.addPointCloud<PointXYZ>(point_cloud_anadir, "sample cloud");
viewer.setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");
CDialogEx::OnTimer(nIDEvent);
}
void CClavegueresDlg::OnBnClickedButton2()
{
// TODO: Agregue aquí su código de controlador de notificación de control
//visualization::PCLVisualizer viewer("", false);
KillTimer(1);
if (!viewer.wasStopped()){
viewer.~PCLVisualizer();
viewer.close();
}
}
void CClavegueresDlg::OnBnClickedButton1()
{
// TODO: Agregue aquí su código de controlador de notificación de control
InitPCL();
}
Button1 is a button that when clicked should begin to show the point cloud and Button2 should stop it. The important code is the InitPCL() and the timer code. The first one initializes the viewer and the Timer inserts into the viewer a point every 10ms. Is there something wrong? How should I change this in order to work?
You should have written what exactly does not work, but I guess you simply forgot ON_WM_TIMER() in the message map and therefore OnTimer is never called.
BEGIN_MESSAGE_MAP(CClavegueresDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_TIMER() // <<<<<<<<<<<<<<< add this line
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON2, &CClavegueresDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON1, &CClavegueresDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
In the declaration of CClavegueresDlg add this:
void OnTimer(UINT_PTR nIDEvent);
You could have found out this yourself by using the debugger.
There may be other issues related to the PCL.

Unhandled exception at 0x71002A95 (SDL2_ttf.dll)

I've been writing some rudimentary code in C++ with the SDL2 library. It was working flawlessly, but I needed to print some text on screen, and to do that, I had to download the SDL2 TTF library. I installed it just like I did with SDL2. I tried to simply print a word, but once I compile the code, Visual Studio says the following:
Unhandled exception at 0x71002A95 (SDL2_ttf.dll) in nuevo proyecto.exe:
0xC0000005: Access violation reading location 0x00000000.
And the program just doesn't work, it's frozen in a white screen (it worked with no problems before I tried to use the TTF library). What can I do? Thanks in advance. Here's my code:
#include "stdafx.h"
#include <SDL.h>
#include <SDL_ttf.h>
#include <string>
SDL_Window * ventana;
SDL_Surface * superficie;
SDL_Surface * alpha;
SDL_Surface * renderizar;
SDL_Surface * texto;
bool inicia = false, cierra=false;
SDL_Point mouse;
TTF_Font *fuente = TTF_OpenFont("arial.ttf", 20);
char* palabras="hola";
SDL_Color color = { 0, 0, 0, 0 };
int controles(){
SDL_GetMouseState(&mouse.x,&mouse.y);
return 0;
}
int graficos(char *archivo){ //la primera vez inicia ventana
//el argumento es el nombre del bmp a renderizar
if (inicia == false){ ventana = SDL_CreateWindow("ventana", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0); } //abre ventana solo una vez
inicia = true; // no permite que se abra mas de una vez la ventana
superficie = SDL_GetWindowSurface(ventana);
alpha = SDL_LoadBMP("alpha.bmp");
texto = TTF_RenderText_Solid(fuente, palabras, color);
renderizar = SDL_LoadBMP(archivo);
SDL_Rect rectangulo = { 0, 0, 640, 480 };
SDL_Rect rrenderizar = { mouse.x, mouse.y, 4, 4 };
SDL_Rect rtexto = { 0, 0, 60, 60 };
SDL_BlitSurface(alpha, NULL, superficie, &rectangulo);
SDL_BlitSurface(renderizar, NULL, superficie, &rrenderizar);
SDL_BlitSurface(texto, NULL, superficie, &rtexto);
SDL_UpdateWindowSurface(ventana);
return 0;
}
int main(int argc, char **argv)
{
TTF_Init();
SDL_Init(SDL_INIT_VIDEO);
SDL_Event evento;
while (!cierra){
SDL_PollEvent(&evento);
switch (evento.type){
case SDL_QUIT:cierra = true; break;
}
//programa aqui abajo
controles();
graficos("hw.bmp");
}
TTF_Quit();
SDL_Quit();
return 0;
}
PS: I do have the DLL's, fonts and other files in the Debug folder.
According to SDL_TTF Documentation:
int TTF_Init()
Initialize the truetype font API. This must be called
before using other functions in this library, except TTF_WasInit. SDL
does not have to be initialized before this call.
You call TTF_OpenFont before calling TTF_Init when declaring your font variable. Instead you should do:
TTF_Font* fuente = NULL;
int main()
{
TTF_Init();
fuente = TTF_OpenFont("arial.ttf", 20);
...
}

Event management in C + +

I tried to use event management in C + +,
I joined the SDL library in VS and in my example,
here is my code:
#include "SDL/SDL.h"
int main(int argc, char *argv[])
{
SDL_Surface *ecran = NULL;
SDL_Event event; /* La variable contenant l'événement */
int continuer = 1; /* Notre booléen pour la boucle */
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
SDL_WM_SetCaption("Gestion des événements en SDL", NULL);
while (continuer) /* TANT QUE la variable ne vaut pas 0 */
{
SDL_WaitEvent(&event); /* On attend un événement qu'on récupère dans event */
switch(event.type) /* On teste le type d'événement */
{
case SDL_QUIT: /* Si c'est un événement QUITTER */
continuer = 0; /* On met le booléen à 0, donc la boucle va s'arrêter */
break;
}
}
SDL_Quit();
return EXIT_SUCCESS;
}
No error in the code but after compiling I got an error:
LINK: fatal error LNK1561: entry point must be defined
Not sure if this is the same issue that you have, but I recall looking at this just a day or two ago!:
Quote:
There's something wrong with your project's settings. Did you actually create a Console Application? I think that you have created a Win32 Project instead of a Console. Do this:
Right click on project name -> Properties -> Expand Linker tab -> System -> SubSystem: make sure that it is Console (/SUBSYSTEM:CONSOLE).
Otherwise, re-create the project, but when you create it, make sure that you select Win32 Console Application.
link
Looks like you have the same issue here...
If I remember correctly, there was something in the SDL which wraps your main() function: In the SDL-header, there is a line
#define main some_other_name
and then, somewhere in the library, there is a main() implementation, which calls some_other_name().
If I read the symptoms correctly, you are not statically linking the sdl library, so that the linker does not see the main() definition inside SDL, only the function some_other_name() which you have defined.