Opengl draw a triangle by clicking a mouse - c++

I want to draw a triangle like this
I think I have to change these part of my codes
glBegin(GL_LINES);
glVertex2f(point[0][0], point[0][1]);
glVertex2f(point[1][0], point[1][1]);
glEnd();
and my mouse button down codes are like this
if (action == GLFW_PRESS && button == GLFW_MOUSE_BUTTON_LEFT)
{
inputMode = InputMode::DRAGGING; // Dragging starts
point[0][0] = xw; point[0][1] = yw; // Start point
point[1][0] = xw; point[1][1] = yw; // End point
}
How I have to do?

You need some global variables for 3 points and one index that is telling you which point you actually edit ...
float point[3][2];
int ix=0;
the render change to
glBegin(GL_LINE_LOOP); // or GL_TRIANGLE
glVertex2fv(point[0]);
glVertex2fv(point[1]);
glVertex2fv(point[2]);
glEnd();
now I do not code in GLFW but you need to change the onclick events to something like:
static bool q0 = false; // last state of left button
bool q1 = (action == GLFW_PRESS && button == GLFW_MOUSE_BUTTON_LEFT); //actual state of left button
if ((!q0)&&(q1)) // on mouse down
{
if (ix==0) // init all points at first click
{
point[0][0]=xw; point[0][1]=yw;
point[1][0]=xw; point[1][1]=yw;
point[2][0]=xw; point[2][1]=yw;
}
}
if (q1) // mouse drag
{
point[ix][0]=xw; point[ix][1]=yw;
}
if ((q0)&&(!q1)) // mouse up
{
point[ix][0]=xw; point[ix][1]=yw;
ix++;
if (ix==3)
{
ix=0;
// here finalize editation for example
// copy the new triangle to some mesh or whatever...
}
}
q0=q1; // remember state of mouse for next event
This is my standard editation code I use in my editors for more info see:
Does anyone know of a low level (no frameworks) example of a drag & drop, re-order-able list?
I am not sure about the q1 as I do not code in GLFW its possible you could extract the left mouse button state directly with different expression. the q0 does not need to be static but in such case it should be global... Also its possible the GLFW holds such state too in which case you could extract it similarly to q1 and no global or static is needed for it anymore...

Related

box2d falling while moving

Hey my player isn't falling while I'm pressing any of movement inputs while I'm falling. Just stands still and moves right or left.
Just watch the video; Video
My movement code;
if (right == true) {
p_pBody.body->SetLinearVelocity(b2Vec2(5, 0));
}
else
{
p_pBody.rect.setPosition(p_xPos * s_METPX, p_yPos * s_METPX); // Set The SFML Graphics
}
if (left == true) {
p_pBody.body->SetLinearVelocity(b2Vec2(-5, 0));
}
else
{
p_pBody.rect.setPosition(p_xPos * s_METPX, p_yPos * s_METPX); // Set The SFML Graphics
}
You're setting the vertical velocity to 0 when you're pressing right or left. That's the second coordinate of b2Vec2. If you want to have gravity, replace that zero with the vertical velocity the block has when the buttons are not being pressed.

OpenGL - Moving Primitives along the X and Y using arrow keys

I'm building a 2D drawing canvas that allows users to draw shapes on the screen by first selecting which shape you want to draw, and then clicking into the drawing area to draw your shape. Here's what the UI looks like for a better visualization:
So far, I have some code that allows the user to click on the derired shape, draw the shape, then click on another shape to draw, and so on...
First I check if a button has been clicked on in my processMouse() function:
if (x >= 0 && x <= 95 && y >= 302 && y <= 380) { // area of SQUARE shape
// squareShape = false by default
squareShape = true;
}
else squareShape = false;
If it has, we highlight the shape in my display() function:
if (squareShape != false) {
drawHighlight(100, 50, 350, true); // highlighted SQUARE
}
and in the same function, we enable some points to be drawn:
if (areaClicked2 != false) {
for (int i = 0; i < points.size();i++)
{
//areaClicked2 = true;
glLineWidth(1);
glBegin(GL_LINES);
glVertex2i(points[i].x + lineOffset.x, points[i].y + lineOffset.y);
}
}
I have applied this exact same method for every other button, and they all seem to be working fine...
My issue?
If I click on a button to draw squares, it draws a few squares, but when I click on an another button, my squares disappear because I don't have the square button selected. So for every button when I click to draw, the shapes are only visible until I click on an another button. How can I fix this?
EDIT:
Everytime I want to make a new points vector for a new shape, I make a new vector like this:
std::vector <point> lines; // old vector
point OnePoint;
std::vector <point> dots; // new vector
point OneDot;
Should I not be doing this? If not, how should I be? I tried to keep lines and just make new point variables but then when I draw, they're exactly the same point.
Just a guess, I think you are clearing(or creating new) points[] collection on each shape selection. You should preserve old point collection and append new shape points so that it will be visible even on different shape selection.

Moving sprites in a vector

I move sprites stored in a formationvector by holding the mousebutton. Problem is: Whenever i move the sprite onto another one, i move both sprites at the same time.
What i want: Moving the sprite1 over the other sprites2 without changing the position of sprite 2 or with other words:
-Testing in a loop if a sprite of a vector is clicked on
-If sprite is clicked on:
Move this sprite around while button is pressed but somehow stop this move while this movement in order to avoid moving more than this one sprite.
Here is my try so far:
while (App.pollEvent(Event))
{
// Window closed
if (Event.type == sf::Event::Closed)
{
return (-1);
}
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
for (size_t k = 0; k < formation.size(); k++)
{
if (isMouseOver(formation[k], App) == true)
{
Mouseposition = sf::Vector2f(sf::Mouse::getPosition(App));
Mouseposition.x = Mouseposition.x - formation[k].getLocalBounds().width / 2;
Mouseposition.y = Mouseposition.y - formation[k].getLocalBounds().height / 2;
formation[k].setPosition(sf::Vector2f(Mouseposition));
Formation_playernames.clear();
Formation_playerinformation.clear();
Formation_Playernames(Font, Formation_playernames, formation, playerlist);
Formation_Playerinformation(Font, Formation_playerinformation, formation, playerlist);
}
}
}
}
The Formation-functions store the correct new positions of the sprites and their colors based on the positions into the formation vector
The problem is the for-loop, i could do it without but that would lead to a much longer code. How could i do it ?
Instead of simply checking whether or not the mouse button is pressed, you should structure your code so you can check exactly when the button is pressed, and when it is released. You can then structure your code such that different presses of the button are distinguished from each other. semi-pseudocode follows
bool button_is_pressed = false;
Sprite* currently_selected_sprite = nullptr;
// main application loop
while (...)
{
...
// other application logic
...
if (!button_is_pressed)
{
if (CheckIfButtonIsPressed())
{
button_is_pressed = true;
// Button was just pressed.
// Select the appropriate sprite by checking
// the mouse coordinates against the positions
// of the sprites.
}
else
{
// Button not being pressed.
// Likely no logic needed here.
}
}
else // button_is_pressed == true
{
if (CheckIfButtonIsPressed())
{
// Button is being held down.
// Implement dragging logic using the
// pointer to the selected sprite.
}
else
{
button_is_pressed = false;
// Button was just released.
// Deselect the sprite.
currently_selected_sprite = nullptr;
}
}
}
Alternatively, you could handle mouse events, which will take care of much of this logic for you. http://sfml-dev.org/documentation/2.0/classsf_1_1Event.php
In a more English like pseudo code, this is what your function is doing:
if the mouse button is currently pressed
move all the sprites which are under the mouse to be centered on the mouse cursor
else
do nothing
This is what I'm suggesting
at the moment the mouse button is pressed down
select the sprite which is under the mouse cursor
at the moment the mouse button is released
deselect the selected sprite
if the mouse button is currently pressed, and a sprite is selected
move the selected sprite to the position of the mouse cursor

C++ how to drag bitmap around screen

Hi so I'm trying to make it so a little UFO bitmap (drawing/painting already taken care of) can be dragged around the screen. I can't seem to make the UFO position update and then redraw repeatedly from the MouseButtonDown() function (simplified code for mouse event handler). Any suggestions on detecting the dragging and redrawing accordingly? Code is below for relevant functions:
void MouseButtonDown(int x, int y, BOOL bLeft)
{
if (bLeft)
{
while(_bMouseMoving == true && _bMouseDragRelease == false) {
_iSaucerX = x - (_pSaucer->GetWidth() / 2);
_iSaucerY = y - (_pSaucer->GetHeight() / 2);
InvalidateRect(_pGame->GetWindow(), NULL, FALSE);
}
// Set the saucer position to the mouse position
_iSaucerX = x - (_pSaucer->GetWidth() / 2);
_iSaucerY = y - (_pSaucer->GetHeight() / 2);
}
else
{
// Stop the saucer
_iSpeedX = 0;
_iSpeedY = 0;
}
}
void MouseButtonUp(int x, int y, BOOL bLeft)
{
_bMouseDragRelease = true;
}
void MouseMove(int x, int y)
{
_bMouseMoving = true;
}
To clarify what chris said, you're only going to get the WM_xBUTTONDOWN message once, and you'll need to use that to toggle a dragging state that you can query when you recieve a WM_MOUSEMOVE message.
When you get the mouse move message during a dragging state, you'll want to invalidate the rectangle surrounding where the ufo was, and the rectangle surrounding where it is.
Invalidating a rectangle causes WM_PAINT messages, where you redraw whatever was behind the ufo, and the ufo in it's new place.
Or you could cheat and make the UFO a cursor when you're dragging :)

OpenGl project with drawPrimitive()

I am trying to change a C++ project, which is currently drawing some lines when I click on the view port. This functionality is perfectly fine, but what I am trying to change is when I click on "UP" or "Down" keys the color for next lines to change. Currently if I click on those keys the color changes for all the lines including the old ones (already drawn).
Please give me an idea of what to do. Here is some of the code:
void drawPrimitive() {
Vertex *temp;
// Set the primitive color
glColor3fv(primitiveColor);
// Set the point size in case we are drawing a point
if (type == POINT)
glPointSize(pointSize);
// Display results depending on the mode
glBegin(mode);
for(temp = head; temp != NULL; temp = temp->np)
{
if (smoothShading)
glColor3f(temp->r, temp->g, temp->b);
glVertex2f(temp->x, temp->y);
}
glEnd(); }
void mouse(int button, int state, int x, int y) {
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
float pointX, pointY;
pointX = (float)x/window_width * world_width;
pointY = (float)(window_height - y)/window_height * world_height;
// Add a vertex to the list of vertices...
addVertex(&head, &tail, pointX, pointY, 0.0f, primitiveColor[0], primitiveColor[1], primitiveColor[2]);
// automatically calls the display function
glutPostRedisplay();
}
else if(button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
{
deleteVertex(&head, &tail);
glutPostRedisplay();
} }
void special(int key, int x, int y) {
switch (key)
{
// change primitive color
case GLUT_KEY_UP :
changePrimitiveColor(1);
break;
case GLUT_KEY_DOWN :
changePrimitiveColor(-1);
break;
}
glutPostRedisplay(); }
void changePrimitiveColor(int step) {
primitiveColorId += step;
if (primitiveColorId < 0)
primitiveColorId = COLOR_COUNT - 1;
if (primitiveColorId >= COLOR_COUNT)
primitiveColorId = 0;
setColor(primitiveColor, primitiveColorId); }
Your code is sort of unclear; is primitiveColor a global variable?
Assuming you're calling drawPrimitive() for all your lines each redraw, the same primitiveColor would be used for all the lines. As soon as you change the color when you press up or down, the redisplay function is called, and all the lines will be redrawn using the same color.
What you might want to do is have a list containing both the primitives and their respective colors. When you iterate through this list, you can set a color for each line.
Keep in mind that OpenGL behaves like a statemachine. If you set a color, everything you draw after it will be drawn with that color. OpenGL will not remember that your other elements had a different color and you want to keep it like that. You have to do the bookkeeping.
So each time your content is drawn, you will have to explicitly state which elements have which color.