[C++] Falsche Werte werden ausgelesen

CodeCrafterCpp

Erfahrenes Mitglied
Hallo,
Ich hatte das kurz in einen anderen Thema aber das hat da nicht mehr rein gepasst also vom Titel her.
Der Code:
C++:
#include <iostream>
#include <windows.h>
#include <SDL.h> 
#include <GL/gl.h>
#include <GL/glu.h>
#include <string>
#include <fstream>
#include <sstream>


using namespace std;



bool e = true;


void init()
{
	glClearColor(0.0,0.0,0.0,1.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0,640.0/480.0,5.0,500.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

class Quad
{
public:
	float ex[10];
	float ey[10];
	float ez[10];


};

void auslesen(string Pfade, class Quad *s1)
{
		int i = 0;
        ifstream file(Pfade);
        string buffer;
		size_t pos1;
		size_t pos2;
		float bxf, byf, bzf;
		string bx, by, bz;
 

		while(e == true && getline(file,buffer))
		{

			if(!buffer.find('v'))
			{
				pos1 = buffer.find(" ");
				buffer = buffer.substr(pos1+1);
				pos2 = buffer.find(" ", pos1);
				bx = buffer.substr(pos1-1, pos2);
				pos1 = buffer.find(" ", pos2);
				by = buffer.substr(pos2+1, pos1);
				pos2 = buffer.find(" ", pos1);
				bz = buffer.substr(pos1+1, pos2);
				cout << bx << by << bz << endl;

				istringstream ibx (bx);
				ibx >> bxf;
				istringstream iby (by);
				iby >> byf;
				istringstream ibz (bz);
				ibz >> bzf;


				s1->ex[i] = bxf;
				s1->ey[i] = byf;
				s1->ez[i] = bzf;
				//cout <<bxf << endl << byf << endl << bzf << endl;
				i++;
				
			}
		}
		e = false;
        file.close();
}


void display()
{
    Quad s1;
    auslesen("C://Users/Jonas/Desktop/test.obj",&s1);
	glClear(GL_COLOR_BUFFER_BIT);
	  glBegin(GL_QUADS);
        glVertex3f(s1.ex[0], s1.ey[0], s1.ez[0]);
        glVertex3f(s1.ex[1], s1.ey[1], s1.ez[1]);
		glVertex3f(s1.ex[2], s1.ey[2], s1.ez[2]);
		glVertex3f(s1.ex[3], s1.ey[3], s1.ez[3]);
		
        /*glVertex3f(1.000000, -1.000000,5.0);
        glVertex3f(-1.000000, -1.000000,5.0);
        glVertex3f(-1.000000, 1.000000,5.0);
        glVertex3f(1.000000, 1.000000,5.0);
        
        glVertex3f(1.000000, 1.000000,-5.0);
        glVertex3f(1.000000, 1.000000,5.0);
        glVertex3f(1.000000, -1.000000,5.0);
        glVertex3f(1.000000, -1.000000,-5.0);
        
        glVertex3f(1.000000, -1.000000,-5.0);
        glVertex3f(1.000000, -1.000000,5.0);
        glVertex3f(-1.000000, -1.000000,5.0);
        glVertex3f(-1.000000, -1.000000,-5.0);
        
        glVertex3f(-1.000000, -1.000000,-5.0);
        glVertex3f(-1.000000, -1.000000,5.0);
        glVertex3f(-1.000000, 1.000000,5.0);
        glVertex3f(-1.000000, 1.000000,-5.0);
        
        glVertex3f(-1.000000, 1.000000,-5.0);
        glVertex3f(-1.000000, 1.000000,5.0);
        glVertex3f(1.000000, 1.000000,5.0);
        glVertex3f(1.000000, 1.000000,-5.0);*/
	glEnd();
}

int main(int, char**)
{
	SDL_Init(SDL_INIT_EVERYTHING);
	SDL_Surface* screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE|SDL_OPENGL);
	bool running=true;
	Uint32 start;
	SDL_Event event;
	init();
	while(running)
	{
		start=SDL_GetTicks();
		while(SDL_PollEvent(&event))
		{
			switch(event.type)
			{
				case SDL_QUIT:
					running=false;
					break;
			}
		}
		display();
		SDL_GL_SwapBuffers();
		if(1000/30>(SDL_GetTicks()-start))
			SDL_Delay(1000/30-(SDL_GetTicks()-start));
	}
	SDL_Quit();
	return 0;
}

Im Bild sieht man die Ausgabe und die Datei mit den Daten ich möchte alle Werte die nach den "V" stehen in einer Float Variable speichern. Die erste Zeile passt ja noch aber dann stimmt es nicht mehr richtig.

mfG
 

Anhänge

  • Unbenannt.png
    Unbenannt.png
    87,1 KB · Aufrufe: 18
Zuletzt bearbeitet von einem Moderator:
Zunächst mal empfehle ich dir, die Daten nicht unbedingt für jeden Frame neu zu laden... so machst du in jedem Render-Aufruf das Daten lesen... lad die nur einmal in ne Datenstruktur und hol dir die Daten zum Rendern da raus...

Grundsätzlich kannst du aber sowas etwas übersichtlicher machen, wenn du

Code:
sscanf_s(line.c_str(), "v %f %f %f", &v_vec.x, &v_vec.y, &v_vec.z);
verwendest...

line ist dabei ein string und v_vec eine entsprechende Datenstruktur, um eben floatwerte entsprechend aufzunehmen...
 
Ok dazu möchte ich sagen das ich eine Klasse verwende was doch so ziemlich das gleiche wie eine Datenstruktur ist. Und das mit den laden der Datei hast du recht bloß wenn ich die Funktion "auslesen" in eine If Verzweigung setzte bekomme ich beim Debuggen einen Error:
Code:
Run-Time Check Failure #3 - The variable 's1' is being used without being initialized.
Und wenn ich es nur einmal auslese wird mir es ja wieder von Zeile: 87 auf 0.

Noch ein anderes Problem. Wenn ich es jetzt rotieren oder bewegen will dann kommt da nicht ein Würfel raus...

C++:
#include <iostream>
#include <windows.h>
#include <SDL.h> 
#include <GL/gl.h>
#include <GL/glu.h>
#include <string>
#include <fstream>
#include <sstream>


using namespace std;


bool readControll = true;
GLfloat     rquad; 


void init()
{
	glClearColor(0.0,0.0,0.0,1.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0,640.0/480.0,5.0,500.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

class Quad
{
public:
	float vx[10];
	float vy[10];
	float vz[10];


};

void auslesen(string Pfade, class Quad *s1)
{

	int i = 0;
	ifstream datei(Pfade);
	string buffer;
	while (getline(datei, buffer)) 
	{
		istringstream is(buffer);
		char type;
    
		is >> type;
		
		switch (type) 
		{
			case 'v':
					is >> s1->vx[i] >> s1->vy[i] >> s1->vz[i];
					i++;
					break;

			case '#': // comment
					break;

			default:
					break;
		}
	}
	readControll = false;
	
}


void display()
{
	Quad s1;
	auslesen("C://Users/Jonas/Desktop/test.obj",&s1);

	glLoadIdentity(); 
	glTranslatef(0,0,-3.5);
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_QUADS);
        glVertex3f(s1.vx[0], s1.vy[0], -5.0);
        glVertex3f(s1.vx[1], s1.vy[1], 5.0);
		glVertex3f(s1.vx[2], s1.vy[2], 5.0);
		glVertex3f(s1.vx[3], s1.vy[3], -5.0);

		glVertex3f(s1.vx[4], s1.vy[4], -5.0);
        glVertex3f(s1.vx[7], s1.vy[7], -5.0);
		glVertex3f(s1.vx[6], s1.vy[6], 5.0);
		glVertex3f(s1.vx[5], s1.vy[5], 5.0);

		glVertex3f(s1.vx[0], s1.vy[0], -5.0);
        glVertex3f(s1.vx[4], s1.vy[4], -5.0);
		glVertex3f(s1.vx[5], s1.vy[5], 5.0);
		glVertex3f(s1.vx[1], s1.vy[1], 5.0);

		glVertex3f(s1.vx[1], s1.vy[1], 5.0);
        glVertex3f(s1.vx[5], s1.vy[5], 5.0);
		glVertex3f(s1.vx[6], s1.vy[6], 5.0);
		glVertex3f(s1.vx[2], s1.vy[2], 5.0);

		glVertex3f(s1.vx[2], s1.vy[2], -5.0);
        glVertex3f(s1.vx[6], s1.vy[6], -5.0);
		glVertex3f(s1.vx[7], s1.vy[7], -5.0);
		glVertex3f(s1.vx[3], s1.vy[3], -5.0);

		glVertex3f(s1.vx[4], s1.vy[4], -5.0);
        glVertex3f(s1.vx[0], s1.vy[0], -5.0);
		glVertex3f(s1.vx[3], s1.vy[3], -5.0);
		glVertex3f(s1.vx[7], s1.vy[7], -5.0);

		
 
	glEnd();
}

int main(int, char**)
{
	SDL_Init(SDL_INIT_EVERYTHING);
	SDL_Surface* screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE|SDL_OPENGL);
	bool running=true;
	Uint32 start;
	SDL_Event event;
	init();
	while(running)
	{
		start=SDL_GetTicks();
		while(SDL_PollEvent(&event))
		{
			switch(event.type)
			{
				case SDL_QUIT:
					running=false;
					break;
			}
		}
		display();
		SDL_GL_SwapBuffers();
		if(1000/30>(SDL_GetTicks()-start))
			SDL_Delay(1000/30-(SDL_GetTicks()-start));
	}
	SDL_Quit();
	return 0;
}

Hier die Datei die ausgelesen wird:

Code:
# Blender v2.62 (sub 0) OBJ File: ''
# www.blender.org
mtllib test.mtl
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
usemtl Material
s off
f 1 2 3 4
f 5 8 7 6
f 1 5 6 2
f 2 6 7 3
f 3 7 8 4
f 5 1 4 8

Und im Anhang ein Bild was dabei rauskommt.

Ich hoffe echt das mir da jemand Helfen kann und mir sagen kann was falsch ist.


mfG
 

Anhänge

  • Unbenannt.png
    Unbenannt.png
    85 KB · Aufrufe: 10
Zuletzt bearbeitet von einem Moderator:
Hi.

Warum hast du denn das Errorchecking aus dem Code genommen?

Und den Anhang hast du wohl vergessen?

Du mußt doch nur das Quad als globales Objekt anlegen und einmal in main auslesen aufrufen.

Das Speichern der Vektoren würde ich auch anders lösen:
C++:
std::list<vec3f> quad; // Liste von Punkten
:offtopic: Meiner Meinung nach keine gute Idee ein neues Thema zu beginnen. Wenn sich ein Thema anders entwickelt, dann ist es halt so. Jetzt hat es keinen Bezug mehr, die obj Datei hast du nun zum x-ten Mal gepostet...

Gruß
 
Um ehrlich zu sein habe ich noch nie mit std::list gearbeitet und kein Plan wie das Funktioniert. Das Bild habe ich oben eingefügt. Und der Errorchecking war doch nur das was er anzeigt was er in der Datei kennt und was nicht oder?
 
Ich denke du meinst ich soll std::list suchen aber ich finde dazu nichts und bei MSDN steig ich nicht durch da ist das wie ich finde ganz schön kompliziert erklärt.
 
Ich check es immer noch nicht ich bin so weit gekommen:
C++:
list<vec3f> quad;
Und das war ja noch von deepthroat. Dann hab ich noch das hier weiß aber noch nicht mal ob das richtig ist:
C++:
 class vec3f
{
private:
	float vx;
	float vy;
	float vz;

};

Aber dann?
Wie bekomme ich denn jetzt "is"(istringstream) in in die Liste und auch das die 3 Werte zu vx, vy, vz rein kommen und nicht nach einander?
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

Angedacht mit dem einmaligen Laden war es so, dass du eine Art Init-Methode machst und da die Werte aus einer Datei lädst. Eine brauchbare Datenstruktur wäre z.B. angehängte Klasse, die ich vor einiger Zeit mal gebaut habe, um rudimentär "OBJ-Files" zu laden.

mvector3 ist dabei ein Struct, das einfach 3 (bzw. 2) float-werte aufnimmt und triangle_face ist ein Struct, das 3 mvector3 Werte aufnimmt.

Die ganze Klasse ist für glDrawArrays gebaut.

Die Daten aus der obj-File werden dann nur einmal beim Initialisieren des Models geladen.

Dass die Runtime Exception geworfen wird, ist wahrscheinlich nicht verwunderlich, wenn du nicht vor der Rendermethode die besagte init-Methode verwendest und s1 sagen wir mal global machst :)

Ach ja, was mir grade auffällt.. du hast ja eine Init-Funktion. Das ist allerdings eigentlich keine klassische Init-Methode, denn die Methode wird eigentlich immer dann aufgerufen, wenn sich dein Zeichenbereich ändert (Fenster größer/kleiner machen etc.)

Ohnehin solltest du vielleicht von den Compatibility Profile Functions wegkommen, weil die seit OpenGL 3.0 eigentlich deprecated sind. Du kannst dir also viel Zeit sparen, wenn du gleich beim aktuellen Stand einsteigst.

Allerdings ist das ganze dann doch ein bisschen umfangreicher (das ganze Thema an sich), sodass sich ein Foren-Thread da weniger für eignet... Ich schick dir mal eine PM mit meiner Email, da kannst du dann mal was sehr ausführliches verfassen und wir könnten das dann auch ein bisschen in realtime machen ;)
 

Anhänge

Zurück