-
May 8th, 2013, 05:02 AM
#1
how do i convert xml attributes to c++ class using tinyxml
Hey i am trying to create a firework display by reading in the fireworks off a .xml file, which will then iterate through and launch each firework.
I followed a tutorial on dinomage to find out how to use tinyxml, i learnt that i can store the attributes into char pointers but i dont know how to convert them to GLfloats to store them in my class variables.
I did try using atof but when i ran the program i got loads of errors which im guessing is because the pointer only stores the address which im passing to my variable.
can anybody point out where im going wrong and how i can go about fixing the issue?
Update
i have found out that tinyxml is not compatible with vs2010 but tinyxml 2 is, so i have changed my code but am still having trouble loading my attributes i have added error checking, and it prints out that the xml has loaded but then it wont load the root
updated code
my code: Firework.h
Code:
#ifndef FIREWORK_H
#define FIREWORK_H
#include <cstdlib>
#include <GL\GL.h>
#include <string>
const GLint particles= 50;
class Firework
{
public:
GLint x[particles];
GLint y[particles];
GLint VelX[particles];
GLint VelY[particles];
GLint Xpos;
GLint Ypos;
GLint Xspeed;
GLint Yspeed;
unsigned char red;
unsigned char blue;
unsigned char green;
GLfloat alpha;
GLfloat redStart;
GLfloat blueStart;
GLfloat greenStart;
std::string hexColour;
std::string type;
GLint timeUntilLaunch;
GLint startTime;
GLint endTime;
GLint duration;
GLfloat particleSize;
GLboolean hasExploded;
GLboolean rocket, fountain;
static const GLfloat gravity;
static const GLfloat baseYSpeed;
static const GLfloat maxYSpeed;
Firework();
void initialise();
void move();
void explode();
};
#endif
Firework.ccp
Code:
#include "Firework.h"
#include "tinyxml2.h"
#include<time.h>
#include <string>
#include<iostream>
#include <vector>
using namespace std;
const GLfloat Firework::gravity = 0.05f;
const GLfloat Firework::baseYSpeed = -4.0f;
const GLfloat Firework::maxYSpeed = -4.0f;
//int QueryAttributeStatus = elem->FirstChildElement("begin")- >QueryFloatAttribute(attr,&timeUntillLaunch);
int convertFromHex(string hex)
{
int value = 0;
int a = 0;
int b = hex.length() - 1;
for (; b >= 0; a++, b--)
{
if (hex[b] >= '0' && hex[b] <= '9')
{
value += (hex[b] - '0') * (1 << (a * 4));
}
else
{
switch (hex[b])
{
case 'A':
case 'a':
value += 10 * (1 << (a * 4));
break;
case 'B':
case 'b':
value += 11 * (1 << (a * 4));
break;
case 'C':
case 'c':
value += 12 * (1 << (a * 4));
break;
case 'D':
case 'd':
value += 13 * (1 << (a * 4));
break;
case 'E':
case 'e':
value += 14 * (1 << (a * 4));
break;
case 'F':
case 'f':
value += 15 * (1 << (a * 4));
break;
default:
cout << "Error, invalid charactare '" << hex[a] << "' in hex number" << endl;
break;
}
}
}
return value;
}
void hextodec(string hex, vector<unsigned char>& rgb)
{
/*
since there is no prefix attached to hex, use this code
string redString = hex.substr(0, 2);
string greenString = hex.substr(2, 2);
string blueString = hex.substr(4, 2);
*/
/*
if the prefix # was attached to hex, use the following code
string redString = hex.substr(1, 2);
string greenString = hex.substr(3, 2);
string blueString = hex.substr(5, 2);
*/
//if the prefix 0x was attached to hex, use the following code
string redString = hex.substr(2, 2);
string greenString = hex.substr(4, 2);
string blueString = hex.substr(6, 2);
unsigned char red = (unsigned char)(convertFromHex(redString));
unsigned char green = (unsigned char)(convertFromHex(greenString));
unsigned char blue = (unsigned char)(convertFromHex(blueString));
rgb[0] = red;
rgb[1] = green;
rgb[2] = blue;
}
Firework::Firework()
{
initialise();
}
void Firework::initialise()
{
tinyxml2::XMLDocument doc;
doc.LoadFile( "fireworks.xml");
if (!doc.LoadFile("fireworks.xml"))
{
std::cout<<"Failed to load file: no xml"<<endl;
}
else
std::cout<<"loaded xml"<<endl;
tinyxml2::XMLElement * root = doc.FirstChildElement();
if (root == NULL)
{
std::cout<<"Failed to load file: no root element."<<endl;
}
else
std::cout<<"root node loaded"<<endl;
for (tinyxml2::XMLElement* elem = root ->FirstChildElement(); elem!=NULL; elem = elem->NextSiblingElement())
{
string elemName = elem->Value();
const char* attr;
if (elemName == "Firework")
{
attr = elem->Attribute("begin");
if(attr != NULL)
{
elem->QueryIntAttribute("begin",&startTime);
}
attr = elem->Attribute("type");
if (attr != NULL)
{
type = elem->GetText();
if (type != "")
std::cout<<"have something"<<endl;
}
attr = elem ->Attribute("colour");
if (attr !=NULL)
{
hexColour= elem->GetText();
vector<unsigned char> rgbColor(3);
hextodec(hexColour,rgbColor);
red =int(rgbColor[0]);
blue = int(rgbColor[1]);
green= int(rgbColor[2]);
}
attr = elem->Attribute("duration");
if (attr !=NULL)
{
elem->QueryIntAttribute("duration", &endTime);
}
for (tinyxml2::XMLElement * e =elem ->FirstChildElement("Position"); e != NULL; e = e->NextSiblingElement("Position"))
{
attr = e->Attribute("x");
if (attr != NULL)
{
Xpos = e->QueryIntAttribute("x", &Xpos);
}
attr = e->Attribute("y");
if (attr != NULL)
{
Ypos = e->QueryIntAttribute("y", &Ypos);
}
}
for(tinyxml2::XMLElement * v =elem ->FirstChildElement("Velocity"); v !=NULL; v = v->NextSiblingElement("Velocity"))
{
attr = v -> Attribute("x");
if (attr != NULL)
{
Xspeed = v ->QueryIntAttribute("x", &Xspeed);
}
attr = v ->Attribute ("y");
if (attr !=NULL)
{
Yspeed = v ->QueryIntAttribute("y", &Yspeed);
}
}
}
}
//Setting initial x/y locations and speeds for each particle
for (int loop = 0; loop < particles; loop++)
{
x[loop] = Xpos;
y[loop] = Ypos;
VelX[loop] = Xspeed;
VelY[loop] = Yspeed;
}
//intiallising the colour and full alpha
redStart = 0.85f;//((float)rand() / (float)RAND_MAX);
greenStart = 0.55f;//((float)rand() / (float)RAND_MAX);
blueStart = 0.01f;//((float)rand() / (float)RAND_MAX);
alpha = 1.0f;
timeUntilLaunch = startTime;
duration = endTime;
particleSize = 1.0f + ((float)rand()/(float)RAND_MAX)* 3.0f;
hasExploded = false;
}
void Firework::move()
{
for (int loop = 0; loop < particles; loop++)
{
if (timeUntilLaunch <= 0)
{
x[loop] += VelX [loop];
y[loop] += VelY [loop];
VelY[loop] += Firework::gravity;
duration --;
}
}
timeUntilLaunch --;
if (duration <= 0)
{
for (int loop2 = 0; loop2 < particles; loop2++)
{
VelX[loop2] = -4 + (rand() / (int)RAND_MAX)*8;
VelY[loop2] = -4 + (rand() / (int)RAND_MAX)*8;
}
hasExploded = true;
}
}
void Firework::explode()
{
for (int loop = 0; loop < particles; loop++)
{
// Dampen the horizontal speed by 1% per frame
VelX[loop] *= 0.99f;
// Move the particle
x[loop] += VelX[loop];
y[loop] += VelY[loop];
// Apply gravity to the particle's speed
VelY[loop] += Firework::gravity;
}
// Fade out the particles (alpha is stored per firework, not per particle)
if (alpha > 0.0f)
{
alpha -= 0.01f;
}
else // Once the alpha hits zero, then reset the firework
{
initialise();
}
}
Main.ccp
Code:
#include <iostream>
#include <ctime>
#include <time.h>
#include <windows.h> // *** IMPORTANT: Uncomment for Win32 systems - This must come -BEFORE- gl.h in the include list! ***
#include "GL\glfw.h"
#include "Firework.h"
#include <GL\GL.h>
#include <GL/glu.h>
#include "tinyxml2.h"
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "lib/glfw/GLFW.lib")
using namespace std;
GLint windowWidth = 1024;
GLint windowHeight = 600;
GLint frameCount =0;
GLint texture;
const int FIREWORKS = 15; // Number of fireworks
Firework fw[FIREWORKS];
void initGL()
{
glfwSwapInterval(1);
glfwSetWindowTitle("Fireworks");
glViewport(0, 0, (GLsizei)windowWidth, (GLsizei)windowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, windowWidth, windowHeight, 0, 0, 1);
glShadeModel(GL_SMOOTH);
// Set our clear colour to opaque black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Disable depth testing (because we're working in 2D!)
glDisable(GL_DEPTH_TEST);
// Enable blending (we need this to be able to use an alpha component)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Set the accumulation buffer clearing colour to opaque black
glClearAccum(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_POINT_SMOOTH);
}
void drawScene()
{
// Take the contents of the current accumulation buffer and copy it to the colour buffer so that it entirely overwrites it
glAccum(GL_RETURN, 1.0f);
// Clear the accumulation buffer (don't worry, we re-grab the screen into the accumulation buffer after drawing our current frame!)
glClear(GL_ACCUM_BUFFER_BIT);
// Set ModelView matrix mode and reset to the default identity matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Displacement trick for exact pixelisation
glTranslatef(0.375, 0.375, 0);
// Draw our fireworks
for (int loop = 0; loop < FIREWORKS; loop++)
{
for (int particleLoop = 0; particleLoop < particles; particleLoop++)
{
// Set the point size of the firework particles (this needs to be called BEFORE opening the glBegin(GL_POINTS) section!)
glPointSize(fw[loop].particleSize);
glBegin(GL_POINTS);
// Set colour to yellow on the way up, then whatever colour firework should be when exploded
if (fw[loop].hasExploded == false)
{
glColor4f(fw[loop].redStart, fw[loop].greenStart, fw[loop].blueStart, 1.0f);
}
else
{
glColor4f(fw[loop].red, fw[loop].green, fw[loop].blue, fw[loop].alpha);
}
// Draw the point
glVertex2f(fw[loop].x[particleLoop], fw[loop].y[particleLoop]);
glEnd();
}
// Move the firework appropriately depending on its explosion state
if (fw[loop].hasExploded == false && fw[loop].type=="Rocket")
{
fw[loop].move();
}
else
{
fw[loop].explode();
}
}
glAccum(GL_ACCUM, 0.85f);
glfwSwapBuffers();
}
int main()
{
int srand((unsigned)time(NULL)); // Seed the random number generator
// Define our buffer settings
int redBits = 8, greenBits = 8, blueBits = 8;
int alphaBits = 64, depthBits = 24, stencilBits = 8;
// Flag to keep our main loop running
bool running = true;
// Initialise glfw
glfwInit();
// Create a window
if(!glfwOpenWindow(windowWidth, windowHeight, redBits, greenBits, blueBits, alphaBits, 0, 0, GLFW_WINDOW))
{
cout << "Failed to open window!" << endl;
glfwTerminate();
return 0;
}
// Call our initGL function to set up our OpenGL options
initGL();
while (running == true)
{
// Draw our scene
drawScene();
// Increase our frame counter
frameCount++;
// Exit if ESC was pressed or the window was closed
running = glfwGetWindowParam(GLFW_OPENED);
}
glfwTerminate();
return 0;
}
firework.xml
Code:
<?xml version="1.0" ?>
<FireworkDisplay>
<Firework begin="1000" type="Fountain" colour="0x20FF40" duration="5000">
<Position x="0" y="-384"/>
</Firework>
<Firework begin="2000" type="Fountain" colour="0x4020FF" duration="4000">
<Position x="100" y="-384"/>
</Firework>
<Firework begin="3000" type="Fountain" colour="0xff5099" duration="3000">
<Position x="-100" y="-384"/>
</Firework>
<Firework begin="1000" type="Rocket" colour="0xFF2020" duration="1000">
<Position x="500" y="-384"/>
<Velocity x="-3" y="10"/>
</Firework>
<Firework begin="2000" type="Rocket" colour="0xFF2020" duration="1000">
<Position x="0" y="-384"/>
<Velocity x="0" y="10"/>
</Firework>
<Firework begin="3000" type="Rocket" colour="0xFF2020" duration="1000">
<Position x="-500" y="-384"/>
<Velocity x="3" y="10"/>
</Firework>
<Firework begin="11000" type="Rocket" colour="0xFFFF20" duration="1000">
<Position x="500" y="-384"/>
<Velocity x="-3" y="10"/>
</Firework>
<Firework begin="12000" type="Rocket" colour="0xFF2020" duration="1000">
<Position x="0" y="-384"/>
<Velocity x="0" y="10"/>
</Firework>
<Firework begin="13000" type="Rocket" colour="0xFF20FF" duration="1000">
<Position x="-500" y="-384"/>
<Velocity x="3" y="10"/>
</Firework>
<Firework begin="4000" type="Fountain" colour="0xffFF40" duration="5000">
<Position x="0" y="-384"/>
</Firework>
<Firework begin="5000" type="Fountain" colour="0x4020FF" duration="4000">
<Position x="-200" y="-384"/>
</Firework>
<Firework begin="6000" type="Fountain" colour="0xff5099" duration="3000">
<Position x="200" y="-384"/>
</Firework>
<Firework begin="7000" type="Fountain" colour="0x20FF40" duration="5000">
<Position x="0" y="-384"/>
</Firework>
<Firework begin="8000" type="Fountain" colour="0x4020FF" duration="4000">
<Position x="400" y="-384"/>
</Firework>
<Firework begin="9000" type="Fountain" colour="0xff5099" duration="3000">
<Position x="-400" y="-384"/>
</Firework>
<Firework begin="10000" type="Fountain" colour="0xff8040" duration="1000">
<Position x="-450" y="-384"/>
</Firework>
<Firework begin="10500" type="Fountain" colour="0x40ffFF" duration="1000">
<Position x="-220" y="-384"/>
</Firework>
<Firework begin="11000" type="Fountain" colour="0xffff99" duration="1000">
<Position x="0" y="-384"/>
</Firework>
<Firework begin="11500" type="Fountain" colour="0xff00ff" duration="1000">
<Position x="220" y="-384"/>
</Firework>
<Firework begin="12000" type="Fountain" colour="0x40ffFF" duration="1000">
<Position x="450" y="-384"/>
</Firework>
</FireworkDisplay>
Last edited by Jamku; May 13th, 2013 at 04:05 PM.
-
May 8th, 2013, 05:12 AM
#2
Re: how do i convert xml attributes to c++ class using tinyxml
What is GLfloat?
What is GLboolean?
FYI: there are some XmlLite Samples in MSDN
Victor Nijegorodov
-
May 8th, 2013, 05:23 AM
#3
Re: how do i convert xml attributes to c++ class using tinyxml
because i'm using Opengl, aint that how you declare a float variable when using the OpenGl library? and im not having trouble loading the xml but converting them into the variables used in the firework class
-
May 8th, 2013, 05:37 AM
#4
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by Jamku
I did try using atof but when i ran the program i got loads of errors which im guessing is because the pointer only stores the address which im passing to my variable.
Well, if you looked at the GL/gl.h file you would find:
Code:
typedef float GLfloat;
So your GLfloat is the same as float. In such a case using atof looks correct (presuming the string contains decimal representation of the value).
What is the problem/error you get by this convertio(s)? And for what string(s)?
Victor Nijegorodov
-
May 8th, 2013, 07:16 AM
#5
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by VictorN
Well, if you looked at the GL/gl.h file you would find:So your GLfloat is the same as float. In such a case using atof looks correct (presuming the string contains decimal representation of the value).
What is the problem/error you get by this convertio(s)? And for what string(s)?
i did look at the gl.h file thats why i was confused when you asked me what it was. the error im getting is
Code:
Unhandled exception at 0x77538dc9 in Fireworks.exe: 0xC0000005: Access violation writing location 0x00000014
-
May 8th, 2013, 07:22 AM
#6
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by Jamku
the error im getting is
Code:
Unhandled exception at 0x77538dc9 in Fireworks.exe: 0xC0000005: Access violation writing location 0x00000014
Well, and what does it have to do with the atof function? 
Did you debug your code? If not - do it and see what line of your code causes this access violation!
If you did debug - then show us the line of your code that causes this access violation!
Victor Nijegorodov
-
May 8th, 2013, 07:41 AM
#7
Re: how do i convert xml attributes to c++ class using tinyxml
ye ive been running it in debug mode, the output don't give me a line where the error is occurring but in the stack frame i got this
Code:
msvcr100d.dll_lock_file(_iobuf*pf) Line237
, and i see this in the Autos
Code:
_base 0x00000000 <Bad Ptr> char *
-
May 8th, 2013, 07:46 AM
#8
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by Jamku
ye ive been running it in debug mode, the output don't give me a line where the error is occurring but in the stack frame i got this
Code:
msvcr100d.dll_lock_file(_iobuf*pf) Line237
, and i see this in the Autos
Code:
_base 0x00000000 <Bad Ptr> char *
Please, look at the call stack more carefull and find the latest part of your fuctions being called before this "msvcr100d.dll_lock_file(_iobuf*pf) Line237"
Victor Nijegorodov
-
May 8th, 2013, 08:21 AM
#9
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by VictorN
Please, look at the call stack more carefull and find the latest part of your fuctions being called before this "msvcr100d.dll_lock_file(_iobuf*pf) Line237"
this is at the very top of the call stack
Code:
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
-
May 9th, 2013, 12:33 PM
#10
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by Jamku
ye ive been running it in debug mode, the output don't give me a line where the error is occurring
I don't know what you expected, but C++ doesn't work that way.
When you debug a C++ program, you practically never get "the line that caused the error". It is your job to then really and truly debug the code by single-stepping through the program, setting breakpoints, watch variables, etc.
I followed a tutorial on dinomage to find out how to use tinyxml, i learnt that i can store the attributes into char pointers
You cannot store attributes in char pointers. A pointer is not a storage location for string data. A pointer is an integer value that denotes a position in memory. Nothing more, nothing less. You can use string variables such as what Victor mentioned to store actual strings. Things such as CString, std::string, and others are string types that actually are smart enough to handle entire strings. A pointer has no such capabilities, as again, it is just an integer value.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; May 9th, 2013 at 12:41 PM.
-
May 8th, 2013, 05:58 AM
#11
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by Jamku
i learnt that i can store the attributes into char pointers but i dont know how to convert them to GLfloats
So you have to put aside your current task and learn about basics of parsing strings (not char pointers) to numbers, floats in particular.
I did try using atof but when i ran the program i got loads of errors which im guessing is because the pointer only stores the address which im passing to my variable.
You should never guess, but always read error messages and documentation carefully to understand the real reason of your problems.
As for the probable reason, the very typical issue is using string functions that mismatch with the really used string types. As long as atof causes troubles, I can suspect your strings are of wide characters, and therefore you should use proper function from atof family that is able to deal with wide strings.
Best regards,
Igor
-
May 8th, 2013, 07:23 AM
#12
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by Igor Vartanov
So you have to put aside your current task and learn about basics of parsing strings (not char pointers) to numbers, floats in particular.
You should never guess, but always read error messages and documentation carefully to understand the real reason of your problems.
As for the probable reason, the very typical issue is using string functions that mismatch with the really used string types. As long as atof causes troubles, I can suspect your strings are of wide characters, and therefore you should use proper function from atof family that is able to deal with wide strings.
Your right you should never guess but this kind of error isn't telling you where the problem is ive tried but still getting the same error thus why i posted on here, and im not using atof on strings, im going to try store the char pointer into a string then use atof on the string variable to store it in my GLfloat, what do you think?
-
May 8th, 2013, 07:43 AM
#13
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by Jamku
... im not using atof on strings, im going to try store the char pointer into a string then use atof on the string variable to store it in my GLfloat, what do you think?
But how do you "store the char pointer into a string"? "string" is supposed to be a kind of character array, not an array of "char pointers"!
Besides, this code is wrong!
char *attr;
...
attr = elem->Attribute("type");
...
if ( attr == "Fountain")
you do not compare here "strings", you compare some pointers! To compare "strings" you should use some c-function like strcmp or use some classes like std::string or MFC CString with their appropriate methods!
Victor Nijegorodov
-
May 8th, 2013, 08:19 AM
#14
Re: how do i convert xml attributes to c++ class using tinyxml
 Originally Posted by VictorN
But how do you "store the char pointer into a string"? "string" is supposed to be a kind of character array, not an array of "char pointers"!
Besides, this code is wrong!
you do not compare here "strings", you compare some pointers! To compare "strings" you should use some c-function like strcmp or use some classes like std::string or MFC CString with their appropriate methods!
oooo i see thanks for POINTING that out lol (see what i did there) i will make the changes accordingly and check what errors i get.
-
May 13th, 2013, 04:08 PM
#15
Re: how do i convert xml attributes to c++ class using tinyxml
would like to thank everyone for there help its helping me progress as a programmer, now with the cout's in place i can see whats not loading and its the xml root, this is my first time using any xml parser, so if theres anyone that can maybe point me in the right direction it would be appreciated
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|