I have some code to move a toy car from left to right.
I want to transform the code to stop its movement by the pressing of any key for example 's'....could someone help me do that...here is my code so far.
#include <GL/glut.h> // Header File For The GLUT Library
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
//#include <unistd.h> // Header File For sleeping.
/* ASCII code for the escape key. */
#define ESCAPE 27
/* The number of our GLUT window */
int window;
/* rotation angle for the triangle. */
float rtri = 0.0f;
/* rotation angle for the quadrilateral. */
float rquad = 0.0f;
/* A general OpenGL initialization function. Sets all of the initial parameters. */
// We call this right after our OpenGL window is created.
void InitGL(int Width, int Height)
{
// This Will Clear The Background Color To Black
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset The Projection Matrix
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
void ReSizeGLScene(int Width, int Height)
{
if (Height==0) // Prevent A Divide By Zero If The Window Is Too Small
Height=1;
glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
float ballX = -0.5f;
float ballY = 0.0f;
float ballZ = 0.0f;
void drawBall(void) {
glColor3f(0.0, 1.0, 0.0); //set ball colour
glTranslatef(ballX,ballY,ballZ); //moving it toward the screen a bit on creation
//glRotatef(ballX,ballX,ballY,ballZ);
glutSolidSphere (0.3, 20, 20); //create ball.
glTranslatef(ballX+1.5,ballY,ballZ); //moving it toward the screen a bit on creation
glutSolidSphere (0.3, 20, 20); //
}
/* The main drawing function. */
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(rtri,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
//glRotatef(rtri,1.0f,0.0f,0.0f); // Rotate The Triangle On The Y axis
// draw a triangle (in smooth coloring mode)
glBegin(GL_POLYGON); // start drawing a polygon
glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
glVertex3f(-1.0f, 1.0f, 0.0f); // Top left
glVertex3f(0.4f, 1.0f, 0.0f);
glVertex3f(1.0f, 0.4f, 0.0f);
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f( 1.0f,0.0f, 0.0f); // Bottom Right
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f(-1.0f,0.0f, 0.0f);// Bottom Left
//glVertex3f();
glEnd(); // we're done with the polygon (smooth color interpolation)
drawBall();
rtri+=0.005f; // Increase The Rotation Variable For The Triangle
if(rtri>2)
rtri=-2.0f;
rquad-=15.0f; // Decrease The Rotation Variable For The Quad
// swap the buffers to display, since double buffering is used.
glutSwapBuffers();
}
/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y)
{
/* sleep to avoid thrashing this procedure */
// usleep(100);
/* If escape is pressed, kill everything. */
if (key == ESCAPE)
{
/* shut down our window */
glutDestroyWindow(window);
/* exit the program...normal termination. */
exit(0);
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
/* get a 640 x 480 window */
glutInitWindowSize(640, 480);
/* the window starts at the upper left corner of the screen */
glutInitWindowPosition(0, 0);
/* Open a window */
window = glutCreateWindow("Moving Car");
/* Register the function to do all our OpenGL drawing. */
glutDisplayFunc(&DrawGLScene);
/* Go fullscreen. This is as soon as possible. */
//glutFullScreen();
/* Even if there are no events, redraw our gl scene. */
glutIdleFunc(&DrawGLScene);
/* Register the function called when our window is resized. */
glutReshapeFunc(&ReSizeGLScene);
/* Register the function called when the keyboard is pressed. */
glutKeyboardFunc(&keyPressed);
/* Initialize our window. */
InitGL(640, 480);
/* Start Event Processing Engine */
glutMainLoop();
return 1;
}
conditionally disable the following bit of code:
rtri+=0.005f; // Increase The Rotation Variable For The Triangle
if(rtri>2)
rtri=-2.0f;
rquad-=15.0f; // Decrease The Rotation Variable For The Quad
this can be done by adding the following to the keyPressed function
if (key == S)
{
updateGeom = false;//stop updating
}
if (key == D)
{
updateGeom = true;//start updating
}
and changing the above mentioned code as
if(updageGeom){
rtri+=0.005f; // Increase The Rotation Variable For The Triangle
if(rtri>2)
rtri=-2.0f;
rquad-=15.0f; // Decrease The Rotation Variable For The Quad
}
you need to add a global boolean updateGeom as well
Related
hello I am using glut and opengl with c++ , I have home I want to draw blue QUADS in it my problem when I draw the QUADS all the sense color in blue , so how I can to color only QUADS in blue color and Prevents to color all sense in blue color what I do wrong how to remove the blue color from all the sense and color only my QUAD?
my try:
void drawSquare1()
{
glBegin(GL_QUADS);
glColor3d(1,0,0);
glVertex3f(-0.5,-0.5,-0.5);
glColor3d(1,1,0);
glVertex3f(0.5,-0.5,-0.5);
glColor3d(1,1,1);
glVertex3f(0.5,0.5,-0.5);
glColor3d(0,1,1);
glVertex3f(-0.5,0.5,-0.5);
glEnd();
}
void render(void) // Our Rendering Is Done Here
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
GLfloat xtrans = -g_xpos;
GLfloat ztrans = -g_zpos;
GLfloat ytrans = -g_ypos;
if(g_yrot > 360)
g_yrot -= 360;
else if(g_yrot < 0)
g_yrot += 360;
GLfloat sceneroty = (360.0f - g_yrot);
int numpolygons;
glRotatef(g_lookupdown,1.0f,0,0);
glRotatef(sceneroty,0,1.0f,0);
glTranslatef(xtrans, ytrans, ztrans);
numpolygons = g_sector1.numpolygons;
for (int loop_m = 0; loop_m < numpolygons; loop_m++)
texture_object(loop_m);
gluQuadricDrawStyle(my_shape[0],GLU_FILL);
glBindTexture(GL_TEXTURE_2D, textures[1].texID);
glScalef(0.1,0.1,0.1);
glTranslatef(0.78,14.3,-4.2);
gluSphere(my_shape[0], 1.0,50,50);
gluQuadricDrawStyle(my_shape[1],GLU_FILL);
glBindTexture(GL_TEXTURE_2D, textures[8].texID);
glTranslatef(-20,0,0);
gluSphere(my_shape[1], 1.0,50,50);
gluQuadricDrawStyle(my_shape[2],GLU_FILL);
glBindTexture(GL_TEXTURE_2D, textures[22].texID);
glTranslatef(40,0,0);
gluSphere(my_shape[2], 1.0,50,50);
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPushMatrix(); // Store The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
glOrtho(-10,window_width,0,window_height,-10,10); // Set Up An Ortho Screen
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
drawSquare1();
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPopMatrix(); // Restore The Old Projection Matrix
//glPushMatrix();
drawSquare1();
//glPopMatrix();
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glutSwapBuffers ( );
}
int main(int argc, char** argv) // Main Function For Bringing It All Together.
{
//cout << "Hello World!" << endl;
//cin.get();
glutInit(&argc, argv); // GLUT Initializtion
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE); // (CHANGED)
if (g_gamemode)
{
glutGameModeString("640x480:16"); // Select The 640x480 In 16bpp Mode
if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
glutEnterGameMode(); // Enter Full Screen
else g_gamemode = false; // Cannot Enter Game Mode, Switch To Windowed
}
screen_width = glutGet(GLUT_SCREEN_WIDTH);
screen_height = glutGet(GLUT_SCREEN_HEIGHT);
window_width = screen_width/1.4;
window_height = screen_height/1.4;
if (!g_gamemode)
{
glutInitWindowSize(window_width,window_height); // Window Size If We Start In Windowed Mode
glutInitWindowPosition((screen_width-window_width)/2,(screen_height-window_height)/2);
glutCreateWindow("Frank's 3-D House"); // Window Title
}
init();
glutIgnoreKeyRepeat(true); // Disable Auto Repeat (NEW)
// glutKeyboardFunc(myKey); // register the key handler.
glutDisplayFunc(render); // Register The Display Function
glutReshapeFunc(reshape); // Register The Reshape Handler
glutKeyboardFunc(keyboard); // Register The Keyboard Handler
//glRasterPos2f(lineMargin, currentHight); // set the cursor to the initial position.
glutSpecialFunc(special_keys); // Register Special Keys Handler
glutSpecialUpFunc(special_keys_up); // Called When A Special Key Released (NEW)
glutIdleFunc(game_function); // Process User Input And Does Rendering (CHANGED)
glutMouseFunc(mouse) ;
glutMainLoop(); // Go To GLUT Main Loop
return 0;
}
and this picture of run my code:
By default the texture environment mode (GL_TEXTURE_ENV_MODE) is GL_MODULATE. See glTexEnv.
This means if texturing is enabled (glEnable(GL_TEXTURE_2D)), then the color from the texture is multiplied by the color which is currently set by glColor.
To fix your issue, I recommend to set glColor4f(1.0f,1.0f,1.0f,1.0f); before the geometry is drawn:
void render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
.....
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
for (int loop_m = 0; loop_m < numpolygons; loop_m++)
texture_object(loop_m);
.....
}
Note, the current color is changed in the function drawSquare1 and keeps its state.
This question already has answers here:
OpenGL texture mapping stubbornly refuses to work
(4 answers)
Closed 6 years ago.
I am trying to create an application that all it does is display an image full screen and then flash through a sequence of images quickly (144hz) repeatedly. I have just started looking at OpenGL, have done a few tutorials and cannot figure out what I'm doing wrong here. The part that I'm getting stuck on is actually rendering the image to to the display as it only shows up as a white square. I have gone through other stack overflow questions for this but none of the suggestions have worked for me.
I am doing this in Visual Studio 2015, using a win32 application and have installed the NupenGL package. For testing purposes, I am using a 256x256 bitmap image and am loading it through the SOIL library which I have built and statically linked.
I was originally thinking that I did not building/linking the SOIL library properly so something funky was going on trying to load the image. I created a custom BMP loader which didn't work and I also tried other peoples BMP loaders on stack overflow to no avail. I now believe that it is not the loading of the texture but that I am messing up something when actually trying to render it. Also in my code below I output if the texture is invalid but it always comes back good.
Output (FULLSCREEN):
Output (WINDOWED):
My Code:
#include <gl/freeglut.h>
#include <stdio.h>
#include <iostream>
#include "SOIL.h"
void init();
void display(void);
void keyPressed(unsigned char key, int x, int y);
void resize(int heightY, int widthX);
// define the window position on screen
int window_x;
int window_y;
// variables representing the window size
int window_width = 480;
int window_height = 480;
// variable representing the window title
char *window_title = "Resolution Enhancement via Display Vibrations";
bool fullscreen = false;
//-------------------------------------------------------------------------
// Program Main method.
//-------------------------------------------------------------------------
void main(int argc, char **argv)
{
// Connect to the windowing system + create a window
// with the specified dimensions and position
// + set the display mode + specify the window title.
glutInit(&argc, argv);
glutInitWindowSize(window_width, window_height);
glutInitWindowPosition(window_x, window_y);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow(window_title);
glutFullScreen();
// Setup keyPressed
glutKeyboardFunc(keyPressed);
// Handler for when the screen resizes
glutReshapeFunc(resize);
// Set OpenGL program initial state.
init();
// Set the callback functions
glutDisplayFunc(display);
// Start GLUT event processing loop
glutMainLoop();
}
//-------------------------------------------------------------------------
// Set OpenGL program initial state.
//-------------------------------------------------------------------------
void init()
{
// Set the frame buffer clear color to black.
glClearColor(0.0, 0.0, 0.0, 0.0);
}
//-------------------------------------------------------------------------
// This function is passed to glutDisplayFunc in order to display
// OpenGL contents on the window.
//-------------------------------------------------------------------------
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
GLuint texture = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
"C:/Users/joeja/Desktop/Grass.bmp",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
if (texture == 0) {
std::cout << "Texture not found!\n" << std::endl;
}
else
{
std::cout << "Texture is good\n" << std::endl;
}
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS); // front face
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.5f, -0.5f, 0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(0.5f, 0.5f, 0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5f, 0.5f, 0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, -0.5f, 0.5f);
glEnd();
glutSwapBuffers();
}
void resize(int heightY,int widthX) {
const float ar = (float)widthX / (float)heightY;
glViewport(0, 20, widthX, heightY);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar + 1, ar - 1, -1.0, 1.0, 2.0, 90.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyPressed(unsigned char key, int x, int y) {
switch (key) {
case 27:
case 70:
case 102: /* Fullscreen mode (Additional) : f/F */
fullscreen = !fullscreen;
if (fullscreen)
{
glutFullScreen(); /* Go to full screen */
}
else
{
glutReshapeWindow(800, 600); /* Restore us */
glutPositionWindow(0, 0);
}
break;
}
}
Do not load the image from file every frame.
In your init you should:
load the image with SOIL like you already are, storing the ID as texture
In display you should,
glBindTexture(GL_TEXTURE_2D, texture);
glEnable(GL_TEXTURE_2D)
draw stuff
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
You may notice that you could skip some enables/disables by just enabling texture 2D and leaving it on. I gave pseudocode that tries to always work, skipping redundant state changes is an optimization not relevant to the problem.
I have two viewports that are currently display 4 points in each of their corners. One viewport (left side) has gray corners, the other (right) has red corners. The two viewports are placed next to each other, with the red viewport intentionally made smaller. The viewport with red corners is also drawing a GL_TRIANGLES.
You can see them here:
The points in the triangle should be in the bottom left corner, top left corner and bottom right corner of the red viewport, but the bottom right corner is significantly short.
I think the second (red) glViewport is still using measurements from a previous object, the other viewport probably.
Am I setting up the second viewport correctly?
I want to have the second viewport 100 pixels across, not 900 pixels, squeezed into 100 pixels.
Here is my code.
I am using the latest version of glut and currently still learning how to use OpenGL/glut.
// windows/pannels
int winWidth = 900; // window width
int winHeight = 600; // window height
int pannelToolsWidth = 100;
int pannelToolsHeight = winHeight;
int pannelToolsX = winWidth - pannelToolsWidth;
int pannelToolsY = 0;
int drawSpaceWidth = winWidth - pannelToolsWidth;
int drawSpaceHeight = winHeight;
// drawing
float red = 0.0f;
float green = 0.0f;
float blue = 0.0f;
float lineSize = 1.0f;
float pointSize = 1.0f;
// ...
// draws a pannel. Make sure to define a colour before calling.
void drawPannel(int x, int y, int width, int height)
{
glBegin(GL_TRIANGLES);
glVertex2f(float(x), float(y));
glVertex2f(float(x), float(height));
glVertex2f(float(width), 0.0);
glEnd();
//glBegin(GL_TRIANGLES);
// glVertex2f(, );
// glVertex2f(, );
// glVertex2f(, );
//glEnd();
}
// Starts a new glViewport and visualises the bounderies with coloured points.
// scene: id of the viewport (viewports draw different things)
// x/y: viewports draw from the bottom left corner
void drawViewport(int x, int y, int width, int height, float red, float green, float blue, int scene)
{
// draw viewport (colours used to visualise limits)
glViewport(x, y, width, height);
glColor3f(red, green, blue);
glBegin(GL_POINTS);
glVertex2f(0.0f, float(winHeight));
glVertex2f(float(winWidth), float(winHeight));
glVertex2f(0.0f, 0.0f);
glVertex2f(float(winWidth), 0.0f);
glEnd();
// draw viewport content. text methods should be called last because the glRasterPos2i() effects the viewport
switch (scene)
{
// add more cases for other viewports here.
case 0:
// colour
// drawing
// text
break;
case 1:
glColor3f(0.8, 0.8, 0.7);
drawPannel(0, 0, pannelToolsWidth, pannelToolsHeight);
break;
default:
// do nothing
break;
}
}
void init()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //set clear background colour
glPointSize(10.0); //set point size
glColor3f(1.0f, 1.0f, 1.0f); //set draw colour
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, winWidth, 0, winHeight); //setup 2D projection
}
void collectScene()
{
glClear(GL_COLOR_BUFFER_BIT);
// viewport(s)
drawViewport(0, 0, drawSpaceWidth, drawSpaceHeight, 0.5, 0.5, 0.5, 0); // paint area
drawViewport(pannelToolsX, pannelToolsY, pannelToolsWidth, pannelToolsHeight, 1, 0, 0, 1); // GUI area
glFlush();
glutSwapBuffers(); //swap front and back buffers
}
//called when no event in queue
void idle()
{
glutPostRedisplay();
}
int main()
{
// create the window
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); // double buffer with RGBA
glutInitWindowSize(winWidth, winHeight);
glutInitWindowPosition(100, 100); // from top left
glutCreateWindow("Paint");
init();
glutDisplayFunc(collectScene);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
Thank you
Projection matrix is relative to the viewport, indeed it is usually set after glViewport call. In your case it doesn't change.
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;