Ошибка: запрос для элемента 'display' в 'square', который имеет тип не класса 'GameBoxes :: Box <double>()' - PullRequest
0 голосов
/ 26 декабря 2018

Я пытаюсь сделать видеоигру Snake с использованием C ++ и OpenGL, чтобы я мог реализовать алгоритм машинного обучения, чтобы играть в нее.

#include <stdio.h>
#include <GL/glut.h>
#include <iostream>

namespace GameBoxes
{
    template<class T>
    class Box
    {
    public:
        Box(); //Initialize with a square size of 10 in center and color white.

        void display(void);

    private:
        T colorBlue;
        T colorRed;
        T colorGreen;
        T vertex1Pos1;
        T vertex1Pos2;
        T thirdForm1;
        T vertex2Pos1;
        T vertex2Pos2;
        T thirdForm2;
        T vertex3Pos1;
        T vertex3Pos2;
        T thirdForm3;
        T vertex4Pos1;
        T vertex4Pos2;
        T thirdForm4;

    };
} //GameBoxes


namespace GameBoxes
{
    template <class T>
    Box<T>::Box() : colorBlue(0.0), colorRed(0.0), colorGreen(0.0), vertex1Pos1(2.0),
                    vertex1Pos2(4.0), thirdForm1(0.0), vertex2Pos1(8.0), vertex2Pos2(4.0),
                    thirdForm2(0.0), vertex3Pos1(8.0), vertex3Pos2(6.0), thirdForm3(0.0),
                    vertex4Pos1(2.0), vertex4Pos2(6.0), thirdForm4(0.0)
    {
    }

    template <class T>
    void Box<T>::display(void)
    {
        glClear( GL_COLOR_BUFFER_BIT);
        glColor3f(colorBlue, colorRed, colorGreen);
        glBegin(GL_POLYGON);
         glVertex3f(vertex1Pos1, vertex1Pos2, thirdForm1);
         glVertex3f(vertex2Pos1, vertex2Pos2, thirdForm2);
         glVertex3f(vertex3Pos1, vertex3Pos2, thirdForm3);
         glVertex3f(vertex4Pos1, vertex4Pos2, thirdForm4);
        glEnd();
        glFlush();
    }
} // GameBoxes

int main(int argc, char **argv)
{
    printf("Hello World\n");
    glutInit(&argc, argv);

    int windowPos1, windowPos2, windowSize1, windowSize2;
    std::cout << "Please enter WinPos1, WinPos2, WinSize1 and WinSize2\n";
    std::cin  >> windowPos1 >> windowPos2 >> windowSize1, windowSize2;

    glutInitDisplayMode ( GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowPosition(windowPos1, windowPos2);
    glutInitWindowSize(windowSize1, windowSize2);
    glutCreateWindow ("square");

    glClearColor(0.0, 0.0, 0.0, 0.0);       // black background
    glMatrixMode(GL_PROJECTION);        // setup viewing projection
    glLoadIdentity();               // start with identity matrix
    glOrtho(0.0, 10.0, 0.0, 10.0, -1.0, 1.0);   // setup 10x10x2 viewing world

    GameBoxes::Box<double> square();
    glutDisplayFunc(square.display);
    glutMainLoop();

    return 0;
};

Это дает мне ошибку, указанную в названии.

Код отлично работает, когда я жестко кодирую все переменные и удаляю void display (void) из класса.

Я, честно говоря, не понимаю, почему функция display внутри класса вызывает так многопроблемы.Я собираюсь попытаться сделать это функцией друга.

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Даже если вы исправите неправильное объявление square (должно быть GameBoxes::Box<double> square, обратите внимание на отсутствие скобок), вы не сможете передать указатель на функцию-член C ++ в API, который ожидает функцию Cуказатель.

Вам нужно будет написать thunk , который будет использоваться в качестве обычного указателя функции, такого как lambda без захвата или статическая функция-член.

Если вы используете FreeGLUT, вы можете использовать glutSetWindowData() / glutGetWindowData(), чтобы установить, какой экземпляр класса следует использовать для каждого окна, и захватывать + приводить в thunk:

glutSetWindowData( &square );
glutDisplayFunc( []()
{
    auto instance = static_cast< GameBoxes::Box<double>* >( glutGetWindowData() );
    instance->display();
} );

Все вместе:

#include <iostream>
#include <GL/freeglut.h>

namespace GameBoxes
{
template<class T>
class Box
{
public:
    void display( void );
};
} //GameBoxes

namespace GameBoxes
{
template <class T>
void Box<T>::display( void )
{
    glClearColor( 0.0, 0.0, 0.0, 0.0 );       // black background
    glClear( GL_COLOR_BUFFER_BIT );
    glColor3f( 0.2, 0.2, 0.2 );
    glBegin( GL_TRIANGLES );
    glVertex2f( -0.5, -0.5 );
    glVertex2f(  0.5, -0.5 );
    glVertex2f(  0.0,  0.5 );
    glEnd();
    glutSwapBuffers();
}
} // GameBoxes

int main( int argc, char **argv )
{
    glutInit( &argc, argv );

    int windowPos1 = 0, windowPos2 = 0, windowSize1 = 400, windowSize2 = 400;
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutInitWindowPosition( windowPos1, windowPos2 );
    glutInitWindowSize( windowSize1, windowSize2 );
    glutCreateWindow( "square" );

    GameBoxes::Box<double> square;

    glutSetWindowData( &square );
    glutDisplayFunc( []()
    {
        auto instance = static_cast< GameBoxes::Box<double>* >( glutGetWindowData() );
        instance->display();
    } );
    glutMainLoop();

    return 0;
};
0 голосов
/ 26 декабря 2018

Измените следующую строку ...

GameBoxes::Box<double> square();  // a func declaration, but I get it

На ...

GameBoxes::Box<double> square; // calls the default constructor anyway.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...