This question already has an answer here:
grid not showing (it is all black)
(1 answer)
Closed 2 years ago.
I am trying to make an option pop-up menu to be able to choose if I want the grid on or off as an option to add to the game I am trying to make. I have been able to display the pop-up menu which has two options called "grid on" and "grid off", however when I click on it, the grid doesn't show at all for me which I am struggling to do.
void myGrid(GLint i) {
glEnable(GL_LINE_STIPPLE); //Activates the line-style feature
glLineStipple(1, 0xAAAA); // Plots a dashed polyline
glColor3f(0.8, 0.8, 0.8);
glBegin(GL_LINES);
for (i = 2; i <= 9; i++)
{
glVertex3f(i * 0.1 * w, 0.0, 0.0);
glVertex3f(i * 0.1 * w, 0.9 * h, 0.0);
}
for (i = 1; i <= 9; i++)
{
glVertex3f(0.1 * w, i * 0.1 * h, 0.0);
glVertex3f(w, i * 0.1 * h, 0.0);
}
glEnd();
glDisable(GL_LINE_STIPPLE);
}
int main(int argc, char* argv[])//standard c entry signature
{
//cout << "Player Controls:\n Up Key - move forward\n Down Key - move backward\n Left/Right key - move left or right\n R/r - rotate";
/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use double-buffered window and RGBA colour model */
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
/* window width = 400 pixels, height = 400 pixels */
glutInitWindowSize(500, 500);
/* window upper left corner at (100, 100) */
glutInitWindowPosition(100, 100);
/* creates an OpenGL window and set its title bar*/
glutCreateWindow("Coursework 1");
init();
glutDisplayFunc(display);
//glutKeyboardFunc(keyboard);
//glutSpecialFunc(specialKeys);
// glutSpecialUpFunc(keyGoneUp);
glutReshapeFunc(reshape);
//Create a grid turning it on and off
glutCreateMenu(myGrid);
glutAddMenuEntry("Grid on", 1);
glutAddMenuEntry("Grid off", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
// SetupRC();
glutIdleFunc(IdleFunc);
glutMainLoop();
return 0;
}
Toggle global (or window-specific, up to you) boolean in menu callback
Issue a glutPostRedisplay() in menu callback
Use global boolean to draw/don't draw grid in display callback
Related
I am using GLUT to draw a sequence of lines and my glutPassiveMotionFunc(passiveMotion); (no button press mouse motion) draws a line from the end of the line sequence to wherever the cursor is. This project is intended to be a bezier curve tool so I also render tangents with glutMotionFunc(motion); (button hold mouse motion). At this stage there are drawLine() calls at every place the cursor is in the window. I call glutPostRedisplay();to refresh the screen at the end of each movement to get rid of the history of drawLine() calls.
The introduction of glutPostRedisplay(); makes the program lag more and more each time my display function glutDisplayFunc(myDisplay); renders a line segment.
void myMouse(int button, int state, int x, int y)
{
// If left button was clicked
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
Point point;
point.setxy(x, SCREEN_HEIGHT - y);
// Draw the red dot.
glColor3f(255, 0, 0);
drawDot(point);
pointsVector[0] = point;
points++;
pointsVector[points].setxy((float)x, (float)(SCREEN_HEIGHT - y));
glColor3f(0, 0, 0);
drawLine(pointsVector[points - 1], pointsVector[points]);
}
else if (state == GLUT_UP)
{
Handle.setxy(x, SCREEN_HEIGHT - y);
controlPoints[0] = pointsVector[0];
controlPoints[points].setxy(Handle.x, Handle.y);
glColor3f(0, 255, 0);
drawDot(Handle);
reverseControlPoints[0] = pointsVector[0];
ReverseHandle.x = (2 * pointsVector[points].x) - Handle.x;
ReverseHandle.y = (2 * pointsVector[points].y) - Handle.y;
reverseControlPoints[points].setxy(ReverseHandle.x, ReverseHandle.y);
glColor3f(0, 255, 0);
drawDot(ReverseHandle);
glColor3f(0, 0, 255);
drawLine(Handle, ReverseHandle);
}
}
}
void passiveMotion(int x, int y)
{
Point Cursor;
Cursor.setxy(x, SCREEN_HEIGHT - y);
if ((pointsVector[0].x != NULL) && (pointsVector[0].y != NULL))
{
drawLine(pointsVector[points], Cursor);
glutPostRedisplay();
}
}
void motion(int x, int y)
{
Point Cursor;
Cursor.setxy(x, SCREEN_HEIGHT - y);
//drawLine(pointsVector[points], Cursor);
Point reverseCursor;
reverseCursor.x = (2 * pointsVector[points].x) - Cursor.x;
reverseCursor.y = (2 * pointsVector[points].y) - Cursor.y;
drawLine(pointsVector[points], reverseCursor);
glutPostRedisplay();
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
for (int i = 1; i < points; i++)
{
// draw main line & dot
glColor3f(255, 0, 0);
drawDot(pointsVector[i]);
glColor3f(0, 0, 0);
drawLine(pointsVector[i], pointsVector[i + 1]);
// draw tangent lines and tangent dots
glColor3f(0, 255, 0);
drawLine(controlPoints[i + 1], reverseControlPoints[i + 1]);
glColor3f(0, 0, 255);
drawDot(controlPoints[i + 1]);
drawDot(reverseControlPoints[i + 1]);
}
glFlush();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 500);
glutInitWindowPosition(100, 150);
glutCreateWindow("Bezier Curve");
glutDisplayFunc(myDisplay);
glutMouseFunc(myMouse);
glutPassiveMotionFunc(passiveMotion);
glutMotionFunc(motion);
myInit();
glutMainLoop();
return 0;
}
Hard to say for sure, however this snippet inside your display function looks suspicious.
controlPoints.push_back(Handle);
reverseControlPoints.push_back(ReverseHandle);
I don't know what Handle is exactly, however it seems like you're inserting new copies of it into your vectors with every frame, and I don't see you ever clearing them out. Also in myMouse() you're incrementing points which you then use to iterate through that ever-expanding vector. From my memory of how GLUT works, unless you explicitly set it to not repeat button presses, myMouse() won't fire just once when you click a mouse button, it will instead keep triggering the callback while you have it held down. Which means more increments to points, more eventual iterations through the vectors, and slower and slower code.
// #include loads up library files, the order can matter
// generally load glut.h last
#include <stdio.h> // this library is for standard input and output
#include "glut.h"// this library is for glut the OpenGL Utility Toolkit
#include <math.h>
// this is the initialisation function, called once only
void init() {
glClearColor(0.0, 0.0, 1.0, 0.0); // set what colour you want the background to be
glMatrixMode(GL_PROJECTION); // set the matrix mode, we will look at this later
// set the projection window size in x an y.
gluOrtho2D(0.0, 500, 0.0, 500.0);
}
// this is the display function it is called when ever you want to draw something
// all drawing should be called form here
void circle() {
// draw circle
float theta;
glClear(GL_COLOR_BUFFER_BIT); // clear the screen using the background colour
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0); // set colour to red
for (int i = 0; i < 320; i++) {
theta = i * 3.142 / 180;
glVertex2f(190 + 50 * cos(theta), 250 + 70 * sin(theta));
}
glEnd();
glFlush(); // force all drawing to finish
}
// this has the effect of repeatedly calling the display function
void display() {
circle();
}
// as with many programming languages the main() function is the entry point for execution of the program
int main(int argc, char** argv) {
glutInit(&argc, argv); //perform the GLUT initialization
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // more initialisation
glutInitWindowSize(800, 600); // set window position
glutInitWindowPosition(0, 0); // set window size
glutCreateWindow("Circle"); // create a display with a given caption for the title bar
init(); // call init function defined above
glutDisplayFunc(display); // define what function to call to draw
// the last function in the program puts the program into infinite loop
glutMainLoop();
// this line exits the program
return 0;
}
I've added comments so you can understand my code. The code creates a big red circle, and cuts the bottom right side of the circle, but I want to the cut only the bottom side. How can I achieve this? I would really appreciate the help.
Like this:
If you want to cut a circle by a Secant line, then you have to define an start angle and an end angle and to specify the vertex coordinates form the point on the circle with the start angle to the point with the end angle.
A Full angle has 360 degrees (2*PI radians). The bottom (south) has an angle of -90 degrees.
If you want to cut a part at the bottom of the circle, then the start and the end angle can be calculated like this:
int cutsegment = 45;
int start = -90 + cutsegment / 2;
int end = 270 - cutsegment / 2;
for (int i = start; i <= end; i++) {
theta = i * 3.142 / 180;
glVertex2f(190 + 50 * cos(theta), 250 + 70 * sin(theta));
}
I have a strange bug affecting my GLUT program
void display(void) {
/* clear the screen to the clear colour */
glClear(GL_COLOR_BUFFER_BIT);
jVector** buff = antialias ? antialiasedBuffer : screen;
for (int y = 0; y < sceneModel.height(); ++y){
for (int x = 0; x < sceneModel.width(); ++x){
glBegin(GL_POINTS);
glColor3d(buff[x][y].x, buff[x][y].y, buff[x][y].z);
glVertex2f(x,y);
glEnd();
}
}
/* swap buffers */
glutSwapBuffers();
}
void reshape (int w, int h) {
/* set the viewport */
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
/* Matrix for projection transformation */
glMatrixMode (GL_PROJECTION);
/* replaces the current matrix with the identity matrix */
glLoadIdentity ();
/* Define a 2d orthographic projection matrix */
gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h);
}
int main(int argc, char** argv) {
// PROJECT CODE
sceneModel.generateProjectModel();
screen = rayTrace(sceneModel);
// OPENGL CODE
/* deal with any GLUT command Line options */
glutInit(&argc, argv);
/* create an output window */
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(sceneModel.width(), sceneModel.height());
/* set the name of the window and try to create it */
glutCreateWindow("CS 488 - Project 3");
/* specify clear values for the color buffers */
glClearColor (0, 0, 0, 1.0);
/* Receive keyboard inputs */
glutKeyboardFunc (Keyboard);
/* assign the display function */
glutDisplayFunc(display);
/* assign the idle function */
glutIdleFunc(display);
/* sets the reshape callback for the current window */
glutReshapeFunc(reshape);
/* enters the GLUT event processing loop */
glutMainLoop();
return (EXIT_SUCCESS);
}
What happens is that the rendered image shows some random vertical black lines. I can assure you that the buffer doesn't have them. And this only happens using the GL_POINTS drawing, when i use GL_LINES these lines don't show up. I also noticed that compiling it on a mac doesn't lead to this glitch. Also, after resizing the window, the number and the position of the black lines change, as it can be seen from the second and third images.
That's about the slowest possible way to blit a bitmap to the framebuffer. At least move your glBegin()/glEnd() pair outside the for-loops!
Try uploading your bitmap to a texture and rendering a viewport-sized textured quad instead.
I have the following code which draws me a "spacecraft" which I'm able to ctrol with my arrow keys to spin clockwise and anti-clockwise. I'm trying to get the spacecraft shoot bullets when another key is pressed (it can be any key). I am so new to OpenGL that I'm confused on how to do it. I have tried so many methods but none of them work. Below is the code where I draw my spaceship and how I control it. Can someone help me with the bullets please?
struct
{
float rotateSpaceCraft;
} scene;
void SpaceCraft (){
glBegin(GL_TRIANGLE_FAN);
//specify the vertices to draw Ship in 2d space
glColor3f(1.0, 0.0, 1.0);
glVertex2f( X_CENTRE + LENGTH * 0, Y_CENTRE + LENGTH * 12);
glColor3f(1.0, 1.0, 0.0);
glVertex2f( X_CENTRE - LENGTH * 8, Y_CENTRE - LENGTH * 8);
glColor3f(0.0, 1.0, 1.0);
glVertex2f( X_CENTRE - LENGTH * 0, Y_CENTRE - LENGTH * 0);
glColor3f(1.0, 0.0, 0.0);
glVertex2f( X_CENTRE + LENGTH * 8, Y_CENTRE - LENGTH * 8);
glEnd();
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT); /* clear window */
glColor3f(1.0, 1.0, 1.0); /* white drawing objects */
/* define object to be drawn as a square polygon */
glPushMatrix();
glRotatef(scene.rotateSpaceCraft, 0.0, 0.0, 1.0);
SpaceCraft();
glPopMatrix();
glutSwapBuffers();
glFlush(); /* execute drawing commands in buffer */
}
static void specialKey(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_LEFT:
scene.rotateSpaceCraft = fmod(scene.rotateSpaceCraft + 7, 360);
break;
case GLUT_KEY_RIGHT:
scene.rotateSpaceCraft = fmod(scene.rotateSpaceCraft - 7, 360);
break;
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use single-buffered window and RGBA colour model */
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
/* window width = 400 pixels, height = 400 pixels */
glutInitWindowSize (600, 600);
/* window upper left corner at (100, 100) */
glutInitWindowPosition (250, 50);
/* creates an OpenGL window with command argument in its title bar */
glutCreateWindow ("Asteroids");
glutKeyboardFunc(key);
glutSpecialFunc(specialKey);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
Step by Step you could do it this way:
Create a spaceship object which holds rotation of the spaceship
Create a bullet object ( struct or class ), which holds the vector of the bullet, the start position ( and the time at which the bullet has been fired, you will need it later )
Create a scene object which holds a list of all bullets fired and the spaceship
Catch Key Events from Windows or any other platform you are using
When the bullet is fired, use the rotation and position of your spaceship to determine the position of the new bullet and the vector of it.
Some pseudo code for the structure:
struct Bullet {
Vector3 Position;
Vector3 Rotation;
}
struct {
struct {
Vector3 Position;
Vector3 Rotation;
} Ship;
Vector<Bullet*> Bullets;
} Scene;
....:
void Update(void) {
if (Key.IsPressed(Space)) {
CreateNewBullet();
}
}
void UpdateBullets(void) {
for (Bullet bullet in Scene.Bullets)
{
// Delete bullets here if not longer used
// and move all others
}
}
void Draw(void) {
// Draw spaceship here
....
// Draw bullets
for (Bullet bullet in Scene.Bullets) {
DrawBullet(bullet);
}
}
I also recommend using VBO but if you want to do it with the deprecated set then what you are looking for is to render a bullet similar to your SpaceCraft() function. A bullet will need to travel so you will need to translate its position every frame.
glTranslatef(x, 0.0f, 0.0f);
This will translate the bullet x amount in the x axis. Therefore you will need a variable that increments certain amount per frame and passes it to your new Bullet() function. You can store the translation X amount just like you did with struct
{
float rotateSpaceCraft;
} scene;
I have a pretty straightforward question. We are asked to make a checkerboard using glRecti in c++ using visual basic 2010. Here's what I have so far and was wondering if anyone can point me in the right direction.
#include <gl/glut.h>
void myInit(void)
{
glClearColor(1.0,1.0,1.0,0.0); // set white background color
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
void drawChecker(int size)
{
int i = 0;
int j = 0;
for (i = 0; i < 7 ; i++) {
if((i + j)%2 == 0) // if i + j is even
glColor3f( 0.4, 0.2, 0.6);
else
glColor3f( 0.2, 0.3, 0.4);
glRecti(i*size, j*size, size, size); // draw the rectangle
j++;
}
glFlush();
}
void checkerboard(void) {
glClear(GL_COLOR_BUFFER_BIT); // clear the screen
drawChecker(32);
}
void main(int argc, char** argv)
{
glutInit(&argc, argv); // initialize the toolkit
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowSize(640,480); // set window size
glutInitWindowPosition(100, 150); // set window position on screen
glutCreateWindow("null"); // open the screen window
glutDisplayFunc(checkerboard); // register redraw function
myInit();
glutMainLoop(); // go into a perpetual loop
}
You should try
for (i = 0; i < 8 ; ++i) {
for (j = 0; j < 8; ++j) {
if((i + j)%2 == 0) // if i + j is even
glColor3f( 0.4, 0.2, 0.6);
else
glColor3f( 0.2, 0.3, 0.4);
glRecti(i*size, j*size, (i+1)*size, (j+1)*size); // draw the rectangle
}
}
You should think if you would rather want to let i and j go to 7 and not to 6, which would make a real checkerboard. Remember that the loop is repeated as long as i is lower than 7 (therefore it is done for i from 0 to 6). Therefore I changed the 7 to 8. If the 7 was really intended, then excuse me for taking this freedom.
Furthermore are the last two arguments not the size of the rectangle, but its opposite vertex, therfore the use of i+1 and j+1.