PDA

View Full Version : Use mouse to draw rectangular VBO



RunningPig
02-02-2017, 11:41 PM
I want write a program in which every click of right button of mouse will generate a rectangle locating at the position of the mouse. I made a base class drawable and derived class rectangle. The class has its own init and displayfunction.

The first step I did is to construct a rectangle by myself. I want to move it every time I click mouse.(This is just a trial step for the whole program.) However, I failed. The program can generate a rectangle when the window is open. But there is nothing change if I click mouse. I don't know where I am wrong.

Is it possible every time I click the mouse and a new rectangle object is drawn?

Here is the code I wrote up to now.


#include "Angel.h"
#include <vector>

vec4 blue_opaque = vec4(0.0, 0.0, 1.0, 1.0);

//-------------------------------------------------------------------------------------
//Build object class
//Base class
class myDrawable{
protected:
GLuint buffer;
GLuint VAO;
std::vector<vec2> points;
int NumVertices;

public:
void setVertices(std::vector<vec2> v){
points = v;
}


void myDisplay(){
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLE_FAN, 0, NumVertices);
}


void myInit(){
//Set up VBO
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, points.size()*sizeof(vec2), &points[0], GL_STATIC_DRAW);

//Load shaders and use the resulting shader program
GLuint program = InitShader("vshader00_v150.glsl", "fshader00_v150.glsl");
glUseProgram(program);

//Set up verte arrays
GLuint vPosition = glGetAttribLocation(program,"vPosition");

//Set up VAO
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

GLuint color_loc = glGetUniformLocation(program, "color");
glUniform4fv(color_loc, 1, blue_opaque);
}
};


//Derived class myRectangle
class myRectangle: public myDrawable{
public:
myRectangle(){
NumVertices = 4;
}//Constructor

// ~myRectangle();//Destructor
};


//Derived class myTriangle
class myTriangle: public myDrawable{
public:
myTriangle(){
NumVertices = 3;
}//Constructor

~myTriangle();//Desturctor
};


//-------------------------------------------------------------------------------------
//Main functions

int MOUSE_X ;
int MOUSE_Y ;

myRectangle rec;
std::vector<vec2> v;


void display(){

glClear(GL_COLOR_BUFFER_BIT);

rec.myDisplay();

glFlush();
}

void mouse(int button, int state, int x, int y){
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
MOUSE_X = x;
MOUSE_Y = y;
glutPostRedisplay();
}
}

void keyboard( unsigned char key, int x, int y )
{
switch( key ) {
case 033: // Escape key
case 'q': case 'Q':
exit( EXIT_SUCCESS );
break;
}
}


int main(int argc, char **argv){
v.push_back(vec2(MOUSE_X+0.2, MOUSE_Y+0.1));
v.push_back(vec2(MOUSE_X+0.2, MOUSE_Y-0.1));
v.push_back(vec2(MOUSE_X-0.2, MOUSE_Y-0.1));
v.push_back(vec2(MOUSE_X-0.2, MOUSE_Y+0.1));


rec.setVertices(v);

glutInit(&argc, argv);

#ifdef __APPLE__
glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_RGBA | GLUT_SINGLE);
#else
glutInitDisplayMode( GLUT_RGBA | GLUT_SINGLE);
#endif

glutInitWindowSize(500, 500);
glutCreateWindow("CS432 HW3");

rec.myInit();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMainLoop();


return 0;



}

john_connor
02-03-2017, 04:06 AM
your "myinit()" function is called only once, right ?
your mouse click callback function doesnt update the content of the vertex buffer
opengl only draws the content of the vertex buffer, so if you dont use uniform variables in your vertexshader to somehow move the rectangle to the desired position, then you'll have to re-upload the vertex buffer's content

your code only assigns the new position to MOUSE_X / MOUSE_Y, so you have to put those values again into a vector / array and call "glBufferData(...)" again

RunningPig
02-03-2017, 10:34 AM
your "myinit()" function is called only once, right ?
your mouse click callback function doesnt update the content of the vertex buffer
opengl only draws the content of the vertex buffer, so if you dont use uniform variables in your vertexshader to somehow move the rectangle to the desired position, then you'll have to re-upload the vertex buffer's content

your code only assigns the new position to MOUSE_X / MOUSE_Y, so you have to put those values again into a vector / array and call "glBufferData(...)" again

Thank you. I added it. Now i can generate the rectangle and move it every time I click. But How can I generate a new object of my class?

john_connor
02-04-2017, 01:44 AM
if you want to draw the same rectangle / geometry multiple times at different positions, you will have to "transform" the vertices. this is usually done in the vertexshader: for each rectangle, you send a new "transformation matrix" and apply it to each vertex, the vertexbuffer stays the same for all rectangles

http://www.songho.ca/opengl/gl_transform.html
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/