opengl how to make fire move smoothly and without a hole - c++

I'm rendering fire in opengl using freeglut, I created a particlesystem with emmiter and forcefield and they are working well.
I'm going to put the fire in an old train in a university project, I used textured spheres to simulate it.
The code is going to be long , I'm very sorry but all is relevant, here it is :
#include <GL/freeglut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <SOIL/SOIL.h>
#include <glm/glm.hpp>
#include <deque> using namespace std;
typedef glm::vec3 Vector3;
struct Force { private :
float strength;
Vector3 orentation; public :
Force(const Vector3 &v,const float &s)
:strength(s),orentation(v)
{
}
Force(const Force &f)
:strength(f.strength),orentation(f.orentation)
{
}
float getStrength() const
{
return strength;
}
Vector3 getOrentation() const
{
return orentation;
} };
class Particle { public :
Vector3 velocity,position;
const float mass;
float *deltatime;
float lifebegin;
Particle(const Vector3 &pos,const float &m,float *dt,const float &life)
:velocity(Vector3()),position(pos),mass(m),deltatime(dt),lifebegin(life)
{
}
void applyforce(const Force &f)
{
Vector3 force=f.getOrentation()*f.getStrength();
Vector3 accleration=force/mass;
velocity+=accleration*(*deltatime);
proceedintime();
}
void proceedintime()
{
position+=velocity*(*deltatime);
}
virtual void draw()const=0;
virtual bool collide(Particle *p)const=0;
virtual ~Particle()
{
} }; class TexturedParticle : public Particle { protected :
unsigned int textureid; public:
TexturedParticle(const Vector3 &pos,const float &m,float *dt,const float &life,const unsigned int &tex)
:Particle(pos,m,dt,life),textureid(tex)
{
}
virtual ~TexturedParticle()
{
}
}; class Emmiter; class ForceField;
class ParticleSystem {
friend class Emmiter;
friend class ForceField; private :
deque<Particle*> particles;
float elapsedtime;
float *deltatime;
float LifeOfParticles;
unsigned short particlesperframe; public :
ParticleSystem(const float &life,float *dt)
:elapsedtime(0),deltatime(dt),LifeOfParticles(life)
{
}
void deleteparticles()
{
float div=fmod(elapsedtime,LifeOfParticles);
if(div==0)
{
deque<Particle*>::const_iterator begin=particles.begin();
deque<Particle*>::const_iterator end=particles.end();
for(deque<Particle*>::const_iterator it=begin;it!=end;it++)
delete (*it);
particles.clear();
}
}
void drawparticl1es()
{
deque<Particle*>::const_iterator begin=particles.begin();
deque<Particle*>::const_iterator end=particles.end();
for(deque<Particle*>::const_iterator it=begin;it!=end;it++)
{
(*it)->proceedintime();
(*it)->draw();
}
elapsedtime+=(*deltatime);
} };
class Emmiter { public :
unsigned short ParticlesPerSecond;
Vector3 position;
ParticleSystem *ps;
unsigned char count;
float *deltatime;
Particle *(*emitfunc)(const Emmiter &em);
Emmiter(const unsigned short &parpersec,const Vector3 &pos,ParticleSystem *p,const unsigned char &c)
:ParticlesPerSecond(parpersec),position(pos),ps(p),count(c)
{
}
unsigned short particlesperframe()const
{
return ParticlesPerSecond*(*deltatime);
}
void emitparticles()const
{
unsigned short numpars=particlesperframe();
Particle *p=0;
for(unsigned char i=0;i<count;i++)
{
for(unsigned short j=0;j<numpars;j++)
{
p=emitfunc(*this);
p->lifebegin=ps->elapsedtime;
ps[i].particles.push_back(p);
}
}
} }; class ForceField { private :
Vector3 center;
float radius,MaxAcceleration;
unsigned char count;
ParticleSystem *pars; public:
ForceField(const Vector3 &cen,const float &r,const float &mf,ParticleSystem *ps,const unsigned char &c);
void applyforceonparticle(Particle *p)const;
void applyforceonsystems()const; };
ForceField::ForceField(const Vector3 &cen,const float &r,const float
&mf,ParticleSystem *ps,const unsigned char &c)
:center(cen),radius(r),MaxAcceleration(mf),count(c),pars(ps) {
}
void ForceField::applyforceonsystems() const {
for(unsigned char i=0;i<count;i++)
{
ParticleSystem p=pars[i];
for(deque<Particle*>::const_iterator it=p.particles.begin();it!=p.particles.end();it++)
{
applyforceonparticle(*it);
}
} }
void ForceField::applyforceonparticle(Particle *p) const {
Vector3 orentation=center-p->position;
float strength=1-orentation.length()/radius;
if(strength<=0)
return;
p->applyforce(Force(orentation,strength*MaxAcceleration*p->mass)); }
class BallParticle:public TexturedParticle { public :
float radius;
BallParticle(const Vector3 &pos,const float &r,const float &m,float *dt,const float &life,const unsigned int &tex)
:TexturedParticle(pos,m,dt,life,tex),radius(r)
{
}
void draw() const
{
glPushMatrix();
glBindTexture(GL_TEXTURE_2D,textureid);
glTranslatef(position.x, position.y, position.z);
glutSolidSphere(radius,10,10);
glPopMatrix();
}
bool collide(Particle *p) const
{
BallParticle *b=dynamic_cast<BallParticle*>(p);
return (b)&&((b->position-position).length()<=b->radius+radius);
} }; using namespace std;
float deltatime; float oldtime; float newtime; GLuint texture;
ParticleSystem pars(1,&deltatime); Emmiter
emmiter(100,Vector3(0,0,0),&pars,1); ForceField
f(Vector3(0,0.5f,0),0.5f,0.1f,&pars,1);
float myrand(const float &min,const float &max) {
return min+(max-min)*(float(rand())/float(RAND_MAX)); }
Particle *emitfunction(const Emmiter &em) {
float x=em.position.x,y=em.position.y;
BallParticle *b=new BallParticle(Vector3(myrand(x-1,x+1),myrand(y-1,y+1),em.position.z),1,2,&deltatime,0.0f,texture);
b->velocity=Vector3(0,1,0);
return b; }
GLuint GetTextId(const char *texture_name) {
return(SOIL_load_OGL_texture(
texture_name,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_POWER_OF_TWO
));
}
/* GLUT callback Handlers */ void resize(int width, int height) {
glViewport(0, 0, width, height);
/*glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,(4/3.0f),2,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camera.LookAt();*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,(float)width/(float)height,0.1f,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( 0, 0, 10, 0, 0, 0, 0, 1, 0 ); }
void display() {
glClear(GL_COLOR_BUFFER_BIT);
newtime=glutGet(GLUT_ELAPSED_TIME)/1000;
deltatime=newtime-oldtime;
oldtime=newtime;
pars.drawparticl1es();
glutSwapBuffers(); } void idle() {
emmiter.emitparticles();
f.applyforceonsystems();
pars.deleteparticles();
glutPostRedisplay(); }
void init() {
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 0.0f };
const GLfloat light_diffuse[] = { 1, 0.5f, 0.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
const GLfloat mat_emissive[]={1,0.5f,0,1};
glClearColor(0, 0, 0, 0);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT,GL_EMISSION,mat_emissive);
//glShadeModel(GL_SMOOTH);
//glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE); }
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitWindowPosition(300,200);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("Fire");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutIdleFunc(idle);
init();
oldtime=glutGet(GLUT_ELAPSED_TIME)/1000;
emmiter.emitfunc=&emitfunction;
emmiter.deltatime=&deltatime;
texture=GetTextId("/home/abd/graphics/fire2.jpg");
glutMainLoop();
return EXIT_SUCCESS;
}
and here is the texture I'm using :
The fire looks somewhat good but I'm still having an empty hole in the middle, also the particles don't move smoothly.
I tried these things :
1-change the strength and radius of the forcefield: didn't work.
2-increasing the number of particles per second : didn't work, still see the hole.
3-I made my particles bigger: well it made the fire look better and the hole almost disappeared(almost, it somewhat goes and come) but I get strange curves around the fire and it's still not moving smoothly.
4-I have double buffering and I made a call to glutPostRedisplay in the idle function , they still don't move smoothly, I tried removing the hint for PERSPECTIVE NICEST and SMOOTH_SHADING_MODEL, I'm using glutSolidSphere which uses new opengl capabilities and I have Nvidia GT9400 with updated driver to the last version, and still they don't move smoothly.
So what to do to solve these two problems ?
PS
because this is for a university project, I don't want code, "where is the mistake" is enough, I can solve it after I know it.
An algorithm is ok but not code.
EDIT
here's a screenshot of the output :
As you can see, there is a small hole in the middle and curves around the fire.

at a first glance it looks like you have to play a bit with the glBlendFunc
https://www.opengl.org/sdk/docs/man2/xhtml/glBlendFunc.xml
here's a nice viewer of what those parameters do
http://www.andersriggelsen.dk/glblendfunc.php

Related

Initialize array of objects

If I were to write a working code of what I want to accomplish, it would be this:
Sprite s1(img_path1);
Sprite s2(img_path2);
Sprite s[] = { s1, s2 }
I want to create the objects inside the {} of array declaration instead of first putting the objects into variables and then in the array.
I checked out this post before asking this question and I will clarify a few things first:
I am compiling with -std=c++11
I have not defined a copy constructor of my own
I'm trying to create an array like this:
Sprite s[] =
{
Sprite(img_path1),
Sprite(img_path2)
};
After executing that statement, the contents of s are the same as if I created the array of objects using the default constructor:
Sprite s[2];
The problem seems not to be with the default copy constructor because the following executes perfectly fine:
sp = Sprite(img_path);
Sprite sp1(sp);
std::cout << sp1.getAspectRatio();
Relevant code:
/*
* Sprite.h
*
*/
#ifndef SPRITE_H
#define SPRITE_H
#include <GL/freeglut.h>
#include <FreeImage.h>
#include <iostream>
#include <stdio.h>
class Sprite
{
GLuint texture;
float aspectRatio;
public:
Sprite();
Sprite(std::string path);
Sprite(GLuint texture, float aspectRatio);
float getAspectRatio();
void draw(float x, float y, float alpha, float size);
virtual ~Sprite();
protected:
private:
};
#endif // SPRITE_H
/*
* Sprite.cpp
*
*/
#include "Sprite.h"
Sprite::Sprite()
{
//ctor
}
Sprite::Sprite(std::string file) {
GLuint texture = 0;
int sWidth, sHeight;
if (texture == 0)
{
FIBITMAP* bitmap = FreeImage_Load(
FreeImage_GetFileType(file.c_str(), 0),
file.c_str());
if (bitmap == NULL) {
printf("Could no load image file %s\n", file.c_str());
}
glGenTextures(1, &texture);
printf("%d\n", texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
FIBITMAP *pImage = FreeImage_ConvertTo32Bits(bitmap);
int nWidth = sWidth = FreeImage_GetWidth(pImage);
int nHeight = sHeight = FreeImage_GetHeight(pImage);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight,
0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage));
FreeImage_Unload(pImage);
FreeImage_Unload(bitmap);
}
this->texture = texture;
this->aspectRatio = (float)sWidth / sHeight;
if(texture == 0) {
std::cout << file << std::endl;
}
}
Sprite::Sprite(GLuint t, float as) : texture(t), aspectRatio(as) {}
void Sprite::draw(float x, float y, float alpha, float size) {
float h = size;
float w = size * aspectRatio;
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0, 1.0, 1.0, alpha);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(x, y);
glTexCoord2f(0.0f, 1.0f); glVertex2f(x, y + h);
glTexCoord2f(1.0f, 1.0f); glVertex2f(x + w, y + h);
glTexCoord2f(1.0f, 0.0f); glVertex2f(x + w, y);
glEnd();
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glPopMatrix();
}
float Sprite::getAspectRatio() { return aspectRatio; }
Sprite::~Sprite()
{
//dtor
}
/*
* main.cpp (extract)
*
*/
#include "Globals.h"
#include <GL/freeglut.h>
#include "Sprite.h"
void render();
std::string img_path = "/home/saurabh/Dropbox/Code/C/OpenGL_Game/images/";
Sprite s[] =
{
Sprite(img_path + "gait-right-1.gif"),
Sprite(img_path + "gait-right-0.gif"),
Sprite(img_path + "gait-left-1.gif"),
Sprite(img_path + "gait-left-0.gif"),
Sprite(img_path + "gait-top-1.gif"),
Sprite(img_path + "gait-top-0.gif"),
Sprite(img_path + "gait-bottom-1.gif"),
Sprite(img_path + "gait-bottom-0.gif")
};
int main(int argn, char** argc) {
FreeImage_Initialise();
glutInit(&argn, argc);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(GV.windowWidth, GV.windowHeight);
glutCreateWindow("Monogatari");
glutDisplayFunc(render);
glutIdleFunc(render);
glutMainLoop();
FreeImage_DeInitialise();
}
void render() {
s[0].draw(0,0,1,0.5);
}

OpenGL program keeps crashing around glDrawArrays()

I am trying to make a function that displays a GLuint texture. This is what I made so far. It should output a white quad, but it just crashes:
position2 Q_pos[4]={{0,0},
{1,0},
{1,1},
{0,1}};
void blit_texture(GLuint texture,Point mid_pt,Point Scale=Point(1,1,1),
Point rotate_angle=Point(0,0),Point focus_point=Point(0,0))
{
glEnableClientState(GL_VERTEX_ARRAY);
glPushMatrix();
GLtranslate2v(mid_pt);
GLrotate3f(rotate_angle);
GLtranslate2v(focus_point);
glScalef(Scale.x,Scale.y,1);
glColor4f(1,1,1,1);
glVertexPointer( 2, GL_FLOAT, 0, Q_pos );
glDrawArrays( GL_QUADS, 0, 4 );
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY);
}
I've also made some definitions for points, easier rotating etc...:
#define GLrotate3f(pt) glRotatef(pt.x,1,0,0),glRotatef(pt.y,0,1,0),glRotatef(pt.z,0,0,1)
#define GLtranslate2v(pt) glTranslatef(pt.x,pt.y,0);
#define GLscale2v(pt) glScalef(pt.x,pt.y,0);
class position3
{
public:
float x,y,z;
position3(float X=0,float Y=0,float Z=0){
x=X,y=Y,z=Z;}
void operator=(float num){x=num,y=num,z=num;}
void operator=(position3 pt){
x=pt.x,y=pt.y,z=pt.z;
}
bool operator>(float Min)
{
if (x<Min || y<Min || z<Min) return 0;
return 1;
}
bool operator<(float Max)
{
if (x>Max || y>Max || z>Max) return 0;
return 1;
}
};
class position2
{
public:
float x,y;
position2(float X=0,float Y=0)
{
x=X,y=Y;
}
void operator=(float num){x=num,y=num;}
void operator=(position2 pt){
x=pt.x,y=pt.y;
}
bool operator>(float Min)
{
if (x<Min || y<Min) return 0;
return 1;
}
bool operator<(float Max)
{
if (x>Max || y>Max) return 0;
return 1;
}
};
class color3f
{
public:
float r,g,b;
color3f(float R=0,float G=0,float B=0){
r=R,g=G,b=B;}
void operator=(color3f cl)
{
r=cl.r,g=cl.g,b=cl.b;
}
};
class Point : public position3 , public color3f
{
public:
Point(float X=0,float Y=0,float Z=0,float R=0,float G=0,float B=0)
{
x=X,y=Y,z=Z;
r=R,g=G,b=B;
}
};
If I make it in intermediate mode it works fine, even the texture appears, but when I try to use VAs it can't make a single white quad.
I did a little debugging on it and figured out that if I put exit(42); before the glDrawArrays() call it returns with 42 but if I take it after the glDrawArrays() the program crashes, so it seems that the problem is caused by glDrawArrays().
Here is my initialization:
const int width=640, height=480;
glViewport(0,0,width, height );
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, ((GLfloat)-1), (GLfloat)1);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glShadeModel(GL_SMOOTH);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
Also, is there a method to check if VBOs are supported or not? This because I made a program with them and it worked fine on my pc (with OpenGL 4.2), but when I tried to run it on my friend's computer (with OpenGL 2.1) it crashed.

Placing objects from an array in individual places OpenGL GLUT C++

I have an array working but I am not able to place each ball separately, all the balls are being drawn within each other at the origin, here is my code:
Ball.cpp
#include "Ball.h"
#include "Vector2f.h"
#include "Vector3f.h"
#include "Glut/glut.h"
#include "GL/gl.h"
#include "GL/glu.h"
Ball::Ball(void)
{
Vector3f Temp_position;
position = Temp_position;
Vector3f Temp_velocity;
velocity = Temp_velocity;
}
Ball::~Ball(void)
{
}
void Ball::SetPos(Vector3f New_position)
{
position = New_position;
}
void Ball::Draw()
{
glPushMatrix();
glTranslatef(position.X(), position.Y(), position.Z());
glColor3d(1, 0, 0);
glutSolidSphere(0.3, 50, 50);
glPopMatrix();
}
void Ball::ArrayPosition()
{
Ball *Yellowball = new Ball[8];
Yellowball[0].SetPos(Vector3f (position.X(), position.Y(), position.Z()));
Yellowball[1].SetPos(Vector3f (position.X(), position.Y(), position.Z()));
Yellowball[2].SetPos(Vector3f (position.X(), position.Y(), position.Z()));
Yellowball[3].SetPos(Vector3f (position.X(), position.Y(), position.Z()));
Yellowball[4].SetPos(Vector3f (position.X(), position.Y(), position.Z()));
Yellowball[5].SetPos(Vector3f (position.X(), position.Y(), position.Z()));
Yellowball[6].SetPos(Vector3f (position.X(), position.Y(), position.Z()));
Yellowball[7].SetPos(Vector3f (position.X(), position.Y(), position.Z()));
}
void Ball::DrawYellow()
{
glPushMatrix();
glColor3f(2,1,0);
glutSolidSphere(0.3, 50, 50);
glPopMatrix();
}
void Ball::SetVel(Vector3f New_velocity)
{
velocity = New_velocity;
}
Vector3f Ball::GetPos()
{
Vector3f temp;
temp = position;
return temp;
}
Vector3f Ball::GetVel()
{
Vector3f temp;
temp = velocity;
return temp;
}
Display.cpp
#include "Display.h"
#include "Vector3f.h"
#include "Ball.h"
#include "Glut/glut.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include <math.h>
#include "Bitmap.h"
Timer Display::m_Timer = Timer();
static float TableWidth = 4; // Z axis normal = 4
float Display::eyeX = -7.5; //-7.5
float Display::eyeY = 3; //3
float Display::eyeZ = 5; //5
float Display::Position[4] = { 1.0f, 0.0f, -3.5, 1.0f };
float Display::translateZ = -3.5;
float Display::translateX = 0.0;
float Display::lightX = 5.0; //5 2.5
float Display::lightY = 5.0;
float Display::lightZ = 2.5;
float m_TableX = -5.0f;
float m_TableZ = -2.5f;
float m_TableWidth = 2.5f;
float m_TableLength = 5.0f;
float ballx = 0.7;
float bally = 0.1;
float ballz = -0.7;
Ball Redball;
float BALL_RED_START = 0;
float RADIUS_OF_BALL = 0.3;
float BALL_RED_END = 8;
Ball Yellowball;
float BALL_YELLOW_START = 0;
float BALL_YELLOW_END = 8;
Bitmap Display::m_HeightMap;
unsigned int Display::m_TextureID;
void Display::Init(int argc, char ** argv)
{
glutInit(&argc, argv); // initializes glut
// sets display mode. These parameter set RGB colour model
// and double buffering.
glutInitWindowSize(500,500);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Pool Version 1.0");
// Set glut callback functions
glutDisplayFunc(Display::DisplayScene);
glutIdleFunc(Display::Idle);
glutReshapeFunc(Display::Resize);
glutKeyboardFunc(Display::KeyboardInput);
m_Timer.getSeconds();
glEnable(GL_DEPTH_TEST);
glPointSize(5);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glClearColor(0,0,0,1);
glEnable(GL_COLOR_MATERIAL);
glutFullScreen();
float white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
glEnable(GL_LIGHT0);
Redball.SetPos(Vector3f(-5.0,0.5,0.0));
Redball.SetVel(Vector3f(1.0,0.0,0.0));
Ball *Yellowball = new Ball[8];
for(int i = BALL_YELLOW_START; i < BALL_YELLOW_START; i++)
{
Yellowball[0].SetPos(Vector3f (1,0,0));
Yellowball[1].SetPos(Vector3f (0,0,0));
Yellowball[2].SetPos(Vector3f (0,0,0));
Yellowball[3].SetPos(Vector3f (0,0,0));
Yellowball[4].SetPos(Vector3f (0,0,0));
Yellowball[5].SetPos(Vector3f (0,0,0));
Yellowball[6].SetPos(Vector3f (0,0,0));
Yellowball[7].SetPos(Vector3f (0,0,0));
}
//
//Ball Redball[8];
//
//for(int i = BALL_RED_START; i < BALL_RED_START; i++)
//{
// glColor3f(1,0,0);
// Redball[i].SetPos(Vector3f (i+128,RADIUS_OF_BALL,45));
//}
glEnable (GL_TEXTURE_2D);
Bitmap image;
image.loadBMP ("myTexture.bmp");
image.loadBMP ("myTexture2.bmp");
glGenTextures(2, &m_TextureID); // change to 2 for 2 textures
glBindTexture ( GL_TEXTURE_2D, m_TextureID);
glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE , GL_MODULATE);
glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
gluBuild2DMipmaps ( GL_TEXTURE_2D, 3, image.width, image.height, GL_RGB, GL_UNSIGNED_BYTE, image.data);
// Begin glut main loop
glutMainLoop();
}
void Display::DisplayScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the back buffer
glPushMatrix();
glLoadIdentity();
glNormal3f(0,1,0);
Vector3f redpos = Redball.GetPos();
gluLookAt(eyeX, eyeY, eyeZ, // eye position
0, 0, 0, // what I'm looking at
0.0, 1.0, 0); // Up direction
float Position[] = {lightX, lightY, lightZ, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, Position);
DrawLight(0, Position);
/* Rendering code goes here */
//Ball Redball[8];
//for (int i = BALL_RED_START; i<BALL_RED_END;i++)
//{
//
//float x = 0;
//glTranslatef(x+1,1,0);
//glColor3f(1,0,0);
//Redball[i].DrawRed();
//}
//glPopMatrix();
Redball.Draw();
glPushMatrix();
Ball Yellowball[8];
for (int i = BALL_YELLOW_START; i<BALL_YELLOW_END;i++)
{
glColor3f(2,1,0);
glTranslatef(1,0,0); //draws the array in a straight line
Yellowball[i].DrawYellow();
}
glPopMatrix();
drawcue();
drawTable();
drawTableLegFrontLeft();
drawTableLegFrontRight();
drawTableLegBackLeft();
drawTableLegBackRight();
drawCushions();
//drawCircle();
//drawHCircle();
Table(-2,-4.5,2,4.5); // Draws the table top in trianglestrip -4.5, 0.5, -0.5, 9.5
glPopMatrix();
glutSwapBuffers(); // Swap the front and back buffers
}
You create YellowBall arrays three times, set positions and then, well you loose the pointer to the arrays. You're not experiencing a OpenGL problem, but a lack of understanding how a program manages its data.
Also OpenGL has no persistency. It's just a sophisticated drawing API. Drawing commands will not be remembered.
A bit of advice: It seems you suffer from something I call "OOP induced blindnes": You tried to put everything into classes, while not understanding what's actually going on. Try to get rid of that Display class, there's little benefit having that one. Writing a class to manage geometry is not a bad idea by itself, but before you do that you must understand how OpenGL works and how data is passed around in a program. Passing class instances around is orders of degrees more difficult if you want to do it properly.

Drawing an array of objects in Open GL Glut

I have been trying to draw multiple balls for a game I am making, I have tried to get this working but there are problems in my init class and display method class, I have commented it where the errors are.
Ball.h:
#pragma once
#include "Vector2f.h"
#include "Vector3f.h"
class Ball
{
private:
Vector3f position;
Vector3f velocity;
public:
Ball(void);
~Ball(void);
void Draw();
void SetPos(Vector3f New_position);
void SetVel(Vector3f New_velocity);
Vector3f GetPos();
};
Ball.cpp
#include "Ball.h"
#include "Vector2f.h"
#include "Vector3f.h"
#include "Glut/glut.h"
#include "GL/gl.h"
#include "GL/glu.h"
Ball::Ball(void)
{
Vector3f Temp_position;
position = Temp_position;
Vector3f Temp_velocity;
velocity = Temp_velocity;
}
Ball::~Ball(void)
{
}
void Ball::SetPos(Vector3f New_position)
{
position = New_position;
}
void Ball::Draw()
{
glPushMatrix();
glTranslatef(position.X(), position.Y(), position.Z());
glColor3d(1, 0, 0);
glutSolidSphere(0.3, 50, 50);
glPopMatrix();
}
void Ball::SetVel(Vector3f New_velocity)
{
velocity = New_velocity;
}
Vector3f Ball::GetPos()
{
Vector3f temp;
temp = position;
return temp;
}
I want the be able to draw an array of the balls in Main.cpp
Main.cpp
#include "Display.h"
#include "Vector3f.h"
#include "Ball.h"
#include "Glut/glut.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include <math.h>
static float TableWidth = 4; // Z axis normal = 4
float Display::eyeX = -7.5; //-7.5
float Display::eyeY = 3; //3
float Display::eyeZ = 5; //5
float Display::Position[4] = { 1.0f, 0.0f, -3.5, 1.0f };
float Display::translateZ = -3.5;
float Display::translateX = 0.0;
//Timer Display::m_Timer = Timer();
float Display::lightX = 5.0; //5 2.5
float Display::lightY = 5.0;
float Display::lightZ = 2.5;
float m_TableX = -5.0f;
float m_TableZ = -2.5f;
float m_TableWidth = 2.5f;
float m_TableLength = 5.0f;
float ballx = 0.7;
float bally = 0.1;
float ballz = -0.7;
Ball Redball;
float BALL_RED_START = 0;
float RADIUS_OF_BALL = 0.3;
float BALL_RED_END = 8;
float m_ball;
void Display::Init(int argc, char ** argv)
{
glutInit(&argc, argv); // initializes glut
// sets display mode. These parameter set RGB colour model
// and double buffering.
glutInitWindowSize(500,500);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Pool Version 1.0");
// Set glut callback functions
glutDisplayFunc(Display::DisplayScene);
glutIdleFunc(Display::Idle);
glutReshapeFunc(Display::Resize);
glutKeyboardFunc(Display::KeyboardInput);
//m_Timer.getSeconds();
glEnable(GL_DEPTH_TEST);
glPointSize(5);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glClearColor(0,0,0,1);
glEnable(GL_COLOR_MATERIAL);
float white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
glEnable(GL_LIGHT0);
Redball.SetPos(Vector3f(0.0,0.3,0.0));
for(int i = BALL_RED_START; i < BALL_RED_START; i++)
{
glColor3f(1,0,0);
Redball[i]->SetPos(Vector3f (i+128,RADIUS_OF_BALL,45)); //I tried this but it doesn't work Error C2227
}
// Begin glut main loop
glutMainLoop();
}
void BallMovement()
{
//Vector3f position(0.0,0.3,0.0);
/*Redball.SetPos(Vector3f(0.0,0.3,0.0));*/
Vector3f New_velocity(0.01,0,0);
Redball.SetVel(New_velocity);
Vector3f New_position;
Vector3f Old_position;
Old_position = Redball.GetPos();
//New_position = Old_position + New_velocity;
New_position.SetX(Old_position.X() + New_velocity.X());
New_position.SetY(Old_position.Y() + New_velocity.Y());
New_position.SetZ(Old_position.Z() + New_velocity.Z());
Redball.SetPos(New_position);
}
void Display::DisplayScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the back buffer
glPushMatrix();
glLoadIdentity();
glNormal3f(0,1,0);
Vector3f didums = Redball.GetPos();
gluLookAt(eyeX, eyeY, eyeZ, // eye position
0, 0, 0, // what I'm looking at
0.0, 1.0, 0); // Up direction
float Position[] = {lightX, lightY, lightZ, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, Position);
DrawLight(0, Position);
/* Rendering code goes here */
for (int i = BALL_RED_START; i<BALL_RED_END;i++)
{
glColor3f(1,0,0);
Redball[i]->Draw(); //I tried this but it doesn't work Error C2227
}
drawTable();
drawTableLegFrontLeft();
drawTableLegFrontRight();
drawTableLegBackLeft();
drawTableLegBackRight();
drawCushions();
//drawCircle();
//drawHCircle();
Table(-2,-4.5,2,4.5); // Draws the table top in trianglestrip -4.5, 0.5, -0.5, 9.5
glPopMatrix();
glutSwapBuffers(); // Swap the front and back buffers
}
void Display::Resize(int w, int h)
{
/* Resize is called when window is resized */
glMatrixMode(GL_PROJECTION); // set matrix mode to profection
// this dictates how the 3d scene is "squashed" onto the 2d screen
glLoadIdentity();
glViewport(0, 0, w, h); // Set the part of the window to use.
gluPerspective(45, // field of view
(float)w/(float)h, // ration of window
1, // front clipping plane
1000 // back clipping plane
); // set the area in the 3d scene to draw
glMatrixMode(GL_MODELVIEW); // Setthe matrix mode to model view
// the matrix specifies how the 3d scene is viewed
/*glLoadIdentity();
gluLookAt(-3.5, 2, eyeZ, // eye position
1, 1, 0, // what I'm looking at
0.0, 1.0, 0); // Up direction*/
}
void Display::Idle()
{
/* When nothing else is happening, idle is called.
* Simulation should be done here and then
* the display method should be called
*/
BallMovement();
glutPostRedisplay();
}
I see you have declared Ball as Ball Redball; which will create a single Ball on the stack.
Then you attempt to treat it as a collection of Balls with Redball[i]->SetPos(...) and Redball[i]->Draw(). It appears you are attempting to work with 8 of them.
What you want to do is create an array of Balls, with a max size of 8 (according to BALL_RED_END). For simplicity, you could do
Ball RedBall[8];
for( //some conditions here )
{
RedBall[i].Draw();
}
as your declaration and usage.
Remember that anytime you use Redball.SetPos(...) will no longer be valid.

What is the best glMatrixMode() for using GLM?

my next question(or problem) in line is that when i load a model with glm, im able to see through parts of the model for example: if there were two mountains one in front of the other, i could see through the nearer mountain.
i would show a picture but it wouldnt be understandable since the texture doesnt work.
heres that problem here:
OLDER STUFF:vvvvvvvvvvvvvvvvvvvvvvv
all im wondering is: what is the best Matrix mode for using glm?
i have been used to GL_PROJECTION but its giving me too many problems when loading my model
and with GL_MODELVIEW im not able to move the camera back
i am also wondering: if i use GL_MODELVIEW, then how can i move the "camera" in the scene? is there a way to maybe setup one since ima have to eventually?
EDIT: alright heres some code to give you guys some kind of vision:
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <string>
#include <stdio.h>
#include <fstream>
#include <assert.h>
#include <vector>
#include <glm/glm.h>
#include <glm/glmint.h>
#include "Item.hpp"
#include "Player.hpp"
///GOLD WAVE
using namespace std;
///GLOBAL VARIABLES
vector<sf::Sprite> SpriteList;
vector<GLMmodel*> ModelList;
vector<GLuint> _texture;
vector<Item*> DefItemList;
Player *pPlayer=new Player();
sf::RenderWindow GameWind(sf::VideoMode(800,600,32),"Carperon Game Window",sf::Style::Titlebar);
sf::View GameView(sf::FloatRect(0,0,25,18.75));//65x45 and 8x 0,0,65,45
///PROTOTYPE FUNCTIONS
void SFMLcreate();
void SFMLdraw();
void GLMcreate();
void GLdraw();
GLuint LoadTexture();
void GLiniti();
void ITEMdefault();
///////////////////////////////////STOP PROTOTYPES//////////////////////////////
//////////////////////////////////FUNCTIONS//////////////////////////////////
int main()
{
GLiniti();
SFMLcreate();
GLMcreate();
ITEMdefault();
sf::Event EventMain;
vector<sf::Sprite> ShowingBag;
sf::Image isbItem[45],iseItem[6];
sf::Sprite sbItem[45],seItem[6];
int BagSlotX[45] {0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30,0,15,30};
int BagSlotY[45] {0,0,0,15,15,15,30,30,30,0,0,0,15,15,15,30,30,30,0,0,0,15,15,15,30,30,30,0,0,0,15,15,15,30,30,30,0,0,0,15,15,15,30,30,30};
int EquipSlotY[6] {0,15,30,0,15,30};
bool BagUpdate = true;
int click = 0;
///MAIN PLAYER
pPlayer->PlayerCreate("Molma");
pPlayer->EquipFill(DefItemList[0]);
pPlayer->AddItem(DefItemList[1]);
pPlayer->AddItem(DefItemList[2]);
pPlayer->AddItem(DefItemList[3]);
pPlayer->AddItem(DefItemList[4]);
while(GameWind.IsOpened())
{
while(GameWind.GetEvent(EventMain))
{
//If its closed
if(EventMain.Type==sf::Event::Closed)
{
//Close the whole thing!
//GameWind.Close();
GameWind.Close();
}
}
float MouseX = (GameWind.GetInput().GetMouseX()/32.f);
float MouseY = (GameWind.GetInput().GetMouseY()/32.f);
if(GameWind.GetInput().IsKeyDown(sf::Key::Escape))
{
GameWind.Close();
//GameWind.Close();
}
/////////////////////////////BEGIN INPUT/////////////////////////////////////////////////
if(GameWind.GetInput().IsKeyDown(sf::Key::Return))
{
pPlayer->RandHealth();
BagUpdate = true;
}
if(GameWind.GetInput().IsKeyDown(sf::Key::Z))
{
pPlayer->GetHit();
}
if(GameWind.GetInput().IsMouseButtonDown(sf::Mouse::Right)&&click<=0)
{
for(int a=0;a<pPlayer->Bag.size();++a)
{
if(MouseX>((17.f+(BagSlotX[a]))/16.f)&&MouseX<(((32.f+(BagSlotX[a]))/16.f))&&MouseY>((60.f+(BagSlotY[a]))/16.f)&&MouseY<(((75.f+(BagSlotY[a]))/16.f)))
{
pPlayer->ItemUse(pPlayer->Bag[a],a);
BagUpdate = true;
click=20;
//cout << "Item used!" << endl;
}
}
for(int b=0;b<6;++b)
{
if(MouseX>2.f/16.f&&MouseX<17.f/16.f&&MouseY>((60.f+(EquipSlotY[b]))/16.f)&&MouseY<((75.f+(EquipSlotY[b]))/16.f)&&pPlayer->EqSpot[b]->get_Type()!="Blank Spot")
{
pPlayer->Unequip(pPlayer->EqSpot[b],DefItemList[0],b);
BagUpdate = true;
click=20;
}
}
}
///////////////////////////////END INPUT/////////////////////////////////////////////////
//////////////////////////////AUTO FUNCTIONS//////////////////////////////////////////////
pPlayer->Guarding();
pPlayer->HitTiming();
if(BagUpdate)
{
for(int a=0;a<pPlayer->Bag.size();++a)
{
isbItem[a].LoadFromFile("Graphics/Items.png");
sbItem[a].SetImage(isbItem[a]);
sbItem[a].SetPosition(((17.f+(BagSlotX[a]))/16.f),((60.f+(BagSlotY[a]))/16.f));
}
for(int b=0;b<6;++b)
{
iseItem[b].LoadFromFile("Graphics/Items.png");
seItem[b].SetImage(iseItem[b]);
seItem[b].SetPosition(2.f/16.f,((60.f+(EquipSlotY[b]))/16.f));
}
BagUpdate=false;
}
if(click>0)
{
click-=1;
}
SpriteList[22].SetPosition(MouseX,MouseY);
GameWind.SetView(GameView);
GLdraw();
SFMLdraw();
for(int a=((pPlayer->get_BagShow())*9);a<((pPlayer->get_BagShow()*9)+9);++a)//18-27=A
{
if(a<pPlayer->Bag.size())
{
sbItem[a].Resize(15.f/16.f,15.f/16.f);
sbItem[a].SetSubRect(sf::IntRect((pPlayer->Bag[a]->get_Index()*15),0,((pPlayer->Bag[a]->get_Index()*15)+15),15));
GameWind.Draw(sbItem[a]);
//cout << "Items Drawn! Position: " << BagSlotX[a] << "," << BagSlotY[a] << "Item: " << a << endl;
//image pos resize subrect
}
}
for(int b=((pPlayer->get_EquipShow())*3);b<((pPlayer->get_EquipShow()*3)+3);++b)
{
seItem[b].Resize(15.f/16.f,15.f/16.f);
seItem[b].SetSubRect(sf::IntRect((pPlayer->EqSpot[b]->get_Index()*15),0,((pPlayer->EqSpot[b]->get_Index()*15)+15),15));
GameWind.Draw(seItem[b]);
}
GameWind.Draw(SpriteList[16]);
GameWind.Draw(SpriteList[20]);
GameWind.Draw(SpriteList[21]);
GameWind.Draw(SpriteList[22]);
GameWind.Display();
GameWind.SetFramerateLimit(60);
}
return EXIT_SUCCESS;
}
void SFMLcreate()
{
sf::Image iStatBack,iStatWindow,ipHealth,ipEnergy,ipStr,ipDex,ipInt,ipEnd,ipCrit,ipSwd,ipAxe,ipBow,ipStar,ipWand,ipStaff,ipBag,ipEquip,ipSkills,ipNumHP,ipNumEP,ipGuard,ipRank,ipRankXP,iCursor;
sf::Sprite StatBack,StatWindow,pHealth,pEnergy,pStr,pDex,pInt,pEnd,pCrit,pSwd,pAxe,pBow,pStar,pWand,pStaff,pBag,pEquip,pSkills,pNumHP,pNumEP,pGuard,pRank,pRankXP,Cursor;
sf::Font MainFont;
//LoadFromFile
iStatBack.LoadFromFile("Graphics/Player Stats/Stats Back.png");
iStatWindow.LoadFromFile("Graphics/Player Stats/StatWindow2.png");
ipHealth.LoadFromFile("Graphics/Player Stats/Health.png");
ipEnergy.LoadFromFile("Graphics/Player Stats/Energy.png");
ipStr.LoadFromFile("Graphics/Player Stats/Strength.png");
ipDex.LoadFromFile("Graphics/Player Stats/Dexterity.png");
ipInt.LoadFromFile("Graphics/Player Stats/Intellegence.png");
ipEnd.LoadFromFile("Graphics/Player Stats/Endurance.png");
ipCrit.LoadFromFile("Graphics/Player Stats/Critical.png");
ipSwd.LoadFromFile("Graphics/Player Stats/Sword Mast.png");
ipAxe.LoadFromFile("Graphics/Player Stats/Axe Mast.png");
ipBow.LoadFromFile("Graphics/Player Stats/Bow Mast.png");
ipStar.LoadFromFile("Graphics/Player Stats/Star Mast.png");
ipWand.LoadFromFile("Graphics/Player Stats/Wand Mast.png");
ipStaff.LoadFromFile("Graphics/Player Stats/Staff Mast.png");
ipBag.LoadFromFile("Graphics/Player Stats/Bag.png");
ipEquip.LoadFromFile("Graphics/Player Stats/Bag.png");
ipSkills.LoadFromFile("Graphics/Player Stats/Skill.png");
ipNumHP.LoadFromFile("Graphics/Player Stats/Number HE.png");
ipNumEP.LoadFromFile("Graphics/Player Stats/Number HE.png");
ipGuard.LoadFromFile("Graphics/Player Stats/Guard.png");
ipRank.LoadFromFile("Graphics/Player Stats/Rank.png");
ipRankXP.LoadFromFile("Graphics/Player Stats/RankXP.png");
iCursor.LoadFromFile("Graphics/Cursor.png");
//SetSmooth()
ipStr.SetSmooth(false);
ipDex.SetSmooth(false);
ipInt.SetSmooth(false);
ipEnd.SetSmooth(false);
ipCrit.SetSmooth(false);
ipSwd.SetSmooth(false);
ipAxe.SetSmooth(false);
ipBow.SetSmooth(false);
ipStar.SetSmooth(false);
ipWand.SetSmooth(false);
ipStaff.SetSmooth(false);
ipSkills.SetSmooth(false);
ipHealth.SetSmooth(false);
ipEnergy.SetSmooth(false);
ipGuard.SetSmooth(false);
ipNumHP.SetSmooth(false);
ipNumEP.SetSmooth(false);
ipRankXP.SetSmooth(false);
ipRank.SetSmooth(false);
//SetImage!!
StatBack.SetImage(iStatBack);
StatWindow.SetImage(iStatWindow);
pHealth.SetImage(ipHealth);
pEnergy.SetImage(ipEnergy);
pStr.SetImage(ipStr);
pDex.SetImage(ipDex);
pInt.SetImage(ipInt);
pEnd.SetImage(ipEnd);
pCrit.SetImage(ipCrit);
pSwd.SetImage(ipSwd);
pAxe.SetImage(ipAxe);
pBow.SetImage(ipBow);
pStar.SetImage(ipStar);
pWand.SetImage(ipWand);
pStaff.SetImage(ipStaff);
pBag.SetImage(ipBag);
pEquip.SetImage(ipEquip);
pSkills.SetImage(ipSkills);
pNumHP.SetImage(ipNumHP);
pNumEP.SetImage(ipNumEP);
pGuard.SetImage(ipGuard);
pRank.SetImage(ipRank);
pRankXP.SetImage(ipRankXP);
Cursor.SetImage(iCursor);
//SetPosition(x,y)!!
StatBack.SetPosition(0,0);
StatWindow.SetPosition(-5.f/16.f,-5.f/16.f);
pHealth.SetPosition(5.f/16.f,23.25f/16.f);
pEnergy.SetPosition(5.f/16.f,31.5f/16.f);
pStr.SetPosition(59.f/16.f,23.f/16.f);
pDex.SetPosition(59.f/16.f,35.f/16.f);
pInt.SetPosition(59.f/16.f,47.f/16.f);
pEnd.SetPosition(3.f/16.f,37.f/16.f);
pCrit.SetPosition(32.f/16.f,37.f/16.f);
pSwd.SetPosition(63.f/16.f,21.f/16.f);
pAxe.SetPosition(63.f/16.f,29.f/16.f);
pBow.SetPosition(63.f/16.f,33.f/16.f);
pStar.SetPosition(63.f/16.f,41.f/16.f);
pWand.SetPosition(63.f/16.f,45.f/16.f);
pStaff.SetPosition(63.f/16.f,53.f/16.f);
pBag.SetPosition(2.f/16.f,60.f/16.f);
pEquip.SetPosition(2.f/16.f,60.f/16.f);
pSkills.SetPosition(71.f/16.f,61.f/16.f);
pNumHP.SetPosition(4.f/16.f,22.f/16.f);
pNumEP.SetPosition(4.f/16.f,30.f/16.f);
pGuard.SetPosition(4.f/16.f,22.5f/16.f);
pRank.SetPosition(41.5f/16.f,25.f/16.f);
pRankXP.SetPosition(39.5f/16.f,23.f/16.f);
//VECTOR STORE
SpriteList.push_back(StatWindow);
SpriteList.push_back(pHealth);
SpriteList.push_back(pEnergy);
SpriteList.push_back(pStr);
SpriteList.push_back(pDex);
SpriteList.push_back(pInt);
SpriteList.push_back(pEnd);
SpriteList.push_back(pCrit);
SpriteList.push_back(pSwd);
SpriteList.push_back(pAxe);
SpriteList.push_back(pBow);
SpriteList.push_back(pStar);
SpriteList.push_back(pWand);
SpriteList.push_back(pStaff);
SpriteList.push_back(pBag);
SpriteList.push_back(pEquip);
SpriteList.push_back(pSkills);
SpriteList.push_back(pNumHP);
SpriteList.push_back(pNumEP);
SpriteList.push_back(pGuard);
SpriteList.push_back(pRank);
SpriteList.push_back(pRankXP);
SpriteList.push_back(Cursor);
}
void SFMLdraw()
{
//////////////////////////////STAT RESIZE/SUBRECT///////////////////////////////////////
SpriteList[1].SetSubRect(sf::IntRect(0,0,120,12)); //30,3
SpriteList[2].SetSubRect(sf::IntRect(0,0,120,12)); //30,3
SpriteList[3].SetSubRect(sf::IntRect(pPlayer->get_Str()*28,0,(pPlayer->get_Str()*28)+28,7)); //28,7
SpriteList[4].SetSubRect(sf::IntRect(pPlayer->get_Dex()*28,0,(pPlayer->get_Dex()*28)+28,7)); //28,7
SpriteList[5].SetSubRect(sf::IntRect(pPlayer->get_Int()*28,0,(pPlayer->get_Int()*28)+28,7)); //28,7
SpriteList[6].SetSubRect(sf::IntRect(pPlayer->get_End()*28,0,(pPlayer->get_End()*28)+28,7)); //28,7
SpriteList[7].SetSubRect(sf::IntRect(pPlayer->get_Crit()*28,0,(pPlayer->get_Crit()*28)+28,7)); //28,7
SpriteList[8].SetSubRect(sf::IntRect(pPlayer->get_Sword()*18,0,(pPlayer->get_Sword()*18)+18,3)); //18,3
SpriteList[9].SetSubRect(sf::IntRect(pPlayer->get_Axe()*18,0,(pPlayer->get_Axe()*18)+18,3)); //18,3
SpriteList[10].SetSubRect(sf::IntRect(pPlayer->get_Bow()*18,0,(pPlayer->get_Bow()*18)+18,3)); //18,3
SpriteList[11].SetSubRect(sf::IntRect(pPlayer->get_Star()*18,0,(pPlayer->get_Star()*18)+18,3)); //18,3
SpriteList[12].SetSubRect(sf::IntRect(pPlayer->get_Wand()*18,0,(pPlayer->get_Wand()*18)+18,3)); //18,3
SpriteList[13].SetSubRect(sf::IntRect(pPlayer->get_Staff()*18,0,(pPlayer->get_Staff()*18)+18,3)); //18,3
SpriteList[14].SetSubRect(sf::IntRect((pPlayer->get_BagShow()*60)+120,0,(pPlayer->get_BagShow()*60)+180,48));
SpriteList[15].SetSubRect(sf::IntRect(pPlayer->get_EquipShow()*60,0,(pPlayer->get_EquipShow()*60)+60,48));
SpriteList[16].SetSubRect(sf::IntRect(pPlayer->get_SkillShow()*30,0,(pPlayer->get_SkillShow()*30)+30,64));
SpriteList[17].SetSubRect(sf::IntRect(pPlayer->get_Health()*7,0,(pPlayer->get_Health()*7)+7,5));
SpriteList[18].SetSubRect(sf::IntRect(pPlayer->get_Energy()*7,0,(pPlayer->get_Energy()*7)+7,5));
SpriteList[19].SetSubRect(sf::IntRect(0,0,128,20));
SpriteList[20].SetSubRect(sf::IntRect(pPlayer->get_Rank()*14,0,(pPlayer->get_Rank()*14)+14,6));//10
SpriteList[21].SetSubRect(sf::IntRect(pPlayer->get_tRankXPN()*18,0,(pPlayer->get_tRankXPN()*18)+18,10));//16
/////////////////////RESIZE PART
SpriteList[0].Resize(410.f/16.f,310.f/16.f);
SpriteList[1].Resize(pPlayer->get_tHealth()/64.f,12.f/64.f);
SpriteList[2].Resize(pPlayer->get_tEnergy()/64.f,12.f/64.f);
SpriteList[3].Resize(28.f/16.f,7.f/16.f);
SpriteList[4].Resize(28.f/16.f,7.f/16.f);
SpriteList[5].Resize(28.f/16.f,7.f/16.f);
SpriteList[6].Resize(28.f/16.f,7.f/16.f);
SpriteList[7].Resize(28.f/16.f,7.f/16.f);
SpriteList[8].Resize(18.f/16.f,3.f/16.f);
SpriteList[9].Resize(18.f/16.f,3.f/16.f);
SpriteList[10].Resize(18.f/16.f,3.f/16.f);
SpriteList[11].Resize(18.f/16.f,3.f/16.f);
SpriteList[12].Resize(18.f/16.f,3.f/16.f);
SpriteList[13].Resize(18.f/16.f,3.f/16.f);
SpriteList[14].Resize(60.f/16.f,48.f/16.f);
SpriteList[15].Resize(60.f/16.f,48.f/16.f);
SpriteList[16].Resize(30.f/16.f,64.f/16.f);
SpriteList[17].Resize(7.f/16.f,5.f/16.f);
SpriteList[18].Resize(7.f/16.f,5.f/16.f);
SpriteList[19].Resize(pPlayer->get_tGuard()/64.f,20.f/64.f);
SpriteList[20].Resize(14.f/16.f,6.f/16.f);
SpriteList[21].Resize(18.f/16.f,10.f/16.f);
SpriteList[22].Resize(15.f/16.f,15.f/16.f);
///////////////////////////////////END RESIZE/SUBRECT!!!////////////////////////////////
////////////////////////////////////DONT TOUCH/////////////////////////////////////////
///////////////////////////////NOW YOU CAN TOUCH//////////////////////////////////////////
//////////////////////////////DRAW STARTS///////////////////////////////////////////////
GameWind.Draw(SpriteList[0]);
GameWind.Draw(SpriteList[19]);
GameWind.Draw(SpriteList[1]);
GameWind.Draw(SpriteList[17]);
GameWind.Draw(SpriteList[2]);
GameWind.Draw(SpriteList[18]);
GameWind.Draw(SpriteList[3]);
GameWind.Draw(SpriteList[4]);
GameWind.Draw(SpriteList[5]);
GameWind.Draw(SpriteList[6]);
GameWind.Draw(SpriteList[7]);
GameWind.Draw(SpriteList[8]);
GameWind.Draw(SpriteList[9]);
GameWind.Draw(SpriteList[10]);
GameWind.Draw(SpriteList[11]);
GameWind.Draw(SpriteList[12]);
GameWind.Draw(SpriteList[13]);
GameWind.Draw(SpriteList[14]);
GameWind.Draw(SpriteList[15]);
}
void GLMcreate()
{
GLMmodel* World = glmReadOBJ("3Dobject/WorldMap3Dv1.obj");
glmUnitize(World);
glmScale(World,1);
}
void GLdraw()
{
GameWind.SetActive();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
////////AMBIENT LIGHT
GLfloat AmbientColor[] = {0.05f,0.05f,0.2f,1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,AmbientColor);
////////POSITIONED LIGHT
GLfloat LightColor0[] = {0.5f,0.5f,0.5f,1.0f};
GLfloat LightPos0[] = {4.0f,4.0f,0.0f,1.0f};
glLightfv(GL_LIGHT0,GL_DIFFUSE,LightColor0);
glLightfv(GL_LIGHT0,GL_POSITION,LightPos0);
////////DIRECTED LIGHT
GLfloat LightColor1[] = {0.9f,0.9f,0.6f,1.0f};
/////Coming from direction (x,y,z)
GLfloat LightPos1[] = {-1.0f,0.5f,0.5f,0.0f};
glLightfv(GL_LIGHT1,GL_DIFFUSE,LightColor1);
glLightfv(GL_LIGHT1,GL_POSITION,LightPos1);
///DRAWING MODELS
}
void GLiniti()
{
GameWind.PreserveOpenGLStates(true);
GameWind.ShowMouseCursor(false);
glClearDepth(1.f);
glClearColor(0.2f,0.2f,0.8f,1.f);
/////z buffer
glEnable(GL_POLYGON_STIPPLE);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHT1);
glEnable(GL_NORMALIZE);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glCullFace(GL_FRONT);
glFrontFace(GL_CW);
glShadeModel(GL_SMOOTH);
glDepthMask(GL_TRUE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.f,(double)800 / (double)600,200.f,0.f);
glTranslatef(0.f, 0.f, -10.0f);
}
GLuint LoadTexture(sf::Image image)
{
GLuint Texture;
glGenTextures(1, &Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA,image.GetWidth(),image.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE,image.GetPixelsPtr());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
return Texture;
}
void ITEMdefault()
{
Blank *BlankSpot=new Blank();
BlankSpot->ItemCreate(0,0,0,0,0,0,0);
///TEST ITEMS
Weapon *sword=new Weapon();
sword->ItemCreate(0,0,0,sf::Randomizer::Random(0,5),1,0,sf::Randomizer::Random(1,4));
Armor *sword2=new Armor();
sword2->ItemCreate(0,0,0,sf::Randomizer::Random(0,5),2,0,sf::Randomizer::Random(1,4));
Necklace *sword3=new Necklace();
sword3->ItemCreate(0,0,0,sf::Randomizer::Random(0,5),3,0,sf::Randomizer::Random(1,4));
Consume *hppotion=new Consume();
hppotion->ItemCreate(0,0,0,6,83,0,6);
DefItemList.push_back(BlankSpot);
DefItemList.push_back(sword);
DefItemList.push_back(sword2);
DefItemList.push_back(sword3);
DefItemList.push_back(hppotion);
}
There is not one certain matrix mode you switch OpenGL too. I explained it already in this post OpenGL: What is MatrixMode? , which I'll simple copy here:
OpenGL uses several matrices to transform geometry and associated data. Those matrices are:
Modelview – places object geometry in the global, unprojected space
Proection – projects global coordinates into clip space; you may think of it as kind of a lens
Texture – adjusts texture coordinates before; mostly used to implement texture projection (i.e. projecting a texture as if it was a slide in a projector)
Color – adjusts the vertex colors. Seldomly touched at all
All these matrices are used all the time. Since they follow all the same rules OpenGL has only one set of matrix manipulation functions: glPushMatrix, glPopMatrix, glLoadIdentity, glLoadMatrix, glMultMatrix, glTranslate, glRotate, glScale, glOrtho, glFrustum.
glMatrixMode selects on which matrix those operations act upon. Say you wanted to write some C++ namespacing wrapper, it could look like this:
namespace OpenGL {
// A single template class for easy OpenGL matrix mode association
template<GLenum mat> class Matrix
{
public:
void LoadIdentity() const
{ glMatrixMode(mat); glLoadIdentity(); }
void Translate(GLfloat x, GLfloat y, GLfloat z) const
{ glMatrixMode(mat); glTranslatef(x,y,z); }
void Translate(GLdouble x, GLdouble y, GLdouble z) const
{ glMatrixMode(mat); glTranslated(x,y,z); }
void Rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) const
{ glMatrixMode(mat); glRotatef(angle, x, y, z); }
void Rotate(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) const
{ glMatrixMode(mat); glRotated(angle, x, y, z); }
// And all the other matrix manipulation functions
// using overloading to select proper OpenGL variant depending on
// function parameters, and all the other C++ whiz.
// ...
};
//
const Matrix<GL_MODELVIEW> Modelview;
const Matrix<GL_PROJECTION> Projection;
const Matrix<GL_TEXTURE> Texture;
const Matrix<GL_COLOR> Color;
}
Later on in a C++ program you could write then
void draw_something()
{
OpenGL::Projection::LoadIdentity();
OpenGL::Projection::Frustum(...);
OpenGL::Modelview::LoadIdentity();
OpenGL::Modelview::Translate(...);
// drawing commands
}
Unfortunately C++ can't template namespaces, or apply using (or with) on instances (other languages have this), otherwise I'd had written something like (invalid C++)
void draw_something_else()
{
using namespace OpenGL;
with(Projection) { // glMatrixMode(GL_PROJECTION);
LoadIdentity(); // glLoadIdentity();
Frustum(...); // glFrustum(...);
}
with(Modelview) { // glMatrixMode(GL_MODELVIEW);
LoadIdentity(); // glLoadIdentity();
Translate(...); // glTranslatef(...);
}
}
I think this last snipped of (pseudo-)code makes it clear: glMatrixMode is kind of a with statement of OpenGL.
All the matrices are used during rendering!
You move the camera by using glTranslate().