Page 1 of 1

Qt MapEditor[HELP]

Posted: Fri Jul 23, 2010 8:46 pm
by WSPSNIPER
ok i went with opengl instead of sfml and everything was going great and rendering fine until i added the second window and now only the window i just added renders the image and the other window dosent... no matter what! even if i load a different image for it it just renders white squares. would this have anything to do with qt. i have a QMainWindow and 2 QGLWidgets ( i made classes that inherit from them ) the glWidgets are childern windows of the main window. do you know why this is happening???? ill post my image code

Code: Select all

#ifndef IMAGE_H
#define IMAGE_H
#include "Windows.h"
#include <QImage>
#include <gl/gl.h>
struct TileRect;
class Image
{
public:
    Image(QString name);
    Image();
    ~Image();

    void Load(QString name);
    void Render();

    QRect& GetRect() const;
    QString& GetImageName() const;
    int GetX() const;
    int GetY() const;

    void SetClip(int x, int y, int w = 32, int h = 32)
    {
        m_clipRect.setRect(x,y,w,h);
        m_position.setRect(x,y,w,h);
    }

    void SetPosition(int x, int y);

private:
    QRect m_clipRect;
    QRect m_position;
    GLuint m_texture;

    QImage image;

};

#endif // IMAGE_H

Code: Select all

#include "Image.h"
#include <QColor>
#include <QRgb>
#include <QFile>
#include <QGLWidget>

Image::Image(QString name)
{
    image.createMaskFromColor(QColor(255, 0, 255).rgb());
    Load(name);
}
Image::Image()
{
    image.createMaskFromColor(QColor(255, 0, 255).rgb());
}

Image::~Image()
{
    if(glIsTexture(m_texture)) glDeleteTextures(1, &m_texture);
}

void Image::Load(QString name)
{
    QImage temp;
    if(!temp.load(name))
    {
        QFile file("log.txt"); file.open(QIODevice::WriteOnly); file.write("not loaded"); file.close();
    }
    image = QGLWidget::convertToGLFormat(temp);
    glGenTextures(1, &m_texture);

    glBindTexture(GL_TEXTURE_2D, m_texture);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

    glTexImage2D(GL_TEXTURE_2D,0,4,image.width(),image.height(),0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits());

    m_clipRect.setCoords(0, 0, image.width(), image.height());
    m_clipRect.setWidth(image.width());
    m_clipRect.setHeight(image.height());

    m_clipRect.setX(0);
    m_clipRect.setY(0);

    m_position.setCoords(0, 0, image.width(), image.height());
    m_position.setWidth(image.width());
    m_position.setHeight(image.height());


}

int Image::GetX() const
{
    return m_position.x();
}

int Image::GetY() const
{
    return m_position.y();
}

void Image::Render()
{
    //glClearColor(0.f, 1.f, 0.f, 0.f);
    glPushMatrix();
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, m_texture);

   // glTranslatef((float)GetX(),(float)GetY(),0);
   ///glColor4f(1.0f,1.0f,1.0f,Alpha);

    /// @todo fix the Render function to work... the code between glBegin and glEnd is broken :(
    /// COMPLETE
    glBegin(GL_QUADS);

        /// @todo do the Vertices
        /// COMPLETE

        glTexCoord2f(m_clipRect.x() / image.width(), m_clipRect.y() / image.height() );

        glVertex2f(m_position.left(),m_position.top());

        glTexCoord2f((m_clipRect.x() + m_clipRect.width() ) / image.width(),m_clipRect.y() / image.width() );

        glVertex2f(m_position.left(), m_position.bottom());

        glTexCoord2f((m_clipRect.x() + m_clipRect.width() ) / image.width(),(m_clipRect.y() + m_clipRect.height()) / image.height());

        glVertex2f(m_position.right() ,m_position.bottom());

        glTexCoord2f(m_clipRect.x() / image.width(), (m_clipRect.y() + m_clipRect.height()) / image.height());

        glVertex2f(m_position.right() ,m_position.top() );

    glEnd();

    glPopMatrix();

}

void Image::SetPosition(int x, int y)
{
    m_position.moveTopLeft(QPoint(x,y));
    //m_position.setCoords(x, y, x + m_position.width(), y - m_position.height());
}

if you want more code i can post it, Thanks for looking

if i cant get this to work im going back to win32 to finish this project but i love Qt sooooo much

Re: Qt MapEditor[HELP]

Posted: Sat Jul 24, 2010 5:19 am
by MrDeathNote
Are you trying to load textures after initialising the widget? Because thats a problem that i'm having, the only way i could get round it was to deallocate the widget and create a new widget passing the file path of the image to the constructor and then loading it when initialising OpenGL for the widget. I made a topic about it but no one replied so i assume no one knows how to fix it.

Re: Qt MapEditor[HELP]

Posted: Sat Jul 24, 2010 9:40 am
by WSPSNIPER
MrDeathNote wrote:Are you trying to load textures after initialising the widget? Because thats a problem that i'm having, the only way i could get round it was to deallocate the widget and create a new widget passing the file path of the image to the constructor and then loading it when initialising OpenGL for the widget. I made a topic about it but no one replied so i assume no one knows how to fix it.

omg i have had this problem for so long and that is the problem! lol thanks for the reply ill give it a shot. i posted as well and no one has responded.

Re: Qt MapEditor[HELP]

Posted: Sat Jul 24, 2010 9:53 am
by WSPSNIPER
MrDeathNote wrote:Are you trying to load textures after initialising the widget? Because thats a problem that i'm having, the only way i could get round it was to deallocate the widget and create a new widget passing the file path of the image to the constructor and then loading it when initialising OpenGL for the widget. I made a topic about it but no one replied so i assume no one knows how to fix it.

wait, i loaded the texture after i loaded the tilesheet window but it rendered there. i would think it has somthing to do with initlizing opengl twice or rendering 2 times each loop or somthing but your thought makes more sence im my case :)

Re: Qt MapEditor[HELP]

Posted: Sat Jul 24, 2010 9:55 am
by WSPSNIPER
ok i found another thing, i use a timed out repaint and if i set the timer to one millisecond for the tile window it dosent render the image either so i set both to 0 and only the tile still renders it... why is it never the map window that renders while the tile dosent lol.

Re: Qt MapEditor[HELP]

Posted: Sat Jul 24, 2010 10:17 am
by combatant936
I have 3 QGLWidgets running in my editor, and they all work fine with my image... I create the widgets for my central widget, and so it loads the image 3 times, one for each. In the class I made that inherits from QGLWidget, I just made a variable called "type" which has to do with the way it renders each widget (since one is rendering the map itself, one is for the tile choices, one is for the current tile I'm using).

For example:

Code: Select all

void cGL::draw(){
    if(type==1)
        //render as a map... the first instance I make of this class I make its type = 1
    else if(type==2)
        //render tile choices... for the second instance I create
    else if(type==3)
       //render current tile... for the last instance I create
}
This seems to work fine and if I ever want to make a new widget I just have to make its type be the next number and add another else if statement to the draw code...

I'm sure theres a wayyy better way to do this but I don't really care because it works and my editor is exactly how I need it for now.

If I want to load a new tilesheet I just change the texture to equal LoadTexture() and it loads it fine and updates each widget.. since I handle that within my central widget, I just make each gl widget's texture become the same thing.
I might be a little vague with what I've said but it's because I'm dead tired and I haven't really worked with this stuff in a long time since I don't need to at the moment.

And sorry if my post sucked and if it doesn't help at all but I just figured I'd tell you how I get my widgets to load a texture and work independently.

Re: Qt MapEditor[HELP]

Posted: Sat Jul 24, 2010 3:21 pm
by WSPSNIPER
combatant936 wrote:I have 3 QGLWidgets running in my editor, and they all work fine with my image... I create the widgets for my central widget, and so it loads the image 3 times, one for each. In the class I made that inherits from QGLWidget, I just made a variable called "type" which has to do with the way it renders each widget (since one is rendering the map itself, one is for the tile choices, one is for the current tile I'm using).

For example:

Code: Select all

void cGL::draw(){
    if(type==1)
        //render as a map... the first instance I make of this class I make its type = 1
    else if(type==2)
        //render tile choices... for the second instance I create
    else if(type==3)
       //render current tile... for the last instance I create
}
This seems to work fine and if I ever want to make a new widget I just have to make its type be the next number and add another else if statement to the draw code...

I'm sure theres a wayyy better way to do this but I don't really care because it works and my editor is exactly how I need it for now.

If I want to load a new tilesheet I just change the texture to equal LoadTexture() and it loads it fine and updates each widget.. since I handle that within my central widget, I just make each gl widget's texture become the same thing.
I might be a little vague with what I've said but it's because I'm dead tired and I haven't really worked with this stuff in a long time since I don't need to at the moment.

And sorry if my post sucked and if it doesn't help at all but I just figured I'd tell you how I get my widgets to load a texture and work independently.

thanks for the post, so what your saying is that you draw all the stuff in the main widget... i draw the stuff in each widget its self, that may be a problem

Code: Select all

#ifndef GLWINDOW_H
#define GLWINDOW_H
#include <Windows.h>
#include <gl/gl.h>
#include <QtOpenGL/QtOpenGL>
#include <QtGui>



class GLWindow :public QGLWidget
{
    Q_OBJECT
public:
    GLWindow(int timerInterval=0, QWidget *parent=0, char *name=0);
    virtual ~GLWindow();

    QTimer* GetTimer() { return m_timer; }

protected:
    virtual void initializeGL()=0;
    virtual void paintGL()=0;

    void resizeGL( int width, int height );
    void showEvent(QShowEvent*);
    void paintEvent(QPaintEvent*);
    virtual void keyPressEvent( QKeyEvent *){}
    virtual void mouseMoveEvent(QMouseEvent *){}
    virtual void mousePressEvent(QMouseEvent*){}

    virtual void timeOut(){} // dont use

    virtual void OnUpdate() = 0;


protected slots:
    virtual void timeOutSlot(){} // dont use

private:
    QTimer *m_timer;
    bool myInitialized;
};

Code: Select all

#include "GLWindow.h"

GLWindow::GLWindow(int timerInterval, QWidget *parent, char* name)
    :QGLWidget(QGLFormat(QGL::NoDepthBuffer), parent)
{
    myInitialized = false;
    m_timer = new QTimer;

    m_timer->setInterval(timerInterval);
}

GLWindow::~GLWindow()
{
    delete m_timer;
}


void GLWindow::showEvent(QShowEvent*)
{
    if (!myInitialized)
    {


        //OnInit();

        connect(m_timer, SIGNAL(timeout()), this, SLOT(repaint()));  // use this to call repaint ( and over ride the paintGL function for drawing )
        m_timer->start();

        myInitialized = true;
    }
}

void GLWindow::paintEvent(QPaintEvent*e)
{
    OnUpdate();
    QGLWidget::paintEvent(e);

}

void GLWindow::resizeGL(int width, int height)
{
    glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, width, height, 0,
    -1,1);

    glMatrixMode(GL_MODELVIEW);
}


thats how my GLWindow class looks and the 2 windows inherit from it

Re: Qt MapEditor[HELP]

Posted: Sat Jul 24, 2010 5:27 pm
by combatant936
Yeah that's basically what I did, but what is the point of making the class GLWindow inherit from QGLWidget and then make 2 other classes inherit from that? It just seems redundant... I mean unless you have a good reason to do so, but what you have in GLWindow didn't really seem like much at all for another class to inherit =P

In my editor I just made everything go into one window with multiple instances of my class that inherits from QGLWidget... but if I want to make them separate windows all I have to do instead of add them to a layout would be to just call QGLWidget::show() and they'll pop up as separate windows.

My suggestion is just to take your GLWindow class and put your rendering in there, maybe using what I use to specify what type it will be (map window, tile choices...) and then just call QGLWidget::show() wherever you make instances of the class for multiple windows. If the windows overlap then just change their positions around, since each widget has position variables relative to the screen.

Re: Qt MapEditor[HELP]

Posted: Sat Jul 24, 2010 7:06 pm
by WSPSNIPER
combatant936 wrote:Yeah that's basically what I did, but what is the point of making the class GLWindow inherit from QGLWidget and then make 2 other classes inherit from that? It just seems redundant... I mean unless you have a good reason to do so, but what you have in GLWindow didn't really seem like much at all for another class to inherit =P

In my editor I just made everything go into one window with multiple instances of my class that inherits from QGLWidget... but if I want to make them separate windows all I have to do instead of add them to a layout would be to just call QGLWidget::show() and they'll pop up as separate windows.

My suggestion is just to take your GLWindow class and put your rendering in there, maybe using what I use to specify what type it will be (map window, tile choices...) and then just call QGLWidget::show() wherever you make instances of the class for multiple windows. If the windows overlap then just change their positions around, since each widget has position variables relative to the screen.

thanks man, i still inherit but i looked into it and i was calling repaint() on a timer and i think that was messing it up because qt calls it internally so it works now. the reason i make inherited classes is because for each one i want to have a different event handling and stuff like that. i could have gone without the GLWindow and just inherited from QGLWidget but then i would have had to write the resize function 2 times lol. but i need a different event loop and stuff for each window so thats why they are that way... whatever works right? :mrgreen:

Re: Qt MapEditor[HELP]

Posted: Sat Jul 24, 2010 8:48 pm
by combatant936
WSPSNIPER wrote:whatever works right? :mrgreen:
lol yep xD