OpenGL GLUT problem

Hello everyone,
I have an OpenGL assignment using GLUT.I am intending to create a space battle game.Very simple one without using any textures.
I am having a problem drawing bullets of the player.
I want to fire the bullet when I press "f" key.When I press "f" one bullet draws but when I press "f" again that the first bullet disappears and re-appears in the original position.
Your help will be much much appreciated since this is very urgent.Thank you
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include "bullet.h"
#include <iostream>

float planetObjX[3] = {-1, 0, 1};
float planetObjY[3] = {2};
float num = 0.0;
float battleShipX = 0;
float battleShipY = 0;
float shipBulletX = 0;
float shipBulletY = 0;
int bulletCount = -1;
bool fire = false;
std::vector<Bullet> shipBullet(100, Bullet(shipBulletX,shipBulletY));

void randNumGenerate()
{
    srand(time(NULL));
    num = rand()%2/3 ;
}

void initRendering()
{
    glEnable(GL_DEPTH_TEST);
}

//this function will keep the ratio of the drawingeven after resizing the window
void handleResize(int w, int h)
{
    if (h == 0)
    {
        h = 1;
    }
    float aspectRatio = w*1.0/h;

    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, aspectRatio, 1.0, 200.0);
}

void update(int value)
{
    /*
    necessary updation comes here
    */
    planetObjY[0] -= 0.07+num;
    planetObjY[1] -= 0.05+num;
    planetObjY[2] -= 0.03+num;
    if (planetObjY[0] <= -2.0f)
        planetObjY[0] = 2.0f;
    if (planetObjY[1] <= -2.0f)
        planetObjY[1] = 2.0f;
    if (planetObjY[2] <= -2.0f)
        planetObjY[2] = 2.0f;
    if (fire == true)
        shipBullet[bulletCount].moveBullet(0.1);

    glutPostRedisplay(); //from this glut will be informed that the display has changed
    glutTimerFunc(25, update, 0); //value = 0, update will be called for every 25 milliseconds
}

void drawSpaceObject()
{
    glPointSize(3.0f);
    glBegin(GL_POINTS);
    glColor3f(0.9f, 0.7f, 0.8f );
    glVertex3f(planetObjX[0],planetObjY[0],-5.0f);
    glVertex3f(planetObjX[1],planetObjY[1],-5.0f);
    glVertex3f(planetObjX[2],planetObjY[2],-5.0f);
    glEnd();
}

void drawBattleShip()
{
    glBegin(GL_TRIANGLES);
    glVertex3f(battleShipX,battleShipY,-5.0f);
    glVertex3f(battleShipX-0.3,battleShipY-0.5,-5.0f);
    glVertex3f(battleShipX+0.3,battleShipY-0.5,-5.0f);
    glVertex3f(battleShipX+0.2,battleShipY-0.5,-5.0f);
    glVertex3f(battleShipX,battleShipY-0.7,-5.0f);
    glVertex3f(battleShipX-0.2,battleShipY-0.5,-5.0f);
    glEnd();
}

void drawScene()
{
    float bullY=0;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    /*
    necessary drawings come here
    */
    drawSpaceObject();
    drawBattleShip();

    if (fire == true)
    {
        shipBullet[bulletCount].drawBullet();
    }

    glutSwapBuffers();
}

void handleKeyPress(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 'q':
        exit(0);
        break;
    case 'a':
        battleShipX -= 0.05;
        shipBulletX = battleShipX;
        break;
    case 'd':
        battleShipX += 0.05;
        shipBulletX = battleShipX;
        break;
    case 'f':
        fire = true;
        bulletCount += 1;
        shipBullet.push_back(Bullet());
        shipBullet[bulletCount].setBulletPos(battleShipX,battleShipY);
        break;
    }
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(600,600);
    glutCreateWindow("Star Battle");
    initRendering();
    randNumGenerate();
    glutDisplayFunc(drawScene);
    glutKeyboardFunc(handleKeyPress);
    glutReshapeFunc(handleResize);
    glutTimerFunc(25, update, 0);
    glutMainLoop();
    return 0;
}

This is the "bullet.h" header file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#ifndef BULLET_H_INCLUDED
#define BULLET_H_INCLUDED
class Bullet
{
    float bulletX;
    float bulletY;

public:
    Bullet()
    {
        bulletX = 0.0f;
        bulletY = 0.0f;
    }
    Bullet(float x, float y)
    {
        bulletX = x;
        bulletY = y;
    }
    void drawBullet()
    {
        glBegin(GL_POLYGON);
        glVertex3f(bulletX,bulletY+0.02,-5.0f);
        glVertex3f(bulletX+0.01,bulletY+0.01,-5.0f);
        glVertex3f(bulletX,bulletY,-5.0f);
        glVertex3f(bulletX-0.01,bulletY+0.01,-5.0f);
        glEnd();
    }
    void moveBullet(float amount)
    {
        bulletY += amount;
    }
    void setBulletPos(float x, float y)
    {
        bulletX = x;
        bulletY = y;
    }
    float getBulletX()
    {
        return bulletX;
    }
    float getBulletY()
    {
        return bulletY;
    }
};


#endif // BULLET_H_INCLUDED 
Look at this code in your drawScene() function (lines 102 - 105):

1
2
3
4
if (fire == true)
    {
        shipBullet[bulletCount].drawBullet();
    }


If fire is true, draw the bullet at the end of the vector.

So, you're effectively only drawing one bullet at a time - the last one. While the other bullets continue to exist, they're simply not drawn.

Also, is fire ever false?
Hello xismn,
Thanks for the reply.I changed my code so that when "f" key is released the fire will be false.

I didn't get why it is drawing only the last bullet? I am incrementing "bulletCount" always when I press "f"

Since I changed my code so that when you release "f" fire becomes false, now the bullet will disappear as soon as I release the "f"

Any suggestions?
Thanks
I have this function now for the key releases

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void handleKeyRelease(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 'a':
        shipVelX = 0.0;
        break;
    case 'd':
        shipVelX = 0.0;
        break;
    case 'f':
        fire = false;
        break;
    }
}
I didn't get why it is drawing only the last bullet? I am incrementing "bulletCount" always when I press "f"


Let's look at the code again:

1
2
3
4
if (fire == true)
    {
        shipBullet[bulletCount].drawBullet();
    }


Let's assume that bulletCount is 2 (which actually means three bullets were fired).
If fire is true, draw the bullet in the bulletCount'th position, in this case 2, which is the last bullet. What about the bullets in the 0th and 1st position? Instead, You need to loop through every bullet and draw it.

Also, my last comment about how fire is never false was more food-for-thought. If it's never false, then what's the point of having it? I didn't mean for you to make changes in your code, sorry for not being clear.

I say get rid of the fire boolean since it's not actually doing anything. And like I said earlier, in your drawing function, simply loop through all your bullets and draw every single one of them.
Last edited on
Great! now it is working. Thanks a lot.

By the way I like to know whether I'm doing right in the line 128

 
shipBullet.push_back(Bullet());


xismn
do you know how to draw my score in opengl. It seems very hard to draw text in opengl
Last edited on
By the way I like to know whether I'm doing right in the line 128
shipBullet.push_back(Bullet());


Looks fine to me.

It's been a long, long time since I've messed around with glut. I don't remember if it was glut or freeGlut... so you'll just have to see if the following snippet works for you:

1
2
3
4
5
6
7
8
9
void drawBitmapText(char* string, float x, float y, float z) {

	char* c;
	glRasterPos3f(x, y, z);

	for (c = string, *c, ++c) {
		glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, *c);
	}
}


Which you'd use like so (in your rendering function someplace):

1
2
3
std::string string = "Hello World!";

drawBitmapText(string.c_str(), 0, 0, 0);


I wouldn't have the string in the rendering function, but you get the idea.

Note: It's important that the C-string that gets passed to drawBitmapText() is null-terminated. The std::string::c_str() member function guarantees a null-terminated C-string, which is why I've elected to use it. If you can't do that for whatever reason, just make sure it's null-terminated - the for loop inside the function expects it. I'm sure you could write it differently, but that's just what I was able to put together from memory and some quick research.

Additionally you'll want to make sure that the coordinates you're supplying for the raster are actually within your viewing frustum.

Also, here's a list of available fonts:

http://openglut.sourceforge.net/group__bitmapfont.html
Last edited on
You are a life saver!

I had to change char* string and char* c to const char* in your code. It is working now. I can draw text and my score now. I am very grateful to you. Thank you.

I will keep this topic open until I finish my game so that I can post any questions that I have to face. Thanks again<thumbs up!>
You're very welcome :)
I am having a deep trouble in my game now. That is in shooting.
I am using a vector for Enemy ships as same as the bullet vector of the player. I am drawing enemy ships randomly using that vector.
Now I am having problem like this. I want the bullets disappear and also that particular enemy ship when they meet.
It is better If I don't use a collision mask. is it possible?

This is my enemy vector
 
std::vector<Enemy> enemyShip(100, Enemy(0,1.5,100));


this is how I randomly choose the x coordinate of the enemy position
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void handleEnemy()
{

    int randm = 0;

    if (timer >= 150)
    {
        enemyCount++;
        enemyShip.push_back(Enemy());
        srand(time(NULL));
        randm = rand()%5-2;
        enemyShip[enemyCount].setEnemyPos(randm*1.0);
        timer = 0;
    }

}


this is how I draw them on the screen
1
2
3
4
for(int i=0;i<enemyCount;i++)
    {
        enemyShip[i].drawEnemy();
     }


I have another 2 days to submit my project. I can finish this if I could make this work.I think I won't be able to make the enemy ships fire back.

Thanks in advance
I finally got this to work. I designed a collision detection mechanism. Now all is fine.
I just couldn't implement the enemy weapon.But I am thinking of not including it to the assignment.I will add that feature later since I have a tight timeline.Thanks
Oops! Sorry for the late response! Glad you've got it working in time for the deadline!
Topic archived. No new replies allowed.