Scaling i want to add scaling to my codeould someone advise me how

I want to add scaling to my code but im not sure how to do it.

I want to make it so that the position is stored in (x_mouse, y_mouse) when the middle button is clicked and When mouse is in motion with middle button pressed down it’s recorded its position in (x_mouse_cur, y_mouse_cur); Thank you

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <math.h>
#include <gl\GL.h>
#include <gl\GLU.h>
#include "glut.h"

using namespace std;

void display();
void reshape(int w, int h);
void idle();
void mouse_click(int button, int state, int x, int y);
void mouse_motion(int x, int y);
void cal_vertices();
void read_vertices();
void init();

// global var, rotation angle
float angle = 0.0;
float vertices[5][2]; // 5 vertices, and x, y coordinates
GLuint listname = 1;
float dx = 0.0;
float dy = 0.0; 
float dz = 0.0;
float scale = 1.0;

// mouse click
int x_click, y_click;
int button;

int main(int argc, char* argv[])
{
	// initialize glut
	glutInit(&argc, argv);

	// initialize window position
	glutInitWindowPosition(10, 10);
	
	// window size
	glutInitWindowSize(1200, 600);

	// display mode
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);

	// create a window
	glutCreateWindow("A simple glut window");

	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutIdleFunc(idle);
	glutMouseFunc(mouse_click);
	glutMotionFunc(mouse_motion);

	init();

	// glut main loop
	glutMainLoop();

	return 0;
}

void display(){
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//glPushMatrix();
	//	glRotatef(angle, 0.0, 1.0, 0.0);
	//	glRotatef(angle, 1.0, 0.0, 0.0);
	//	glutSolidTeapot(0.5);
	//glPopMatrix();

	glPushMatrix();
	glTranslatef(dx, dy, dz);
	glRotatef(angle, 0.0, 0.0, 1.0);
	glScalef(scale, scale, scale);
	glCallList(listname);
	glPopMatrix();

	glutSwapBuffers();
}

void reshape(int w, int h) {

	// Prevent a divide by zero, when window is too short
	// (you cant make a window of zero width).
	if(h == 0)
		h = 1;

	float ratio = 1.0* w / h;

	// Reset the coordinate system before modifying
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	// Set the viewport to be the entire window
	glViewport(0, 0, w, h);

	// Set the correct perspective.
	gluPerspective(45,ratio,1,1000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.0,0.0,5.0,     // eye's position
		      0.0,0.0,1.0,     // center of interest
			  0.0f,1.0f,0.0f); // up direction

}

void idle()
{
	angle = angle + 0.5;
	glutPostRedisplay();
}

void mouse_click(int button, int state, int x, int y)
{
	if (state == GLUT_DOWN) {
		x_click = x;
		y_click = y;
		::button = button; // button = GLUT_LEFT_BUTTON, GLUT_RIGHT_BUTTON, GLUT_MIDDLE_BUTTON
	}else {
		::button = -1;
	}
}

void mouse_motion(int x, int y)
{
	switch (button){
	case GLUT_LEFT_BUTTON:
		dx -= (x_click - x) * 0.01;
		dy += (y_click - y) * 0.01;
		break;
	case GLUT_RIGHT_BUTTON:
		angle -=(x_click - x);
		break;
	case GLUT_MIDDLE_BUTTON:
		scale -= (x_click - x) * 0.02;
		break;
	}
	x_click = x;
	y_click = y;
}

void cal_vertices()
{
	// open a file for writing pentagen vertices 
	ofstream outfile("vertices.txt");
	float a = 2 * 3.1415926 / 5.0;
	float x1 = 0.0, y1 = 1.0;
	outfile << x1 << " " << y1 << endl;;
	float x, y;
	for (int i = 1; i < 5; i++) {
		x = x1 * cos(a * i) - y1 * sin(a * i);
		y = y1 * cos(a * i) + x1 * sin(a * i);
		outfile << x << " " << y << endl;;
	}
	outfile.close();
}

void read_vertices()
{
	ifstream infile("vertices.txt");
	for (int i = 0; i < 5; i++){
		infile >> vertices[i][0];
		infile >> vertices[i][1];
		cout << vertices[i][0] << " " << vertices[i][1] << endl;
	}
}

void init()
{
	cal_vertices();
	read_vertices();

	glNewList(listname, GL_COMPILE);
	glBegin(GL_LINE_LOOP);
	for(int i = 0; i < 5; i++){
		glVertex3f(vertices[i][0], vertices[i][1], 0.0);
	}
	glEnd();
	glEndList();
}


The problem seem only to be generated by the sign you use into the GLUT_MIDDLE_BUTTON in your mouse_motion() func
=> only use += instead -= and this seem to work fine


void mouse_motion(int x, int y)
{
    switch (button){

    case GLUT_LEFT_BUTTON:
        dx -= (x_click - x) * 0.01;
        dy += (y_click - y) * 0.01;
        break;

    case GLUT_RIGHT_BUTTON:
        angle -=(x_click - x);
        break;

    case GLUT_MIDDLE_BUTTON:
        scale += (x_click - x) * 0.02;
        break;
    }
    x_click = x;
    y_click = y;
}

(the figure grow when the mouse goes to right and the figure narrow when the mouse goes to left)
[while the middle button is always pressed of course]

I have a very little transform your code for to can compile it on a linux box and add an exit key to it
(you now quit the program when you hit the Escape key)


 #ifdef WINDOWS
#include "stdafx.h"
#include <Windows.h>
#include <gl\GL.h>
#include <gl\GLU.h>
#endif

#include <math.h>
#include <fstream>
#include <iostream>
#include <GL/glut.h>


using namespace std;
 
void display();
void reshape(int w, int h);
void idle();
void mouse_click(int button, int state, int x, int y);
void mouse_motion(int x, int y);
void keyboard( unsigned char key, int x, int y);
void cal_vertices();
void read_vertices();
void init();
 
// global var, rotation angle
float angle = 0.0;
float vertices[5][2]; // 5 vertices, and x, y coordinates
GLuint listname = 1;
float dx = 0.0;
float dy = 0.0; 
float dz = 0.0;
float scale = 1.0;
 
// mouse click
int x_click, y_click;
int button;

// OpenGL window handle
int win;
 
int main(int argc, char* argv[])
{
    // initialize glut
    glutInit(&argc, argv);
 
    // initialize window position
    glutInitWindowPosition(10, 10);
 
    // window size
    glutInitWindowSize(1200, 600);
 
    // display mode
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
 
    // create a window
    win = glutCreateWindow("A simple glut window");
 
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutMouseFunc(mouse_click);
    glutMotionFunc(mouse_motion);
    glutKeyboardFunc(keyboard);
 
    init();
 
    // glut main loop
    glutMainLoop();
 
    return 0;
}
 
void display(){
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    //glPushMatrix();
    //    glRotatef(angle, 0.0, 1.0, 0.0);
    //    glRotatef(angle, 1.0, 0.0, 0.0);
    //    glutSolidTeapot(0.5);
    //glPopMatrix();
 
    glPushMatrix();
    glTranslatef(dx, dy, dz);
    glRotatef(angle, 0.0, 0.0, 1.0);
    glScalef(scale, scale, scale);
    glCallList(listname);
    glPopMatrix();
 
    glutSwapBuffers();
}
 
void reshape(int w, int h) {
 
    // Prevent a divide by zero, when window is too short
    // (you cant make a window of zero width).
    if(h == 0)
        h = 1;
 
    float ratio = 1.0* w / h;
 
    // Reset the coordinate system before modifying
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
 
    // Set the viewport to be the entire window
    glViewport(0, 0, w, h);
 
    // Set the correct perspective.
    gluPerspective(45,ratio,1,1000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0,0.0,5.0,     // eye's position
              0.0,0.0,1.0,     // center of interest
              0.0f,1.0f,0.0f); // up direction
 
}
 
void idle()
{
    angle = angle + 0.5;
    glutPostRedisplay();
}
 
void mouse_click(int button, int state, int x, int y)
{
    if (state == GLUT_DOWN) {
        x_click = x;
        y_click = y;
        ::button = button; // button = GLUT_LEFT_BUTTON, GLUT_RIGHT_BUTTON, GLUT_MIDDLE_BUTTON
    }else {
        ::button = -1;
    }
}
 
void mouse_motion(int x, int y)
{
    switch (button){

    case GLUT_LEFT_BUTTON:
        dx -= (x_click - x) * 0.01;
        dy += (y_click - y) * 0.01;
        break;

    case GLUT_RIGHT_BUTTON:
        angle -=(x_click - x);
        break;

    case GLUT_MIDDLE_BUTTON:
        scale += (x_click - x) * 0.02;
        break;
    }
    x_click = x;
    y_click = y;
}

void keyboard( unsigned char key, int x, int y)
{
    if ( key == 27 )
    {
        glutDestroyWindow(win);
    }
}
         

void cal_vertices()
{
    // open a file for writing pentagen vertices 
    ofstream outfile("vertices.txt");
    float a = 2 * 3.1415926 / 5.0;
    float x1 = 0.0, y1 = 1.0;
    outfile << x1 << " " << y1 << endl;;
    float x, y;
    for (int i = 1; i < 5; i++) {
        x = x1 * cos(a * i) - y1 * sin(a * i);
        y = y1 * cos(a * i) + x1 * sin(a * i);
        outfile << x << " " << y << endl;;
    }
    outfile.close();
}

void read_vertices()
{
    ifstream infile("vertices.txt");
    for (int i = 0; i < 5; i++){
        infile >> vertices[i][0];
        infile >> vertices[i][1];
        cout << vertices[i][0] << " " << vertices[i][1] << endl;
    }
}
 
void init()
{
    cal_vertices();
    read_vertices();
 
    glNewList(listname, GL_COMPILE);
    glBegin(GL_LINE_LOOP);
    for(int i = 0; i < 5; i++){
        glVertex3f(vertices[i][0], vertices[i][1], 0.0);
    }
    glEnd();
    glEndList();
}

This compile fine on a linux box using only this :


g++ scaling.c -o scaling -lm -lglut -lGL -lGLU

This is exactely the same thing, only inverse the grow vs narrow action :frowning:

=> I have reread your initial post and look about the needed transformation for to handle updates of x_move_cur and y_mov_cur
(I think this need only to differentiate GLUT_*_BUTTON cases on the mouse_click() function)