2013-05-07 17 views
2

嘿,我想创建一个烟花汇演XML属性到C++类。如何转换由烟花阅读过一个.xml文件,然后将遍历并推出各自的烟花使用TinyXML的

我跟着dinomage上的教程来了解如何使用tinyxml,我知道我可以将属性存储到字符指针,但我不知道如何将它们转换为GLfloats以将它们存储在我的类变量中。

我也尝试使用ATOF但是当我运行该程序,我得到它即时猜测是因为指针只保存其即时通讯传递给我的变量的地址错误的负荷。

有谁能够指出哪里我去错了,我怎么能去修复这个问题?

更新

我已经发现,TinyXML的不与VS2010兼容,而且TinyXML的2,所以我改变了我的代码,但我仍然无法载入我的属性,我添加了一些错误检查,并印刷出的是,XML已经加载,但然后它不会加载根

代码更新

代码:Firework.h

#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

#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

#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

<?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> 
+0

这个问题逗我:) – acron 2013-05-29 12:55:34

回答

0
if (attr == "Fountain") 

这是不对的。它比较指针,而不是字符串内容。使用strcmp。检查每个事件。

if (rocket = true) 

这将永远是真实的,因为它是一个赋值,用==代替。检查每个事件。

+0

OOO你们的感谢,但你是什么每种情况的意思是用支票? – user2359517 2013-05-07 21:01:58

+0

我的意思是同一种表达的代码出现多次,纠正他们。 – jmihalicza 2013-05-07 21:37:51

+0

好吧,我现在明白,我没有做到这一点自然感谢您的答复。我想出了这个代码中提取出来的数据的XML来我的变量你看到什么错之前,我改变一切? timeUntillLaunch = elem-> FirstChildElement( “开始”) - > QueryFloatAttribute(ATTR,&timeUntillLaunch); – user2359517 2013-05-07 21:54:53