0

I'm using Visual Studio Express 2017 to work with OpenGL. My teacher provided the class with this code that worked on the lab computers which had the 2012 version installed, but on my PC it is not working. It keeps giving me 2 errors:

no instance of constructor canvas::canvas matches the argument list. E0289

This error is on the line Canvas cvs(640, 480, "my prog");

Canvas::canvas(canvas&&) cannot convert argument 3 from 'const char[7] to char*' C2664

This error is on the line if (n < 3)

Sorry, it's my first time using this site, so I pasted the entire code. It would be great if anyone could help me with this. I'm not really good with programming.

#include "stdafx.h"
#include<Windows.h>
#include<glut.h>
#include<gl/GLU.h>
#include <gl/GL.H>
#include<math.h>
#include<fstream>

void myInit(void)
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glColor3ub(1.0, 1.0, 1.0);
    glPointSize(100.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}

class Point2   //single point w/ floating point coordinates
{
public:
    Point2() { x = y = 0.0f; }
    Point2(float xx, float yy) { x = xx; y = yy; }
    void set(float xx, float yy) { x = xx; y = yy; }
    float getX() { return x; }
    float getY() { return y; }
    void draw(void)
    {
        glBegin(GL_POINTS); //draw this point
        glVertex2f((GLfloat)x, (GLfloat)y);
        glEnd();
    }
private:
    float x, y;
};

class IntRect  //aligned rectangle with integer coordinates, used for viewport
{
public:
    IntRect() { l = 0; r = 100; b = 0; t = 100; }
    IntRect(int left, int right, int bottom, int top)
    {
        l = left; r = right; b = bottom; t = top;
    }
    void set(int left, int right, int bottom, int top)
    {
        l = left; r = right; b = bottom; t = top;
    }
    void draw(void); //draw this rectangle using OpenGL
    int getL(void)
    {
        return l;
    }
    int getR(void)
    {
        return r;
    }
    int getT(void)
    {
        return t;
    }
    int getB(void)
    {
        return b;
    }

private:
    int l, r, b, t;
};

class RealRect   //simlar to IntRect but w/ floating points & used for world window
{
public:
    RealRect() { l = 0; r = 100; b = 0; t = 100; }
    RealRect(float left, float right, float bottom, float top)
    {
        l = left; r = right; b = bottom; t = top;
    }
    void set(float left, float right, float bottom, float top)
    {
        l = left; r = right; b = bottom; t = top;
    }
    float getL(void)
    {
        return l;
    }
    float getR(void)
    {
        return r;
    }
    float getT(void)
    {
        return t;
    }
    float getB(void)
    {
        return b;
    }
    void draw(void); //draw this rectangle using OpenGL
private:
    float l, r, b, t;
};
//<<End Support Classes>>>

class Canvas
{
public:
    Canvas(int width, int height, char* windowTitle); //constructor
    void setWindow(float l, float r, float b, float t);
    void setViewport(int l, int r, int b, int t);
    IntRect getViewport(void); //divulge the viewport data
    RealRect getWindow(void); // divulge the window data
    float getWindowAspectRatio(void);
    void clearScreen();
    void setBackgroundColor(float r, float g, float b);
    void setColor(float r, float g, float b);
    void lineTo(float x, float y);
    void lineTo(Point2 p);
    void moveTo(float x, float y);
    void moveTo(Point2 p);
    void moveRel(float dx, float dy);
    void turnTo(float angle);
    void turn(float angle);
    void forward(float dist, int isVisible);
    Point2 Tween(Point2 A, Point2 B, float t);
    void drawTween(Point2 A[], Point2 B[], int N, float t);


private:
    Point2 CP;         //current position in the world
    float CD;          //current direction in the world
    IntRect viewport;  //the current window
    RealRect window;   //the current viewport

};

//<<moveTo>>
//changes current point
void Canvas::moveTo(float x, float y)
{
    CP.set(x, y);
}

//<<lineTo>>
//draws a line from current point to new point
void Canvas::lineTo(float x, float y)
{
    glBegin(GL_LINES);
    glVertex2f((GLfloat)CP.getX(), (GLfloat)CP.getY());
    glVertex2f((GLfloat)x, (GLfloat)y); //draw the line
    glEnd();
    CP.set(x, y); //update current point to new point
    glFlush();
}

//<<setWindow>>
void Canvas::setWindow(float l, float r, float b, float t)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D((GLdouble)l, (GLdouble)r, (GLdouble)b, (GLdouble)t);
    window.set(l, r, b, t);
}

//<<setViewport>>
void Canvas::setViewport(int l, int r, int b, int t)
{
    glViewport(l, b, r - l, t - b);
    viewport.set(l, r, b, t);
}

IntRect Canvas::getViewport(void)
{
    return viewport;
}

RealRect Canvas::getWindow(void)
{
    return window;
}

void Canvas::clearScreen(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
}

void Canvas::setBackgroundColor(float r, float g, float b)
{
    glClearColor(r, g, b, 0.0);   //4th variable level of transparency, may need to change 
}

void Canvas::setColor(float r, float g, float b)
{
    glColor3f(r, g, b);
}

void Canvas::lineTo(Point2 p)
{
    glBegin(GL_LINES);
    glVertex2f((GLfloat)CP.getX(), (GLfloat)CP.getY());
    glVertex2f((GLfloat)p.getX(), (GLfloat)p.getY());
    glEnd();
    CP.set(p.getX(), p.getY());
    glFlush();
}

Canvas::Canvas(int width, int height, char* windowTitle)
{
    char* argv[1];  //dummy argument list for glutinit()
    char dummyString[8];
    argv[0] = dummyString;  //hook up the pointer
    int argc = 1;

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(width, height);
    glutInitWindowPosition(20, 20);
    glutCreateWindow("FourCircle");
    setWindow(0, (float)width, 0, (float)height); // default world window
    setViewport(0, width, 0, height); //default viewport
    CP.set(0.0f, 0.0f); //initialize the cp to (0,0)
}

void Canvas::moveTo(Point2 p)  //moves current point CP to point p object 
{
    float x1, y1;
    x1 = p.getX();
    y1 = p.getY();
    CP.set(x1, y1);
}

float Canvas::getWindowAspectRatio(void)  //calculates aspect ratio of world window
{
    float width, height, aspectRatio;
    width = window.getR() - window.getL();
    height = window.getT() - window.getB();
    aspectRatio = width / height;
    return aspectRatio;
}

void Canvas::moveRel(float dx, float dy)
{
    CP.set(CP.getX() + dx, CP.getY() + dy);
}

void Canvas::turnTo(float angle)
{
    CD = angle;
}

void Canvas::turn(float angle)
{
    CD += angle;
}

void Canvas::forward(float dist, int isVisible)
{
    const float RadPerDeg = 0.017453393;  //radians per degree
    float x = CP.getX() + dist * cos(RadPerDeg * CD);
    float y = CP.getY() + dist * sin(RadPerDeg * CD);
    if (isVisible)
        lineTo(x, y);
    else
        moveTo(x, y);
}

Point2 Canvas::Tween(Point2 A, Point2 B, float t)
{
    Point2 P;
    P.set(A.getX() + (B.getX() - A.getX())*t, A.getY() + (B.getY() - A.getY())*t);
    return P;
}
class point {
public:
    int x, y;
};

void Canvas::drawTween(Point2 A[], Point2 B[], int N, float t)
{
    for (int i = 0; i < N; i++)
    {
        Point2 P;
        P = Tween(A[i], B[i], t);
        if (i == 0) moveTo(P.getX(), P.getY());
        else  lineTo(P.getX(), P.getY());

    }
}

Canvas cvs(640, 480, "my prog");

void ngon(int n, float x, float y, float radius, float rot)
{
    if (n < 3)
        return;
    double angle = rot * 3.141592 / 180;
    double angleinc = 2 * 3.141592 / n;
    cvs.moveTo(radius*cos(angle) + x, radius*sin(angle) + y);
    for (int i = 0; i < n; i++)
    {
        angle += angleinc;
        cvs.lineTo(radius*cos(angle) + x, radius*sin(angle) + y);
    }
    glFlush();
}


void display(void)
{
    glColor3ub(255, 60, 60);
    ngon(100, 300, 320, 60, 90);//top
    ngon(100, 300, 200, 60, 90);//bottom
    ngon(100, 240, 260, 60, 90);//left
    ngon(100, 360, 260, 60, 90);//right
    ngon(100, 260, 300, 60, 90);//top left
    ngon(100, 340, 300, 60, 90);//top right
    ngon(100, 260, 220, 60, 90);//bottom left
    ngon(100, 340, 220, 60, 90);//bottom right

    glFlush();
}

void main(void)
{
    glutDisplayFunc(display);
    glutMainLoop();
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • [This question](https://stackoverflow.com/questions/25549562/how-to-convert-const-char-to-char-in-c) may answer the question about char* conversion, although take heed of the warnings included in the answer. Meanwhile, please follow the guidance in [creating a Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – Korosia Feb 25 '22 at 10:07

1 Answers1

2

The code is not valid since C++11 and makes use of a deprecated conversion before that. A string literal is not convertible to char*, only to const char*.

So the constructor should read

Canvas(int width, int height, const char* windowTitle); //constructor
                              ^^^^^

Depending on the settings, Visual Studio will accept the wrong version anyway, even in newer standard version modes, but that is not standard-conform.

Interestingly the constructor parameter seems to be unused in the definition of the constructor, so maybe just remove it completely.


The constructor also has another issue: glutInit is supposed to be passed argc and argv from main's parameters directly. The shown code passes a pointer to an uninitialized array instead. Depending on what glutInit does with this, it is likely to cause undefined behavior for reading uninitialized values of dummyString.


void main(void) is also not legal standard C++. The return type of main should always be int. Using void as single parameter for an empty parameter list is allowed, but unconventional, in C++. It comes from C, where it has a different meaning from an empty parameter list. In C++ one would usually just write () instead of (void).

user17732522
  • 53,019
  • 2
  • 56
  • 105