Display a sequence of images on a QGraphicsView/QGraphicsScene - c++

I am developing an application in which I have to display a sequence of images and draw some rectangles on it. That's why I have to chosen to display my images in a QGraphicsScene/QGraphicsView.
Before showing you my code I will detail some of the functions I have developed :
void equalizeHist_16U_linear(Mat &img, int Tolmin, int Tolmax);
and void equalizeHist_16U_linear(Mat &img, int Tolmin, int Tolmax, int x1, int x2, int y1, int y2);
=> Does the linear transformation of an image (img), on all the image,or a specified part of the image (x1->x2, y1->y2),with an upper (Tolmax) and lower (Tolmin) tolerance
void equalizeHist_16U(Mat &img); and void equalizeHist_16U(Mat &img, int x1, int x2, int y1, int y2);
=> Does the egalisation of a 16bits grayscale image, on a specified part of the image (x1->x2, y1->y2) or on all the image.
ZonePoints getZonePoints();
=> Function used to get the zone of the image on which transformations will be done (the points comes from mouse positions), returns a ZonePoints object (int xmin, xma, ymin, ymax)
QPixmap convert16uc1(const cv::Mat& source);
=> Converts an OpenCV 16bits grayscale image (Mat) to a RGB32 QPixmap imgage
I have a folder containing numerous images labelled "ImageRaw_00000.png" to "ImageRaw_02999.png". My images are 16bits grayscale, I open them using OpenCV (as Qt cannot read 16bits images), I want to do some process on it (with OpenCV), convert them to QPixmap, add a rectangle (which represents the zone) on it and display them.
I also need to display 2 images at the same time (on the first I do the transformation on the zone given by "getZonePoints", on the second I display a rectangle corresponding to the zone points). My application looks like this : PrintScreen of the application
This is what I have so far :
Class declaration :
class FenetrePrinc : public QMainWindow
{
Q_OBJECT
public:
explicit FenetrePrinc(QWidget *parent = 0);
~FenetrePrinc();
void compute_hist_16U(Mat &img, long* hist, bool cumul);
void equalizeHist_16U(Mat &img, int x1, int x2, int y1, int y2);
void equalizeHist_16U(Mat &img);
void equalizeHist_16U_linear(Mat &img, int Tolmin, int Tolmax, int x1, int x2, int y1, int y2);
void equalizeHist_16U_linear(Mat &img, int Tolmin, int Tolmax);
QPixmap convert16uc1(const cv::Mat& source);
public slots:
virtual void openFile();
virtual void start();
private:
QString filename;
QGraphicsScene *scene_src, *scene_dst;
QGraphicsItem *item_rect;
QGraphicsItem *img_src, *img_dst;
VideoCapture sequence;
Mat src, dst;
bool transfo_lineaire;
bool coupling;
int Tolmin, Tolmax;
int impsec;
ZonePoints zpoints;
};
Class definition :
FenetrePrinc::FenetrePrinc(QWidget *parent) : QMainWindow(parent), ui(new Ui::FenetrePrinc)
{
scene_src = new QGraphicsScene();
img_src = scene_src->addPixmap(QPixmap("vide.jpg"));
img_src->setZValue(1);
ui->view_src->setScene(scene_src);
scene_dst = new QGraphicsScene();
img_dst = scene_dst->addPixmap(QPixmap("vide.jpg"));
img_dst->setZValue(1);
ui->view_dst->setScene(scene_dst);
}
void FenetrePrinc::openFile()
{
filename = QFileDialog::getOpenFileName(this, tr("Open Video file"), "C:/", tr("Image Files (*.png)"));
sequence.open(filename.toStdString());
if(!sequence.isOpened())
ui->buttonStart->setEnabled(false);
else
ui->buttonStart->setEnabled(true);
}
void FenetrePrinc::start()
{
char key;
for(;;)
{
sequence >> src;
sequence >> dst;
if(src.empty() || dst.empty())
{
cout << "End of sequence" << endl;
break;
} zpoints = getZonePoints();
key = (char)waitKey(1000);
if(transfo_lineaire)
{
equalizeHist_16U_linear(src, Tolmin, Tolmax, zpoints.xmin, zpoints.xmax, zpoints.ymin, zpoints.ymax);
equalizeHist_16U_linear(dst, Tolmin, Tolmax);
}
else
{
equalizeHist_16U(src, zpoints.xmin, zpoints.xmax, zpoints.ymin, zpoints.ymax);
equalizeHist_16U(dst);
}
scene_src->removeItem(img_src);
img_src = scene_src->addPixmap( convert16uc1(src));
img_src->setZValue(1);
scene_dst->removeItem(img_dst);
img_dst = scene_dst->addPixmap( convert16uc1(dst));
img_dst->setZValue(1);
scene_dst->removeItem(item_rect);
item_rect = scene_dst->addRect(zpoints.xmin, zpoints.ymin, zpoints.xmax-zpoints.xmin+1, zpoints.ymax-zpoints.ymin+1, QPen(Qt::red, 2, Qt::SolidLine));
item_rect->setZValue(2);
if(key == 'q' || key == 'Q' || key == 27)
break;
}
}
I had done an working application with the same behavior in which I did not used Qt, I used OpenCV for the image processing and the display. I tried to use the same technique :
Mat img;
VideoCapture sequence;
sequence.open(filename.toStdString());
for(;;)
{
sequence >> img;
... //Process images
... //Display images
}
But it does not work. Only the last image and rectangle is displayed. I guess the technique is similar with Qt but I cannot find examples of code
Thank you in advance

I found a way to do what I want, in the end it is really simple.
I used a timer and signal/slot mechanism.
My new class declaration is the following :
class FenetrePrinc : public QMainWindow
{
Q_OBJECT
public:
explicit FenetrePrinc(QWidget *parent = 0);
~FenetrePrinc();
void compute_hist_16U(Mat &img, long* hist, bool cumul);
void equalizeHist_16U(Mat &img, int x1, int x2, int y1, int y2);
void equalizeHist_16U(Mat &img);
void equalizeHist_16U_linear(Mat &img, int Tolmin, int Tolmax, int x1, int x2, int y1, int y2);
void equalizeHist_16U_linear(Mat &img, int Tolmin, int Tolmax);
QPixmap convert16uc1(const cv::Mat& source);
public slots:
virtual void openFile();
virtual void start();
virtual void tick(); //Added a 'tick()' slot
private:
QString filename;
QGraphicsScene *scene_src, *scene_dst;
QGraphicsItem *item_rect;
QGraphicsItem *img_src, *img_dst;
VideoCapture sequence, sequence2; //Declared a 2nd sequence
//If there's only 1 sequence, both images will be the same
Mat src, dst;
QTimer *timer //Added a QTimer
bool transfo_lineaire;
bool coupling;
int Tolmin, Tolmax;
int impsec;
ZonePoints zpoints;
};
Class definition :
FenetrePrinc::FenetrePrinc(QWidget *parent) : QMainWindow(parent), ui(new Ui::FenetrePrinc)
{
scene_src = new QGraphicsScene();
img_src = scene_src->addPixmap(QPixmap("vide.jpg"));
img_src->setZValue(1);
ui->view_src->setScene(scene_src);
scene_dst = new QGraphicsScene();
img_dst = scene_dst->addPixmap(QPixmap("vide.jpg"));
img_dst->setZValue(1);
ui->view_dst->setScene(scene_dst);
timer = new QTimer(this); //timer instantiation
}
void FenetrePrinc::openFile()
{
filename = QFileDialog::getOpenFileName(this, tr("Open Video file"), "C:/", tr("Image Files (*.png)"));
sequence.open(filename.toStdString());
sequence2.open(filename.toStdString());
if(!sequence.isOpened())
ui->buttonStart->setEnabled(false);
else
ui->buttonStart->setEnabled(true);
}
void FenetrePrinc::start()
{
connect(timer, SIGNAL(timeout()), this, SLOT(tick()));
timer->start(1000/impsec);
}
void FenetrePrinc::tick()
{
char key;
int i=0;
sequence >> src;
sequence2 >> dst;
if(src.empty() || dst.empty())
{
stop_timer();
}
zpoints = mgaze->getZonePoints();
zpoints = mgaze->applyOFFSET(zpoints);
zpoints = mgaze->fixZonePoints(zpoints);
if(transfo_lineaire)
{
equalizeHist_16U_linear(src, Tolmin, Tolmax, zpoints.xmin, zpoints.xmax, zpoints.ymin, zpoints.ymax);
equalizeHist_16U_linear(dst, Tolmin, Tolmax);
}
else
{
equalizeHist_16U(src, zpoints.xmin, zpoints.xmax, zpoints.ymin, zpoints.ymax);
equalizeHist_16U(dst);
}
scene_src->removeItem(img_src);
img_src = scene_src->addPixmap(convert16uc1(src));
img_src->setZValue(1);
scene_dst->removeItem(img_dst);
img_dst = scene_dst->addPixmap(convert16uc1(dst));
img_dst->setZValue(1);
scene_dst->removeItem(item_rect);
item_rect = scene_dst->addRect(zpoints.xmin, zpoints.ymin, zpoints.xmax-zpoints.xmin+1, zpoints.ymax-zpoints.ymin+1, QPen(Qt::red, 2, Qt::SolidLine));
item_rect->setZValue(2);
}
This works well, I just have to create a 'stop' slot in case I want to stop the video and that'll be good

Related

How to draw a custom shaped element?

I'm currently working in an app which is essentially a pong game. The game features two paddles currently in rectangular format to ease collision detection against the ball(currently square).
I'm using a "QRect" element as paddle since it provides the ".intersect" method, making it easy to check for collisions.
My implementation for a rectangular paddle is as follows:
Paddle::Paddle(int initial_x, int initial_y) {
QImage image.load(":images/paddle.png");
QRect rect = image.rect();
resetState(initial_x, initial_y);
}
I'm trying to draw an arch like paddle and hitbox, similar to what the code below provides:
QRectF rectangle(10.0, 20.0, 80.0, 60.0);
int startAngle = 30 * 16;
int spanAngle = 120 * 16;
QPainter painter(this);
painter.drawChord(rectangle, startAngle, spanAngle);
The only problem with the code above is it only works inside a paintEvent function and that won't work for me.
paddle.h
#ifndef PADDLE_H
#pragma once
#include <QImage>
#include <QRect>
class Paddle {
public:
Paddle(int, int);
~Paddle();
public:
void resetState(int, int);
void move();
void setDx(int);
void setDy(int);
QRect getRect();
QImage & getImage();
private:
QImage image;
QRect rect;
int dx;
int dy;
static const int INITIAL_X1 = 70;
static const int INITIAL_Y1 = 350;
};
#define PADDLE_H
#endif // PADDLE_H
paddle.cpp
#include <iostream>
#include "paddle.h"
Paddle::Paddle(int initial_x, int initial_y) {
dy = 0;
image.load(":images/paddle.png");
rect = image.rect();
resetState(initial_x, initial_y);
}
Paddle::~Paddle() {
std::cout << ("Paddle deleted") << std::endl;
}
void Paddle::setDy(int y) {
dy = y;
}
void Paddle::move() {
int x = rect.x();
int y = rect.top() + dy;
rect.moveTo(x, y);
}
void Paddle::resetState(int initial_x, int initial_y) {
rect.moveTo(initial_x, initial_y);
}
QRect Paddle::getRect() {
return rect;
}
QImage & Paddle::getImage() {
return image;
}
mainGame.h
#ifndef BREAKOUT_H
#pragma once
#include <QWidget>
#include <QKeyEvent>
#include <QFrame>
#include "ball.h"
#include "brick.h"
#include "paddle.h"
class Breakout : public QFrame {
Q_OBJECT
public:
Breakout(QWidget *parent = 0);
~Breakout();
signals:
void leftScoreChanged(int leftScore);
void rightScoreChanged(int rightScore);
void ballLost(int ballsLeft);
protected:
void paintEvent(QPaintEvent *);
void timerEvent(QTimerEvent *);
void keyPressEvent(QKeyEvent *);
void keyReleaseEvent(QKeyEvent *);
void drawObjects(QPainter *);
void finishGame(QPainter *, QString);
void moveObjects();
void startGame();
void pauseGame();
void stopGame();
void victory();
void validateScoreChange(int);
void checkCollision();
private:
int x;
int timerId;
int ballsLeft;
int leftScore;
int rightScore;
static const int N_OF_BRICKS = 30;
static const int DELAY = 5;
static const int TOP_EDGE = 0;
static const int LEFT_EDGE = 0;
static const int BOTTOM_EDGE = 700;
static const int RIGHT_EDGE = 1200;
Ball *ball;
Paddle *leftPaddle;
Paddle *rightPaddle;
Brick *bricks[N_OF_BRICKS];
bool gameOver;
bool gameWon;
bool gameStarted;
bool paused;
};
#define BREAKOUT_H
#endif // BREAKOUT_H
Breakout::paintEvent()
void Breakout::paintEvent(QPaintEvent *e) {
Q_UNUSED(e);
QPainter painter(this);
if (gameOver) {
finishGame(&painter, "Game lost");
} else if(gameWon) {
finishGame(&painter, "Victory");
}
else {
drawObjects(&painter);
}
QWidget::paintEvent(e);
}
From what I understand you do not want to load the QImage from a .png file but you want to draw it, if so you can use QPainter to create the image as I show below:
Paddle::Paddle(int initial_x, int initial_y) {
// draw image
QRectF rectangle(10.0, 20.0, 80.0, 60.0);
int startAngle = 30 * 16;
int spanAngle = 120 * 16;
image = QImage(QSize(100, 100), QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.drawChord(rectangle, startAngle, spanAngle);
painter.end();
dy = 0;
rect = image.rect();
resetState(initial_x, initial_y);
}

SFML sprite is a white square when making multiple textures

I am making a SFML framework, and when I use the function loadImage one time, the image loads correctly with all colors, but if I use it two times for another texture, there is only one sprite rendered and it's all white. I read that you don't want to delete the texture or the sprite or it will be white. But in this code I'm storing all the textures in a vector. Does any one know what is wrong in this function?
FM::Image FM::graphics::loadImage(const char* fileName) {
texturesindex++;
sf::Texture texture;
texture.loadFromFile(fileName);
textures.push_back(texture);
sf::Sprite sprite(textures[texturesindex]);
Image image;
image.sprite = sprite;
return image;
}
Here's all the code:
SFFM.cpp:
#include "SFFM.h"
#include <SFML/Graphics.hpp>
#include <vector>
#include <string>
int backgroundcolor[3] = { 0,0,0};
sf::RenderWindow Window(sf::VideoMode(800, 600), "MyGame");
std::vector<sf::Texture> textures;
int texturesindex = -1;
void FM::window::setWindowOptions(unsigned int Width, unsigned int Height, const char* Title, int FrameLimit) {
Window.setSize(sf::Vector2u(Width, Height));
Window.setFramerateLimit(FrameLimit);
Window.setTitle(Title);
}
void FM::window::setBackgroundColor(int r, int g, int b) {
backgroundcolor[0] = r;
backgroundcolor[1] = g;
backgroundcolor[2] = b;
}
FM::Image FM::graphics::loadImage(const char* fileName) {
texturesindex++;
sf::Texture texture;
texture.loadFromFile(fileName);
textures.push_back(texture);
sf::Sprite sprite(textures[texturesindex]);
Image image;
image.sprite = sprite;
return image;
}
void FM::graphics::drawImage(Image image, int x, int y, int scalex, int scaley, int rotation) {
image.sprite.setPosition(x, -y);
image.sprite.setRotation(rotation);
image.sprite.setScale(sf::Vector2f(scalex, scaley));
Window.draw(image.sprite);
}
void FM::graphics::drawImage(Image image, int x, int y, int scalex, int scaley) {
image.sprite.setPosition(x, -y);
image.sprite.setScale(sf::Vector2f(scalex, scaley));
Window.draw(image.sprite);
}
void FM::graphics::drawImage(Image image, int x, int y) {
image.sprite.setPosition(x, -y);
Window.draw(image.sprite);
}
int main()
{
FM::Start();
while (Window.isOpen())
{
sf::Event event;
while (Window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
Window.close();
else if (event.type == sf::Event::Resized)
{
Window.setView(sf::View(sf::FloatRect(0, 0, event.size.width, event.size.height)));
}
}
Window.clear(sf::Color(backgroundcolor[0], backgroundcolor[1], backgroundcolor[2]));
FM::Update();
Window.display();
}
return 0;
}
SFFM.h:
#pragma once
#include <SFML/Graphics.hpp>
namespace FM
{
void Update();
void Start();
class window {
public:
static void setWindowOptions(unsigned int Width, unsigned int Height, const char * Title, int FrameLimit);
static void setBackgroundColor(int r, int g, int b);
};
class Image {
public:
sf::Sprite sprite;
};
class graphics {
public:
static Image loadImage(const char* fileName);
static void drawImage(Image image, int x, int y, int scalex, int scaley, int rotation);
static void drawImage(Image image, int x, int y, int scalex, int scaley);
static void drawImage(Image image, int x, int y);
};
class Input {
public:
};
};
main.cpp:
#include "SFFM.h"
#include <SFML\Graphics.hpp>
FM::Image Gangster;
FM::Image Block;
int x = 0;
int y = 0;
void FM::Start() {
window::setWindowOptions(1280, 720, "Platformer", 120);
window::setBackgroundColor(0, 127, 255);
Gangster = graphics::loadImage("assets/Gangster.png");
}
void FM::Update() {
graphics::drawImage(Gangster, x, y, 5, 5);
graphics::drawImage(Block, 100, 100, 5, 5);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
y += 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
y -= 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
x += 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
x -= 1;
}
}
Here's a screenshot:
TL;DR Solutions, either:
Use a container other than std::vector<sf::Texture> - std::list<sf::Texture> or std::forward_list<sf::Texture>.
Store pointers to textures - std::vector<std::unique_ptr<sf::Texture>>.
Explanation
You store texture objects along with sprites referring them. This is correct because a spite just keeps a reference (a pointer) to its texture. This also implies that the texture address must remain unchanged during the sprite lifetime.
It looks like you did not take into account how std::vector push_back() works. A vector initally allocates some memory, and once there is no place to insert a new item, the vector allocates more memory and copies all inserted items and the new one there. So all the item addresses change.
In your case an item is a texture, its address is changed upon an isertion of another texture, so some sprite "looses" its texture. This usually results in white squares drawn.

Qthread signal emit not connecting

I have two signals that are connecting and one that will not.
I have a mainwindow widget to display images processed by a Qthread which emits the original and processed images to the my mainwidow where they are displayed, this works. I would also like to emit a frames per second calculation from this thread, but it will not connect.
all code here:
https://github.com/ianzur/qtGui_imageProcessing
mainwindow.cpp:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Timer for UI responsivness
tmrTimer = new QTimer(this);
connect(tmrTimer,SIGNAL(timeout()),this,SLOT(UpdateGUI()));
tmrTimer->start(20);
// Set initial sliders postion (for selecting ROI)
ui->SldLower->setSliderPosition(0);
ui->SldUpper->setSliderPosition(480);
ui->SldLeft->setSliderPosition(0);
ui->SldRight->setSliderPosition(640);
//connections to video processor thread
const bool c = connect(&processor,SIGNAL(outFPS(float)),ui->FPS,SLOT(setNum(float)));
connect(&processor,SIGNAL(inDisplay(QPixmap)),ui->inVideo,SLOT(setPixmap(QPixmap)));
connect(&processor,SIGNAL(outDisplay(QPixmap)),ui->outVideo,SLOT(setPixmap(QPixmap)));
qDebug() << "connected" << c;
}
Thread declaration
class ProcessorThread : public QThread
{
Q_OBJECT
public:
explicit ProcessorThread(QObject *parent = 0);
void update(QRect r, float low, float high);
int CLOCK();
float avgfps();
signals:
void inDisplay(QPixmap pixmap);
void outDisplay(QPixmap pixmap);
void outFPS(float fps);
protected:
void run() override;
private:
cv::VideoCapture capture;
//Region of interest
cv::Rect myROI;
float lowHz;
float highHz;
//float fps;
int _fpsstart=0;
float _avgfps=0;
float _fps1sec=0;
};
Thread definition
ProcessorThread::ProcessorThread(QObject *parent) : QThread(parent)
{
}
int ProcessorThread::CLOCK()
{
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return (t.tv_sec * 1000)+(t.tv_nsec*1e-6);
}
float ProcessorThread::avgfps()
{
if(CLOCK()-_fpsstart>1000)
{
_fpsstart=CLOCK();
_avgfps=0.9*_avgfps+0.1*_fps1sec;
_fps1sec=0;
}
_fps1sec++;
return _avgfps;
}
void ProcessorThread::run()
{
VideoCapture camera(0);
cv::Mat inFrame, outFrame, cropped, bit;
while(camera.isOpened() && !isInterruptionRequested())
{
camera >> inFrame;
if(inFrame.empty())
continue;
outFrame = inFrame.clone();
cropped = inFrame(myROI);
bitwise_not(cropped, bit);
bit.copyTo(outFrame(myROI));
//qDebug() << avgfps();
emit outFPS(avgfps());
emit inDisplay(QPixmap::fromImage(QImage(inFrame.data,inFrame.cols,inFrame.rows,inFrame.step,QImage::Format_RGB888).rgbSwapped()));
emit outDisplay(QPixmap::fromImage(QImage(outFrame.data,outFrame.cols,outFrame.rows,outFrame.step,QImage::Format_RGB888).rgbSwapped()));
}
}
void ProcessorThread::update(QRect r, float low, float high)
{
this->myROI = cv::Rect(r.x(),r.y(),r.width(),r.height());
this->lowHz = low;
this->highHz = high;
}
I cannot figure out why only the outFPS will not connect.
My first thoughts, looking at this line:
const bool c = connect(&processor,SIGNAL(outFPS(float)),ui->FPS, SLOT(setNum(float)));
In your UI, FPS looks like a QPlainTextEdit. I don't see a setNum() slot documented for that class. There is one for a QLabel (it takes an int or double), is that what you meant to use.

qt graphicsscene line subclass

I added a Line subclass from the GraphicsScene class , to draw a line. From MainWindow I call the line function in that class, there are no errors, but the line isn't drawn. I know this must be lack of my c++ skills. But searching didn't help me on this one. What I want is to make different classes for drawing different shapes, instead of polluting the GraphicsScene with all that code, to keep things a bit structured. But what am I doing wrong? I posted my code on github github.com/JackBerkhout/QT_Draw001
line.h
#ifndef LINE_H
#define LINE_H
#include <QMainWindow>
#include <QObject>
#include <QDebug>
#include "graphicsscene.h"
class Line: public GraphicsScene
{
public:
Line();
void drawLine(int x1, int y1, int x2, int y2);
};
#endif // LINE_H
line.cpp
#include "line.h"
Line::Line():
GraphicsScene()
{
}
void Line::drawLine(int x1, int y1, int x2, int y2)
{
// Just draw something by clicking a button
qDebug() << "line"; // This debug message is shown
QColor color;
color.setRgb(128, 0, 255);
QPen pen;
pen.setColor(color);
pen.setWidth(20);
pen.setCapStyle(Qt::RoundCap);
this->addLine(x1, y1, x2, y2, pen); // Didn't draw the line on the scene
}
graphicsscene.cpp
#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPointF>
#include <QList>
class GraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit GraphicsScene(QObject *parent = 0);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent);
virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent);
QPointF getMousePoint(void);
int getMouseX(void);
int getMouseY(void);
int getNumber(void);
void setNumber(int num);
QPointF mousePoint;
int MouseX, MouseY;
int myNumber;
signals:
void changedMousePosition(QPointF mousePoint);
void changedNumber(int myNumber);
public slots:
private:
QList <QPointF> mousePoints;
// int Number;
};
#endif // GRAPHICSSCENE_H
graphicsscene.cpp
#include "mainwindow.h"
#include "graphicsscene.h"
#include <QDebug>
GraphicsScene::GraphicsScene(QObject *parent) :
QGraphicsScene(parent)
{
this->setBackgroundBrush(Qt::black);
myNumber = 0;
// this-> ->setMouseTracking(true);
}
void GraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
// mousePoint = mouseEvent->scenePos();
// MouseX = mousePoint.x();
// MouseY = mousePoint.y();
qDebug() << Q_FUNC_INFO << mouseEvent->scenePos();
QGraphicsScene::mouseDoubleClickEvent(mouseEvent);
}
void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
mousePoint = mouseEvent->scenePos();
MouseX = mouseEvent->scenePos().x();
MouseY = mouseEvent->scenePos().y();
emit changedMousePosition(mousePoint);
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
mousePoint = mouseEvent->scenePos();
MouseX = mouseEvent->scenePos().x();
MouseY = mouseEvent->scenePos().y();
mousePoints.append(mouseEvent->scenePos());
MainWindow *mainWindow = new MainWindow();
mainWindow->Count++;
if(mousePoints.size() == 2)
{
myNumber++;
emit changedNumber(myNumber);
QColor color;
color.setRgb(128, 0, 255);
QPen pen;
pen.setColor(color);
pen.setWidth(20);
pen.setCapStyle(Qt::RoundCap);
this->addLine(mousePoints.at(0).x(), mousePoints.at(0).y(), mousePoints.at(1).x(), mousePoints.at(1).y(), pen);
mousePoints.clear();
}
QGraphicsScene::mousePressEvent(mouseEvent);
}
void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
mousePoint = mouseEvent->scenePos();
MouseX = mouseEvent->scenePos().x();
MouseY = mouseEvent->scenePos().y();
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
QPointF GraphicsScene::getMousePoint(void)
{
return mousePoint;
}
int GraphicsScene::getMouseX(void)
{
MouseX = mousePoint.x();
return mousePoint.x();
}
int GraphicsScene::getMouseY(void)
{
MouseY = mousePoint.y();
return mousePoint.y();
}
void GraphicsScene::setNumber(int num)
{
myNumber = num;
}
int GraphicsScene::getNumber(void)
{
return myNumber;
}
You are complicating too much, besides that I think you do not understand what is the purpose of the inheritance, you just have to create a function in GraphicsScene called drawLine and use it when you need it.
GraphicsScene.h
public:
void drawLine(int x1, int y1, int x2, int y2);
GraphicsScene.cpp
void GraphicsScene::drawLine(int x1, int y1, int x2, int y2)
{
QColor color;
color.setRgb(128, 0, 255);
QPen pen;
pen.setColor(color);
pen.setWidth(20);
pen.setCapStyle(Qt::RoundCap);
addLine(x1, y1, x2, y2, pen);
}
And then you call in Mainwindow:
void MainWindow::on_toolButtonDraw_clicked()
{
scene->drawLine(300, 100, 500, 300);
}
When you create a Line object you are creating a new scene and it will be drawn in that scene, so you will not see it.

Graphical output suddenly quits working with allegro based header

EDIT: ANSWERED. Upon examination of the g.drawLines in my drawBackground function, I was drawing a point, not a line. It was user error.
Our school has written a header that simplifies much of allegro 5. I'm writing a program that will use that header (GameEngineV4) to simply emulate checkers, however, I'm having some difficulty getting the board to display to the screen.
Here is my code:
#include "GameEngineV4.h"
#include <iostream>
using namespace std;
void drawBackground(GameEngineV4, const int, const int);
int main()
{
const int BOARD_WIDTH = 600;
const int BOARD_MARGIN = 100;
GameEngineV4 g; // instantiate graphic object
g.initializePanel(800,800); // initialize Window
g.setBackground(g.CYAN); // color the background
drawBackground(g, BOARD_MARGIN, BOARD_WIDTH);
//* cleanup
g.displayPanel();
system("Pause");
g.displayDelay(1.0); // wait 10 seconds
g.closePanel();
return 0;
}
void drawBackground(GameEngineV4 g, const int BOARD_MARGIN, const int BOARD_WIDTH){
g.setColor(g.BLACK);
int i = 0;
int offset = (BOARD_WIDTH / 8) * i; //Variable to hold the amount a line should be shifted from original.
for (i = 0; i < 9; i++){
offset = (BOARD_WIDTH / 8) * i;
g.drawLine(BOARD_MARGIN, BOARD_MARGIN + offset, BOARD_MARGIN, BOARD_MARGIN + offset); //Horizontal lines
g.drawLine(BOARD_MARGIN + offset, BOARD_MARGIN, BOARD_MARGIN + offset, BOARD_MARGIN); //Vertical lines
}
}
The difficulty lies somewhere in the drawBackground function. I had tested the drawBackground function first by replacing the drawLine code in the for loop with g.drawLine(50, 50 + offset, 450, 450 + offset); and the code displayed just fine then. Why would changing it to calculate using constants affect my code?
Coded and compiled in Visual Studio 2013 on Windows 7.
EDIT: Of course, it would be a bit simpler if I included the header and implementation for GameEngineV4
Here's GameEngineV4.h:
#ifndef _GameEngineV4
#define _GameEngineV4
#include <string>
#include <allegro5\allegro.h>
#include <allegro5\allegro_primitives.h> //Our primitive header file
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
using namespace std;
class GameEngineV4
{
private:
int gSleep;
int gSpeed;
bool appRunning;
ALLEGRO_COLOR colortable[32];
ALLEGRO_FONT * fonttable[32];
int keyTable[256];
int default_pen;
int default_brush;
int default_font;
int default_BGColor;
double default_thickness;
bool keyPressed;
int pressedChar;
ALLEGRO_DISPLAY *gdisplay;
public:
GameEngineV4();
//-------------------------------------------------
// Game Engine Functions
//-------------------------------------------------
// call to return last key pressed
int gameLastkey();
// call to set game speed;
void gameSetGameSpeed(int);
void gameSetSpeed(int);
// call to set game speed;
int gameGetGameSpeed();
int gameGetSpeed();
// call to set display delay;
void gameSetDisplayDelay(int);
// start game
int gameEngineMain(void);
// call to repaint window
void gameRepaint();
// creates and fills a rectangle color is index into standard color table
void fill_rect(int xl,int yl,int xr,int yr,int penColor,int brushColor);
void fill_rect(int x1,int y1,int w,int h);
// creates and fills an ellipse
void fill_ellipse(int x1 ,int y ,int w,int h,int penColor,int brushColor);
void fill_ellipse(int x1,int y1,int w,int h);
// text out string, x, y, color code
void text_out(char *,int ,int ,int);
void text_out(char *txt, int x,int y);
void text_out(LPCSTR txt,int x,int y,int clr);
void text_out(LPCSTR txt,int x,int y);
// draw line from point1(x1,y1) to point2(x2,y2)
void draw_line(int x1,int y1,int x2,int y2); // uses default color
void draw_line(int x1,int y1,int x2,int y2,int color);
// draws ellipse
void draw_ellipse(int x1,int y1,int w,int h,int penColor,int brushColor);
void draw_ellipse(int x1,int y1,int w,int h); // uses default color
// draws rectangle
void draw_rect(int x1,int y1,int w,int h,int penColor,int brushColor);
void draw_rect(int x1,int y1,int w,int h);
// sets default color
void color(int pen,int brush);
// sets default pen color
void pen_color(int pen);
// sets default brush
void brush_color(int brush);
// register call backs
void registerGameMain(void (*fun)());
void registerGameInit(void (*fun)());
void registerGameQuit(void (*fun)());
void registerGamePaint(void (*fun)());
void registerGameKeyUp(void (*fun)(int));
void registerGameKeyDown(void (*fun)(int));
void registerGameLMouse(void (*fun)(int,int,int));
void registerGameRMouse(void (*fun)(int,int,int));
void registerGameMoveMouse(void (*fun)(int,int,int));
void playBeep1();
void playBeep2();
void playBeep(float g, float s );
void playWav(char * filename, float gain, float speed, float duration);
void playWave(string filename, float gain, float speed, float duration);
int initializeAudio(int samples);
//-----------------------------------------------
// call back functions
//-----------------------------------------------
// called during initialization
void gameInit();
// called during initialization
void gameMain();
// called at exit
void gameQuit();
// called to repaint screen
void gamePaint();
// keyboard and mouse functions
void gameKeyUp(int);
void gameKeyDown(int);
void gameLMouse(int,int,int);
void gameRMouse(int,int,int);
void gameMoveMouse(int,int,int);
// initialization methods
void initColorTable();
void initFontTable();
void initKeyTable();
void GoPaint();
// Alternate Graphics functions
int initializePanel(int width, int height);
int initializePanel(int width, int height, int color);
void closePanel();
void displayPanel();
void displayDelay(double delay);
void setBackground(int color);
void setBackground(int r, int g, int b);
void setThickness(double t);
void setPenColor(int pen);
void setColor(int pen);
void setColor(int r, int g, int b);
void setBrushColor(int brush);
void setBrushColor(int r, int g, int b);
void setFont(int font);
void setFontSize(int fontSize, int flag);
void setFont(string family, int fontSize, int flag);
void drawLine(int x1, int y1, int x2, int y2);
void drawOval(int x1,int y1,int w,int h);
void drawRect(int x1,int y1,int w,int h);
void drawString(char *txt,int x,int y);
void drawString(string txt,int x,int y);
void drawARC(int x1,int y1,int r, int w,int h,float st, float dt);
void fillOval(int x1,int y1,int w,int h);
void fillRect(int x1,int y1,int w,int h);
void drawTriangle(float x1, float y1, float x2, float y2 , float x3, float y3);
void fillTriangle(float x1, float y1, float x2, float y2 , float x3, float y3);
void fillRibbon(int x1,int y1,int x2,int y2, int w);
void drawRibbon(int x1,int y1,int x2,int y2, int w);
enum color{BLACK,BLUE,CYAN,DARK_GRAY,GRAY,GREEN,
LIGHT_GRAY,MAGENTA,ORANGE,PINK,RED,WHITE,YELLOW,
MAROON,PURPLE,LIME,OLIVE,NAVY,TEAL};
};
#endif
And here's the implementation, GameEngineV4.cpp:
//-------------------------------------------------------
//-------------------------------------------------------
// GameEngine Version 4.2 - Allegro, class Based, and
// registered callbacks
// 4.1
// 4.2 Enhanced Audio
//-------------------------------------------------------
//-------------------------------------------------------
#include <iostream>
#include <string>
#include "GameEngineV4.h"
#include <allegro5\allegro.h>
#include <allegro5\allegro_primitives.h> //Our primitive header file
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5\allegro_audio.h>
#include <allegro5\allegro_acodec.h>
using namespace std;
//-------------------------------------------------------
// Definitions
//-------------------------------------------------------
#define WINDOW_WIDTH 800 // default size of game window
#define WINDOW_HEIGHT 600
#define T2SLEEP 20 // thread 2 default sleep time
#define T1SPEED 700000 // thread 1 default delay loops
//-------------------------------------------------------
// Global Variables
//-------------------------------------------------------
ALLEGRO_SAMPLE *beep1 = NULL;
ALLEGRO_SAMPLE *beep2 = NULL;
//-------------------------------------------------------
// Function pointers
//-------------------------------------------------------
void (*pGameMain) ()=NULL;
void (*pGameInit) ()=NULL;
void (*pGameQuit) ()=NULL;
void (*pGamePaint) ()=NULL;
void (*pGameKeyUp) (int)=NULL;
void (*pGameKeyDown) (int)=NULL;
void (*pGameLMouse) (int,int,int)=NULL;
void (*pGameRMouse) (int,int,int)=NULL;
void (*pGameMoveMouse) (int,int,int)=NULL;
enum KEYS{ UP, DOWN, LEFT, RIGHT};
GameEngineV4::GameEngineV4()
{
gSleep=T2SLEEP;
gSpeed=T1SPEED;
appRunning=false;
for (int i=0;i<256;i++)
keyTable[i]=0;
default_pen=0;
default_brush=0;
default_font=0;
default_BGColor=0;
default_thickness=2.0;
gdisplay = NULL;
}
int GameEngineV4::gameEngineMain(void)
{
int width = WINDOW_WIDTH;
int height = WINDOW_HEIGHT;
bool done = false;
bool redraw = true;
int pos_x = width / 2;
int pos_y = height / 2;
int FPS = 60;
bool keys[4] = {false, false, false, false};
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *timer = NULL;
if(!al_init()) //initialize Allegro
return -1;
display = al_create_display(width, height); //create our display object
if(!display) //test display object
return -1;
al_init_primitives_addon();
al_install_keyboard();
al_install_mouse();
al_init_font_addon();
al_init_ttf_addon();
al_install_audio();
al_init_acodec_addon();
al_reserve_samples(10);
beep1 = al_load_sample("beep1.ogg");
beep2 = al_load_sample("beep2.ogg");
initColorTable();
initFontTable();
initKeyTable();
gameInit();
//CreateThread(0,0,ThreadProc1,0,0,0);
//CreateThread(0,0,ThreadProc2,0,0,0);
event_queue = al_create_event_queue();
timer = al_create_timer(1.0 / gameGetSpeed());
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_mouse_event_source());
al_register_event_source(event_queue, al_get_display_event_source(display));
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_start_timer(timer);
while(!done)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
{
keyPressed=true;
pressedChar=keyTable[(int)ev.keyboard.keycode];
gameKeyDown(keyTable[(int)ev.keyboard.keycode]);
}
else if(ev.type == ALLEGRO_EVENT_KEY_UP)
{
keyPressed=true;
pressedChar=keyTable[(int)ev.keyboard.keycode];
gameKeyUp(keyTable[(int)ev.keyboard.keycode]);
}
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
{
done = true;
}
else if(ev.type == ALLEGRO_EVENT_TIMER)
{
gameMain();
redraw = true;
}else if (ev.type== ALLEGRO_EVENT_MOUSE_AXES)
{
gameMoveMouse(ev.mouse.x,ev.mouse.y,1);
}else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
{
if (ev.mouse.button & 1)
{
gameLMouse(ev.mouse.x,ev.mouse.y,1);
}
if (ev.mouse.button & 2)
{
gameRMouse(ev.mouse.x,ev.mouse.y,1);
}
}
if(redraw && al_is_event_queue_empty(event_queue))
{
redraw = false;
gamePaint();
al_flip_display();
al_clear_to_color(colortable[default_BGColor]);
}
}
al_destroy_sample(beep1);
al_destroy_sample(beep2);
al_destroy_event_queue(event_queue);
al_destroy_timer(timer);
al_destroy_display(display); //destroy our display object
return 0;
}
/*
//-------------------------------------------------------
// Additional Game Threads
//-------------------------------------------------------
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
gameMain1();
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
while(appRunning)
{
gameMain2();
GoPaint(NULL,NULL);
Sleep(gSleep);
}
return 0;
}
*/
//-------------------------------------------------------
// register callbacks and callbacks
//-------------------------------------------------------
void GameEngineV4:: registerGameMain(void (*fun)() )
{
pGameMain = fun ;
}
void GameEngineV4::gameMain()
{
if (pGameMain !=NULL) pGameMain();
}
void GameEngineV4:: registerGameInit(void (*fun)() )
{
pGameInit = fun ;
}
void GameEngineV4::gameInit()
{
if (pGameInit !=NULL) pGameInit();
}
void GameEngineV4:: registerGameQuit(void (*fun)() )
{
pGameQuit = fun ;
}
void GameEngineV4::gameQuit()
{
if (pGameQuit !=NULL) pGameQuit();
}
void GameEngineV4:: registerGamePaint(void (*fun)() )
{
pGamePaint = fun ;
}
void GameEngineV4::gamePaint()
{
if (pGamePaint !=NULL) pGamePaint();
}
void GameEngineV4:: registerGameKeyUp(void (*fun)(int) )
{
pGameKeyUp = fun ;
}
void GameEngineV4::gameKeyUp(int x)
{
if (pGameKeyUp !=NULL) pGameKeyUp(x);
}
void GameEngineV4:: registerGameKeyDown(void (*fun)(int) )
{
pGameKeyDown = fun ;
}
void GameEngineV4::gameKeyDown(int x)
{
if (pGameKeyDown !=NULL) pGameKeyDown(x);
}
void GameEngineV4:: registerGameLMouse(void (*fun)(int,int,int) )
{
pGameLMouse = fun ;
}
void GameEngineV4::gameLMouse(int x, int y, int z)
{
if (pGameLMouse !=NULL) pGameLMouse(x, y, z);
}
void GameEngineV4:: registerGameRMouse(void (*fun)(int,int,int) )
{
pGameRMouse = fun ;
}
void GameEngineV4::gameRMouse(int x, int y, int z)
{
if (pGameRMouse !=NULL) pGameRMouse(x, y, z);
}
void GameEngineV4:: registerGameMoveMouse(void (*fun)(int,int,int) )
{
pGameMoveMouse = fun ;
}
void GameEngineV4::gameMoveMouse(int x, int y, int z)
{
if (pGameMoveMouse !=NULL) pGameMoveMouse(x, y, z);
}
//-------------------------------------------------------
// Pens and Brushes
//-------------------------------------------------------
void GameEngineV4::initColorTable()
{
colortable[0]=al_map_rgb(0,0,0); // black
colortable[1]=al_map_rgb(0,0,255); // blue
colortable[2]=al_map_rgb(0,255,255); // cyan /aqua
colortable[3]=al_map_rgb(96,96,96); // dark gray
colortable[4]=al_map_rgb(160,160,160); // gray
colortable[5]=al_map_rgb(0,160,0); // green
colortable[6]=al_map_rgb(192,192,192); // light gray /silver
colortable[7]=al_map_rgb(255,0,255); // magenta
colortable[8]=al_map_rgb(255,165,0); // orange
colortable[9]=al_map_rgb(255,160,203); // pink
colortable[10]=al_map_rgb(255,0,0); // red
colortable[11]=al_map_rgb(255,255,255); // white
colortable[12]=al_map_rgb(255,255,0); // yellow
colortable[13]=al_map_rgb(160,0,0); // maroon
colortable[14]=al_map_rgb(160,0,160); // purplE
colortable[15]=al_map_rgb(0,255,0); // lime
colortable[16]=al_map_rgb(160,160,0); // olive
colortable[17]=al_map_rgb(0,0,160); // navy
colortable[18]=al_map_rgb(0,160,160); // teal
}
void GameEngineV4::initFontTable()
{
fonttable[0] = al_load_font("arial.ttf", 16, 1);
fonttable[1] = al_load_font("arial.ttf", 32, 2);
fonttable[2] = al_load_font("arial.ttf", 48, 2);
}
void GameEngineV4::initKeyTable()
{
for (int i=0; i< 256;i++)
keyTable[i]=0; // zero
keyTable[84]=0x26; // keyup
keyTable[85]=0x28; // key down
keyTable[82]=0x25; // left
keyTable[83]=0x27; // right
for (int i=0; i< 26;i++)
keyTable[i+1]=i+0x41; // a-z
for (int i=0; i< 9;i++)
keyTable[i+27]=i+0x30; // 0-9
for (int i=0; i< 9;i++)
keyTable[i+37]=i+0x60; // 0-9 key pad
for (int i=0; i< 12;i++)
keyTable[i+47]=i+0x70; // F1-F12
keyTable[59]=0x1b; // escape
keyTable[61]=0x6d; // minus
keyTable[63]=0x08; // backspace
keyTable[64]=0x09; // tab
keyTable[75]=0x20; // space
keyTable[67]=0x0d; // return or enter
}
//-------------------------------------------------------
// Text Procssing
//-------------------------------------------------------
void GameEngineV4::text_out(char *txt,int x,int y,int clr)
{
al_draw_text(fonttable[default_font], colortable[clr], x, y, 0, txt);
}
void GameEngineV4::text_out(char *txt,int x,int y)
{
al_draw_text(fonttable[default_font], colortable[default_pen], x, y, 0, txt);
}
//-------------------------------------------------------
// Functions to Draw Lines and Shapes
//-------------------------------------------------------
void GameEngineV4::draw_line(int x1,int y1,int x2,int y2)
{
al_draw_line(x1, y1, x2, y2, colortable[default_pen],default_thickness);
}
void GameEngineV4::draw_line(int x1,int y1,int x2,int y2,int clr)
{
al_draw_line(x1, y1, x2, y2, colortable[clr] ,default_thickness);
}
void GameEngineV4::draw_ellipse(int x1,int y1,int w,int h,int penClr,int brushClr)
{
int w1=w/2;
int h1=h/2;
al_draw_ellipse(x1+w1, y1+h1, w1, h1, colortable[penClr], default_thickness);
}
void GameEngineV4::draw_rect(int x1,int y1,int w,int h)
{
al_draw_rectangle(x1,y1,x1+w,y1+h,colortable[default_pen],default_thickness);
}
void GameEngineV4::draw_rect(int x1,int y1,int w,int h,int penClr,int brushClr)
{
al_draw_rectangle(x1,y1,x1+w,y1+h,colortable[penClr],default_thickness);
}
void GameEngineV4::draw_ellipse(int x1,int y1,int w,int h)
{
int w1=w/2;
int h1=h/2;
al_draw_ellipse(x1, y1, w1, h1, colortable[default_pen], default_thickness);
}
void GameEngineV4::fill_ellipse(int x1,int y1,int w,int h,int penClr,int brushClr)
{
int w1=w/2;
int h1=h/2;
al_draw_filled_ellipse (x1+w1,y1+h1,w1,h1,colortable[penClr]);
}
void GameEngineV4::fill_ellipse(int x1,int y1,int w,int h)
{
int w1=w/2;
int h1=h/2;
al_draw_filled_ellipse (x1+w1,y1+h1,w1,h1,colortable[default_brush]);
}
void GameEngineV4::fill_rect(int x1,int y1,int w,int h)
{
al_draw_filled_rectangle(x1,y1,x1+w,y1+h,colortable[default_brush]);
}
void GameEngineV4::fill_rect(int x1,int y1,int w,int h,int penClr,int brushClr)
{
al_draw_filled_rectangle(x1,y1,x1+w,y1+h,colortable[penClr]);
}
void GameEngineV4::color(int pen,int brush)
{
default_pen=pen;
default_brush=brush;
}
void GameEngineV4::pen_color(int pen)
{
default_pen=pen;
}
void GameEngineV4::brush_color(int brush)
{
default_brush=brush;
}
int GameEngineV4::gameLastkey()
{
if(!keyPressed)
{
return 0;
}
else
{
keyPressed=false;
return pressedChar;
}
}
void GameEngineV4::gameSetSpeed(int x)
{
gSpeed=x;
}
void GameEngineV4::gameSetGameSpeed(int x)
{
gSpeed=x;
}
void GameEngineV4::gameSetDisplayDelay(int x)
{
gSleep=x;
}
int GameEngineV4::gameGetSpeed()
{
return gSpeed;
}
int GameEngineV4::gameGetGameSpeed()
{
return gSpeed;
}
// graphics interface
int GameEngineV4::initializePanel(int width, int height)
{
if(!al_init()) //initialize Allegro
return -1;
gdisplay = al_create_display(width, height); //create our display object
if(!gdisplay) //test display object
return -1;
al_init_primitives_addon();
al_install_keyboard();
al_install_mouse();
al_init_font_addon();
al_init_ttf_addon();
al_install_audio();
al_init_acodec_addon();
al_reserve_samples(100);
initColorTable();
initFontTable();
initKeyTable();
return 0;
}
void GameEngineV4::closePanel()
{
al_destroy_display(gdisplay); //destroy our display object
return;
}
void GameEngineV4::displayPanel()
{
al_flip_display();
}
void GameEngineV4::setBackground(int color)
{
default_BGColor =color;
al_clear_to_color(colortable[default_BGColor]);
}
void GameEngineV4::setBackground(int r, int g, int b)
{
colortable[30] =al_map_rgb(r,g,b);
default_BGColor =30;
al_clear_to_color(colortable[default_BGColor]);
}
void GameEngineV4::setThickness(double t)
{
default_thickness=t;
}
void GameEngineV4::setPenColor(int pen)
{
default_pen=pen;
}
void GameEngineV4::setColor(int clr)
{
default_pen=clr;
default_brush=clr;
}
void GameEngineV4::setColor(int r, int g, int b)
{
colortable[31] =al_map_rgb(r,g,b);
default_pen=31;
}
void GameEngineV4::setBrushColor(int brush)
{
default_brush=brush;
}
void GameEngineV4::setBrushColor(int r, int g, int b)
{
colortable[30] =al_map_rgb(r,g,b);
default_brush=30;
}
void GameEngineV4::setFont(int font)
{
default_font=font;
}
void GameEngineV4::setFontSize(int fontSize, int flag)
{
fonttable[31] = al_load_font("arial.ttf", fontSize, flag);
default_font=31;
}
void GameEngineV4::setFont(string family, int fontSize, int flag)
{
fonttable[31] = al_load_font(family.c_str(), fontSize, flag);
default_font=31;
}
void GameEngineV4::drawLine(int x1, int y1, int x2, int y2)
{
al_draw_line(x1, y1, x2, y2, colortable[default_pen] ,default_thickness);
}
void GameEngineV4::drawOval(int x1,int y1,int w,int h)
{
int w1=w/2;
int h1=h/2;
al_draw_ellipse(x1+w1, y1+h1, w1, h1, colortable[default_pen], default_thickness);
}
void GameEngineV4::drawRect(int x1,int y1,int w,int h)
{
al_draw_rectangle(x1,y1,x1+w,y1+h,colortable[default_pen],default_thickness);
}
void GameEngineV4::drawString(char *txt,int x,int y)
{
text_out(txt,x,y);
}
void GameEngineV4::drawString(string txt,int x,int y)
{
al_draw_text(fonttable[default_font], colortable[default_pen], x, y, 0, txt.c_str());
}
void GameEngineV4::fillOval(int x1,int y1,int w,int h)
{
int w1=w/2;
int h1=h/2;
al_draw_filled_ellipse (x1+w1,y1+h1,w1,h1,colortable[default_brush]);
}
void GameEngineV4::fillRect(int x1,int y1,int w,int h)
{
al_draw_filled_rectangle(x1,y1,x1+w,y1+h,colortable[default_brush]);
}
void GameEngineV4::displayDelay(double d)
{
al_rest(d);
}
void GameEngineV4::drawARC(int x1,int y1, int r, int w,int h,float st, float dt)
{
int w1=w/2;
int h1=h/2;
float dt1=3.14 * (dt*-1)/180.0;
float st1=3.14 * (st*-1)/180.0;
al_draw_arc(x1+w1,y1+h1,r,st1,dt1,colortable[default_brush],default_thickness);
}
void GameEngineV4::playBeep1()
{
al_play_sample(beep1, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
}
void GameEngineV4::playBeep2()
{
al_play_sample(beep2, 1, 0, 1 , ALLEGRO_PLAYMODE_ONCE, 0);
}
void GameEngineV4::playBeep(float g, float s )
{
al_play_sample(beep1, g, 0, s, ALLEGRO_PLAYMODE_ONCE, 0);
}
void GameEngineV4::playWav(char filename[], float gain, float speed, float duration )
{
ALLEGRO_SAMPLE *soundeffect = al_load_sample(filename);
al_play_sample(soundeffect,gain,0.0, speed, ALLEGRO_PLAYMODE_ONCE, 0);
al_rest(duration);
al_destroy_sample(soundeffect);
}
void GameEngineV4::playWave(string filename, float gain, float speed, float duration )
{
ALLEGRO_SAMPLE *soundeffect = al_load_sample(filename.c_str());
al_play_sample(soundeffect,gain,0.0, speed, ALLEGRO_PLAYMODE_ONCE, 0);
al_rest(duration);
al_destroy_sample(soundeffect);
}
// audio interface
int GameEngineV4::initializeAudio(int samples)
{
if(!al_init()) //initialize Allegro
return -1;
al_install_audio();
al_init_acodec_addon();
al_reserve_samples(samples);
return 0;
}
void GameEngineV4::drawTriangle(float x1, float y1, float x2, float y2 , float x3, float y3)
{
al_draw_triangle(x1,y1,x2,y2,x3,y3,colortable[default_pen],default_thickness);
}
void GameEngineV4::fillTriangle(float x1, float y1, float x2, float y2 , float x3, float y3)
{
al_draw_filled_triangle(x1,y1,x2,y2,x3,y3,colortable[default_brush]);
}
void GameEngineV4::fillRibbon(int x1,int y1,int x2,int y2, int w)
{
struct MyPoint
{
float x, y;
};
const size_t num_points1 = 2;
MyPoint points1[] =
{
{x1, y1},
{x2, y2}
};
al_draw_ribbon((float*)points1, sizeof(MyPoint), colortable[default_brush], w, num_points1);
}
void GameEngineV4::drawRibbon(int x1,int y1,int x2,int y2, int w)
{
fillRibbon(x1,y1,x2,y2, w);
}
EDIT: ANSWERED. See top for more info.
In my drawBackground function, I am supposed to provide the starting point of the line and the ending point of the line. I provided the same point for both the start and end point. End result, nothing displayed.