I use visual studio 2019 community edition. I'm trying to make a basic OpenGL withdrawing 3d objects in perspective. Whatever. The problem is when I change anything and run, the program doesn't display that change unless i "Rebuild Solution".example.

object.cpp

std::cout<< "PosX"<<std::endl;

to

std::cout<< "PosX1"<<std::endl;

when I run again, I get old output "PosX", not the new one.

I have these files on my project

main.cpp
header.h
Object.cpp
Puller.cpp
Cube.cpp
Cyclinder.cpp

I'm including all other class files within the header.h with safeguard(#ifndef #define class example #endif) if you want I can provide the code. Thx for your time.

i dont have other classes header file. Only .cpp file

Object.cpp

#include "Header.h"

#ifndef OBJECT_CPP
#define OBJECT_CPP

class Object
{
public:
    GLfloat matrixMV[16];
    vec3 Cordinates;
    vec3 Scale;
    vec4r Rotate;

    Object()
    {
    };

    Object(vec3 _Cordinates, vec3 _Scale = vec3(1, 1, 1), vec4r _Rotate = vec4r(0, 0, 0, 0)) : Cordinates(_Cordinates),
                                                                                               Scale(_Scale),
                                                                                               Rotate(_Rotate)
    {
    };

    virtual void move(vec2 direction)
    {
        Cordinates.x += direction.x;
        Cordinates.y += direction.y;
    };
};
#endif

header.h

#pragma once

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

struct vec3
{
    GLfloat x;
    GLfloat y;
    GLfloat z;

    vec3(GLfloat _x = 0, GLfloat _y = 0, GLfloat _z = 0)
    {
        x = _x;
        y = _y;
        z = _z;
    }
};

struct vec2
{
    GLfloat x;
    GLfloat y;

    vec2(GLfloat _x = 0, GLfloat _y = 0)
    {
        x = _x;
        y = _y;
    }
};

struct vec4r
{
    GLfloat x;
    GLfloat y;
    GLfloat z;
    GLfloat radiant;

    vec4r(GLfloat _x = 0, GLfloat _y = 0, GLfloat _z = 0, GLfloat _radiant = 0) : x(_x), y(_y), z(_z), radiant(_radiant)
    {
    };
};

const double PI = 3.1415927;

#include "Object.cpp"
#include "Puller.cpp"
#include "Cube.cpp"
#include "Cyclinder.cpp"
#include "TrianglePrism.cpp"


main.cpp

#include "Header.h"
#include <cstdint>


char wTitle[] = "3D PinPon";

GLfloat aspect = 0;
GLsizei _height;
GLsizei _width;
unsigned int id;
/* PREDEFINATION */
void display();

GLdouble _angle = 0.0;
vec3 rotate = vec3();


Cube block;
Cyclinder RightCylinder;
Cyclinder LeftCylinder;
Cube littlecube;
TrianglePrism my_prism;
Puller my_puller;


void initGL()
{
    glClearColor(0.0, 0.0, 0.0, 1.0); // Set background color to black and opaque
    glClearDepth(1.0); // Set background depth to farthest
    glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
    glDepthFunc(GL_LEQUAL); // Set the type of depth-test
    glShadeModel(GL_SMOOTH); // Enable smooth shading
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
}

void reshape(GLsizei width, GLsizei height)
{
    // GLsizei for non-negative integer
    _height = height;
    _width = width; // Compute aspect ratio of the new window
    if (height == 0) height = 1; // To prevent divide by 0
    aspect = (GLfloat)width / (GLfloat)height;

    // Set the viewport to cover the new window
    glViewport(0, 0, width, height);

    // Set the aspect ratio of the clipping volume to match the viewport
    glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
    glLoadIdentity(); // Reset
    // Enable perspective projection with fovy, aspect, zNear and zFar
    gluPerspective(45.0, aspect, 0.1, 100.0);
    //glOrtho(0.0f, width, height, 0.0f, 0.1f, 100.0f);
}

void processNormalKeys(unsigned char key, int x, int y)
{
    if (key == 27)
        exit(0);
}

void processSpecialKeys(int key, int xx, int yy)
{
    float fraction = 0.1;
    float speed = 0.05f;
    switch (key)
    {
    case GLUT_KEY_LEFT:
        rotate = vec3(rotate.x > 0 ? rotate.x - 0.1f : 0, rotate.y < 1 ? rotate.y + 0.1f : 1,
                      rotate.z > 0 ? rotate.z - 0.1f : 0);
        _angle -= 10;
        block.move(vec2(-1 * speed, 0));
        break;
    case GLUT_KEY_RIGHT:
        rotate = vec3(rotate.x > 0 ? rotate.x - 0.1f : 0, rotate.y < 1 ? rotate.y + 0.1f : 1,
                      rotate.z > 0 ? rotate.z - 0.1f : 0);
        _angle += 10;
        block.move(vec2(1 * speed, 0));
        break;
    case GLUT_KEY_UP:
        rotate = vec3(rotate.x < 1 ? rotate.x + 0.1f : 1, rotate.y > 0 ? rotate.y - 0.1f : 0, 0);
        _angle -= 10;
        break;
    case GLUT_KEY_DOWN:
        rotate = vec3(rotate.x < 1 ? rotate.x + 0.1f : 1, rotate.y > 0 ? rotate.y - 0.1f : 0, 0);
        _angle += 10;

        break;
    }
}

void demo_menu(int id)
{
    switch (id)
    {
    case 1:
        exit(0);
        break;
    case 2:
        glutIdleFunc(display);
        break;
    case 3:
        glutIdleFunc(nullptr);
        break;
    }
    glutPostRedisplay();
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
    glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix



    littlecube.render();
    RightCylinder.render();
    LeftCylinder.render();
    my_prism.render();
    my_puller.render();
    block.render();
    //std::cout << LeftCylinder.matrixMV[12] << std::endl;


    glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
}

void InitObjects()
{
    my_puller = Puller(vec3(-1.95, -2.9, -7.0),vec3(1,1,1),vec4r());
    block = Cube(0.2, vec3(-0.03, -2.35, 0), vec3(3, 1, 1),my_puller);
    littlecube = Cube(0.3, vec3(0, 1, 0));
    RightCylinder = Cyclinder(0.2, 0.5f, 255, 160, 100, vec3(0.8, 0, -6), false);
    LeftCylinder = Cyclinder(0.3, 0.3f, 255, 160, 100, vec3(-0.8, 0, -6), true);
    my_prism = TrianglePrism(vec3(0, 0, -7), vec3(0.3, 0.3, 0.3), vec4r(0.2, 0, 0, 20));

}

void secondDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
    glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
    glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
}

int main(int argc, char* argv[])
{
    InitObjects();
    glutInit(&argc, argv); // Initialize GLUT
    glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
    glutInitWindowSize(480, 720); // Set the window's initial width & height
    glutInitWindowPosition(50, 50); // Position the window's initial top-left corner

    //id = glutCreateWindow("second window");
    //glutSetWindow(id);
    //glutCreateMenu(demo_menu);
    //glutAddMenuEntry("quit", 1);
    //glutAddMenuEntry("start rotation", 2);
    //glutAddMenuEntry("stop rotation", 3);
    //glutAttachMenu(GLUT_RIGHT_BUTTON);
    //glutDisplayFunc(secondDisplay);
    //glutIdleFunc(secondDisplay);


    glutCreateWindow(wTitle); // Create window with the given title
    glutDisplayFunc(display); // Register callback handler for window re-paint event
    glutReshapeFunc(reshape); // Register callback handler for window re-size event
    glutIdleFunc(display);
    glutKeyboardFunc(processNormalKeys);
    glutSpecialFunc(processSpecialKeys);
    initGL(); // Our own OpenGL initialization
    glutMainLoop(); // Enter the infinite event-processing loop
    return 0;
}


1 Answers

4
Jesse Lawson On

The problem is when I change anything and run, the program doesn't display that change unless i "Rebuild Solution"

When I was first writing this answer, the code from the earlier version of this post indicated that the object file can't be consumed by the linker with the changes you made until it's been rebuilt--but since the files included were never linked correctly, you'd never see the changes.

Your issue lies in basic project organization.

For starters, look at the bottom of your header file and how you are organizing your includes. Remove this section from your header file:

#include "Object.cpp"
#include "Puller.cpp"
#include "Cube.cpp"
#include "Cyclinder.cpp"
#include "TrianglePrism.cpp"

While including *.cpp files from other *.cpp files is legal C++, it's not really adhering to the One Definition Rule.

Source files (*.cpp) should include header files, not the other way around.

Header files should contain things like class declarations, and the source files contain their respective implementations.

If you want to have a single header file, that's fine. It should have something like this:

header.h

#ifndef MYPROJECT_HEADER_H
#define MYPROJECT_HEADER_H

// all your header specifications

#endif

Then, all your *.cpp files include header.h.

I don't understand what you are trying to do by organizing your project in this way. If you are going for a traditional, object-oriented approach to development, you would create your class declarations in header files and then include those header files in any *.cpp file where you want to manipulate some instance of said class.

Your main.cpp file should be the glue that binds everything together. Your other *.cpp files should be the implementation of the classes you are defining in the other *.h files.