Drawing a polygon when the mouse is clicked - c

Consider this code:
#include <stdlib.h>
#include <stdarg.h>
#include <GLUT/GLUT.h>
#include <OpenGL/OpenGL.h>
double width=600;
double height=600;
void processMouse(int button, int state, int x, int y)
{
glColor4f(1.0,0.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glEnd();
glFlush();
}
static void render()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
glutMouseFunc(processMouse);
}
int main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutCreateWindow("Board");
glutDisplayFunc(render);
glutMainLoop();
}
The render function is executed, and every time a click is performed, it should start the function processMouse.
So if the mouse is clicked, all the window should become red with the instructions:
glColor4f(1.0,0.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glEnd();
glFlush();
But when I click the mouse I notice a strange behaviour: only a part of the window gets colored, the part at bottom left (instead of all the screen).
The window remains in this state, until I open a google chrome window.If I open a google chrome (or another graphical application), all the window become colored of red.
Why this? I also have problems with more complex programs, it seems like sometime the glVertex instructions are ignored.If I try debugging the program with fprintf it appears that everything is ok, and everything seems to go like expected (for example I tried to print mouse coordinates in the processMouse function, they were ok), except for the fact that what I draw is ignored.
Edit:
I have modified this code but it still has the same problem:
#include <stdlib.h>
#include <stdarg.h>
#include <GLUT/GLUT.h>
#include <OpenGL/OpenGL.h>
double width=600;
double height=600;
bool down=false;;
// http://elleestcrimi.me/2010/10/06/mouseevents-opengl/
static void render()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
if(down)
{
glColor4f(1.0,0.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glEnd();
glFlush();
}
}
void processMouse(int button, int state, int x, int y)
{
if(state==GLUT_DOWN)
{
down=true;
glutPostRedisplay();
}
}
int main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutCreateWindow("Board");
glutMouseFunc(processMouse);
glutDisplayFunc(render);
glutMainLoop();
}
Still getting only a part of the screen red.
PS: Solved using glutSwapBuffers(), thanks.

When you are using double buffering with GLUT, you need to call glutSwapBuffers() to see the result of the draw.
Add this to the end of your render() function and it will work fine.

Related

Vertex object doesn't show up (legacy OpenGL 1.2)

So I got the OpenGL Redbook 3e and am currently on chapter 2 (newer OpenGL seems too difficult for beginners to graphics programming). I copied a code snippet from the book (I added the initialization code and drawing code) and I've tried each of the options for rendering vertex arrays (glDrawElements, glDrawRangeElements, and gDrawArrays). For this example I decided to go with glDrawArrays because it seemed to be the most straightforward. As far as I can tell there's nothing wrong with this code because it compiles and runs. However, no polygon is drawn. Does anyone have any idea what's going on? I feel like I'm either making an incredibly silly error or am missing something fundamental.
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/freeglut.h>
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
void display() {
static GLint vertices[] = { 25, 25,
100, 325,
175, 25,
175, 325,
250, 25,
325, 325 };
static GLfloat colors[] = { 1.0, 0.2, 0.2,
0.2, 0.2, 1.0,
0.8, 1.0, 0.2,
0.75, 0.75, 0.75,
0.35, 0.35, 0.35,
0.5, 0.5, 0.5 };
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 0, colors);
glVertexPointer(2, GL_INT, 0, vertices);
glDrawArrays(GL_POLYGON, 0, sizeof(vertices) / sizeof(GLint));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glFlush();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(512, 512);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Your vertices are so far out of the clipping planes.
glOrtho is usually setup using pixel coordinates (but that is not required) see ref.
You probably want
glOrtho(0.0, 512.0, 0.0, 512.0, -1.0, 1.0);

Where is my display function being called in GLUT?

I do not understand how this main function works. I have a display function, which uses glDrawArrays, but I do not see it being called. I only see it being used as a parameter for glutDisplayFunction.
Here is my main:
int main(int argc, char** argv){
// Set up the window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Hello Triangle");
// Tell glut where the display function is
glutDisplayFunc(display);
// A call to glewInit() must be done after glut is initialized!
GLenum res = glewInit();
// Check for any errors
if (res != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
// Set up your objects and shaders
init();
// Begin infinite event loop
glutMainLoop();
return 0;
}
The problem is, I need to create two different triangles, on the same window, using seperate VAOs and VBOs. I've created the seperate VAO and VBO for my second triangle. However, I do not see how I am meant to generate and link my buffers, draw my arrays, switch to my second buffer, and draw those arrays, when I do not even know when my display function is being called.
My display function looks like this:
void display(){
glClear(GL_COLOR_BUFFER_BIT);
// NB: Make the call to draw the geometry in the currently activated vertex buffer. This is where the GPU starts to work!
glDrawArrays(GL_TRIANGLES, 0, 3);
glutSwapBuffers();
}
All operations could be done in separate function named asyouwant called from main
example:
#include <GL/glut.h>
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(300, 300);
glutInitWindowPosition(100, 100);
glutCreateWindow("Hello world :D");
glutDisplayFunc(displayMe); // = > draw in displayme function
glutMainLoop();
return 0;
}
void displayMe(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.5, 0.0, 0.0);
glVertex3f(0.5, 0.5, 0.0);
glVertex3f(0.0, 0.5, 0.0);
glEnd();
// a second geoform
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(-0.5, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0.0);
glVertex3f(0.0, -0.5, 0.0);
glEnd();
glFlush();
}
As complement: for VAO and buffer
1- Init (declare VAO , declare buffer of vertices, ...)
GLuint VaoID;
glGenVertexArrays(1, &VaoID);
glBindVertexArray(VaoID);
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
Once time only
// This will identify our vertex buffer
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
2- Use it (bind and draw in display fucntion)
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);

How to setup gluLookat() and glOrtho() in openGL?

I am new to openGL and have a hard time to understand how to actually parametrize the function gluLookat. I what it does but don't know how to know which parameters I should pass to that function and what consequences it will have.
This is my current code and strangely enough I don't even see the axis I drew... I think it is due to the parameters I pass to the function gluLookAt();
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GL/glut.h>
void init(void)
{
glClearColor(0.8, 0.8, 0.8, 0.0); /* window color white */
glEnable(GL_DEPTH_TEST);
}
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(3.0,3.0,3.0, 0.0,0.0,0.0, 0.0,1.0,0.0);
//used some random parameters...
gluLookAt(0.0, 0.0, 0.0, 5.0, 5.0, 5.0, 0, 1, 0);
//axis
//x
glColor3f(1.0,0.0,0.0);
glLineWidth(1.0);
glBegin(GL_LINES);
glVertex3d(0.0,0.0,0.0);
glVertex3d(1.0,0.0,0.0);
glEnd();
//y
glColor3f(0.0,1.0,0.0);
glLineWidth(1.0);
glBegin(GL_LINES);
glVertex3d(0.0,0.0,0.0);
glVertex3d(1.0,0.0,0.0);
glEnd();
//z
glColor3f(0.0,0.0,1.0);
glLineWidth(1.0);
glBegin(GL_LINES);
glVertex3d(0.0,0.0,0.0);
glVertex3d(1.0,0.0,0.0);
glEnd();
glFlush();
}
void herschaal(){
glViewport(0,0,500,500);
glMatrixMode(GL_PROJECTION);
glOrtho(-10, 10, 10, -10, 10, -10);
glLoadIdentity();
}
int main( int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowPosition(50, 100);
glutInitWindowSize(500, 500);
glutCreateWindow("mijn test");
glutReshapeFunc(herschaal);
init();
glutDisplayFunc(drawScene);
glutMainLoop();
return 0;
}

Regarding glutReshapeFunc()

I have small code drawing a square initially but when I maximize the window it changes to rectangle. I know this has do with aspect ratio and when I add glutReshapeFunc(Reshape); call it works perfectly, I mean after maximizing the window, it remains square only. ReshapFunc is called every time display is modified and before the first display as well.
I am not getting just by adding reshapefunc, how it maintains aspect ratio. Please help me understanding this. I am copying my code here:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.5, 0.5, 1.0);
glBegin(GL_POLYGON);
glVertex2f(-0.5, -0.5);
glVertex2f(0.5, -0.5);
glVertex2f(0.5, 0.5);
glVertex2f(-0.5, 0.5);
glEnd();
glutSwapBuffers();
glFlush();
}
void Reshape(int w, int h) {
glutPostRedisplay();
}
void init()
{
glClearColor(1.0, 0.0, 1.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(200, 200);
glutCreateWindow("basics");
glutDisplayFunc(display);
// If I comment this, it will become rectangle.
glutReshapeFunc(Reshape);
init();
glutMainLoop();
}
Your problem is related to the use of gluOrtho2D (...). If you want to preserve aspect ratio, your projection matrix needs to be defined based on the dimensions of your window.
I suggest you do this in your reshape function:
GLdouble aspect = (GLdouble)w / (GLdouble)h;
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (-1.0 * aspect, 1.0 * aspect, -1.0, 1.0);
glMatrixMode (GL_MODELVIEW);
glViewport (0, 0, w, h);

OpenGL Pre-compiled Header Skipped

Hey guys I'm having a problem with my coding at the moment.
The Problem is that my #Include <glut.h> File is being skipped when looking for Precompiled Header Use and cannot find a way to solve it.
Here is my code:
#include <D:/GL/glut.h>
#include <stdafx.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
using namespace System;
void drawScene(void)
{
int i, j;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glLoadIdentity();
glTranslatef(0.0, 0.0, -25.0);
glutWireCube(5.0); // Box.
glColor3f(1.0, 0.0, 0.0);
for(i=5; i<5; i++)
{
for (j = -5; j < 5; j++)
{
glPushMatrix();
glTranslatef(i*5, j*5, -35.0);
glColor3f(1.0, 1.0, 0);
glutSolidCube(5.0);
glColor3f(0.0, 0.0, 1.0);
glutWireCube(5.0);
glPopMatrix();
}
}
glFlush();
}
void setup(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
}
void resize (int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-10.0, 10.0, -10.0, 10.0, 10.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void KeyInput(unsigned char key, int x, int y)
{
switch(key)
{
case 27:
exit(0);
break;
default:
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500); /* Size of the Program Window */
glutInitWindowPosition(100,100);
glutCreateWindow("Voxel Assignment");
setup();
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(KeyInput);
glutMainLoop();
return 0;
}
It's probably because of the very strange absolute path usage, with drive specifier.
Don't do that, include paths are not supposed to include stuff at that level.
Just say #include <GL/glut.h> and adjust your compiler's settings to add the required directory to the include path.

Resources