PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Buch "Interactive Computer Graphics" und OSX


urpils
2013-08-29, 08:10:50
Hallo liebe Gemeinde,

eins vorweg: ich bin kein Programmierer, ich habe etwas vollkommen anderes studiert und ich will auch keine abgefahrenen Hightechspiele programmieren - mich interessiert einfach nur die Thematik und ich will etwas rumspielen.

Ich habe günstig ein gebrauchtes Exemplar von dem Buch Interactive Computer Graphics (http://www.amazon.com/Interactive-Computer-Graphics-Top-Down-Shader-Based/dp/0132545233) bekommen und möchte nun versuchen zu verstehen, wie 3D-Computergrafik funktioniert und ein bisschen damit rumspielen um mein Verständnis zu festigen.

In dem Buch komme ich auch sehr gut mit - toll erklärt - ich verstehen die Beispiele - habe Kapitel 1&2 durch und wollte mich langsam an die Codebeispiele und Übungen machen.

Ich bekomme aber aufs verrecken die Codebeispiele von hier (http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/) unter OSX mit XCode nicht zum laufen.

Wie gesagt - ich bin kein Programmierer - ich habe nie größere Projekte gemacht und benutze eigentlich auch Xcode nicht. Ich habe 1-2 C(++) Bücher vor Jahren gelesen (also Grundlegendes, wie Schleifen, Strukturen, Objekte, Zeiger,...) und verstehe die wichtigen Elemente der Quelldateien (wenn dann aber ständig "&" oder "*" und Überladungen durch die Gegend fliegen steige ich dennoch aus.

Wie dem auch sei - wenn ich die Quelltexte in Xcode einfüge, bekomme ich sie nicht zum Laufen - egal wie viel ich rumfummele.

Habe mich hier (http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/CODE/CHAPTER02/MAC_VERSIONS/) an Example1.cpp probiert:


//
// main.cpp
// OpenGL-Uebungen-1
//
// Created by Jan Engert on 27.08.13.
// Copyright (c) 2013 Jan Engert. All rights reserved.
//
/*
#include <iostream>
#include <GLUT/glut.h>
#include <OpenGL/OpenGL.h>


int main(int argc, const char * argv[])
{

// insert code here...
std::cout << "Hello, World!\n";
return 0;
}
*/

// Two-Dimensional Sierpinski Gasket
// Generated using randomly selected vertices and bisection

#include "Angel.h"

const int NumPoints = 5000;

//----------------------------------------------------------------------------

void
init( void )
{
vec2 points[NumPoints];

// Specifiy the vertices for a triangle
vec2 vertices[3] = {
vec2( -1.0, -1.0 ), vec2( 0.0, 1.0 ), vec2( 1.0, -1.0 )
};

// Select an arbitrary initial point inside of the triangle
points[0] = vec2( 0.25, 0.50 );

// compute and store N-1 new points
for ( int i = 1; i < NumPoints; ++i ) {
int j = rand() % 3; // pick a vertex at random

// Compute the point halfway between the selected vertex
// and the previous point
points[i] = ( points[i - 1] + vertices[j] ) / 2.0;
}

// Create a vertex array object
GLuint vao[1];
glGenVertexArraysAPPLE( 1, vao );
glBindVertexArrayAPPLE( vao[0] );


// Create and initialize a buffer object
GLuint buffer;
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );

// Load shaders and use the resulting shader program
GLuint program = InitShader( "vshader21.glsl", "fshader21.glsl" );
glUseProgram( program );

// Initialize the vertex position attribute from the vertex shader
GLuint loc = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( loc );
glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0) );

glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background
}

//----------------------------------------------------------------------------

void
display( void )
{
glClear( GL_COLOR_BUFFER_BIT ); // clear the window
glDrawArrays( GL_POINTS, 0, NumPoints ); // draw the points
glFlush();
}

//----------------------------------------------------------------------------

void
keyboard( unsigned char key, int x, int y )
{
switch ( key ) {
case 033:
exit( EXIT_SUCCESS );
break;
}
}

//----------------------------------------------------------------------------

int
main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA );
glutInitWindowSize( 512, 512 );

glutCreateWindow( "Sierpinski Gasket" );

init();

glutDisplayFunc( display );
glutKeyboardFunc( keyboard );

glutMainLoop();
return 0;
}


habe die Angel.h zum Projekt in Xcode hinzugefügt, darüberhinaus die von der Angel.h benötigten mat.h und vec.h.

Wenn ich compilieren möchte bekomme ich den Fehler:
Non-const lvalue reference to type 'Angel::mat2' cannot bind to temporary of type 'Angel::mat2' (Zeile 132 der mat.h)

das gleiche noch für mat3 und mat 4 in der mat.h
(die mat.h gibt es hier (http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/CODE/include/))

der beanstandete Teil ist wohl dieser hier:

mat2& operator /= ( const GLfloat s ) {
#ifdef DEBUG
if ( std::fabs(s) < DivideByZeroTolerance ) {
std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] "
<< "Division by zero" << std::endl;
return mat2();
}
#endif // DEBUG


und wie oben beschrieben - bei DIESEN Dingern steige ich aus - ich hab keine Ahnung wozu dieser Bereich da ist und was er macht.

hat irgendjemand die Muße mir hierbei zu helfen - das wäre wirklich toll.

edit: achso - ich hatte diese Fehlermeldung bei Stack-overflow schon gefunden - jedoch hilft die dort angebotene Lösung auch nichts, weil ich weiterhin eine Warnung erhalte und das compilieren dann mit der Fehlermeldung:

Undefined symbols for architecture x86_64:
"Angel::InitShader(char const*, char const*)", referenced from:
init() in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

dennoch abbricht :/

Ectoplasma
2013-08-29, 10:32:02
ich hab keine Ahnung wozu dieser Bereich da ist und was er macht.

Dieser Bereich prüft ab, ob die Variable s, zu einer Division durch 0 führen könnte. In diesem Fall wird die Berechnung abgebrochen und es wird eine neue Instanz von mat2 zurück gegeben (ziemlich gruseliger Code btw.). Der Code wird übrigens nur compiliert, wenn im Compiler das Makro "DEBUG" gesetzt wurde.

Nun zum Fehler. In den neueren C++ Standards ist es so, dass man keine Instanz als Rückgabewert an eine nicht konstante Referenz zurück geben kann.

In Zeile 127 steht:
mat2& operator /= ( const GLfloat s )
Richtig wäre:
const mat2& operator /= ( const GLfloat s )

Nur damit handelt man sich andere Probleme ein, auf die ich jetzt nicht weiter eingehen will. Also diese Zeile nicht ändern. Du könntest aber z.B. die Zeile 132 durch folgenden Code ersetzen:
throw std::domain_error("Division by zero");
In Zeile 11 schreibst du noch:
#include <stdexcept>

urpils
2013-08-29, 14:44:44
Vielen Dank für die Antwort! :)
Wenn ich später Zuhause bin werde ich es ausprobieren. Danke!

urpils
2013-08-29, 18:01:25
leck mich doch am arsch - jetzt kommt folgende Meldung ;)


Undefined symbols for architecture x86_64:
"Angel::InitShader(char const*, char const*)", referenced from:
init() in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

"Angel::InitShader(char const*, char const*)", referenced from:
init() in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

was genau will er mir denn jetzt damit sagen?
(an dem mat2 meckert er zwar - aber nur noch als Warnung - er versucht sich am zusammenbauen - aber dann kommt das hier)

Ectoplasma
2013-08-29, 18:18:24
Gut ist aber schon einmal, dass der Code kompiliert wird. Was du jetzt siehst sind "nur" Linker-Fehler. Kannst du mal zeigen, wie das Makefile aussieht, falls es eines gibt. Oder anders gefragt, wie kompilierst du überhaupt? Es sieht nämlich so aus, als ob du die Dateien, in denen sich z.B. die Methode "Angel::InitShader(char const*, char const*)" befindet, entweder nicht mitkompiliert hast, oder diese, falls sie bereits vorkompiliert wurden, nicht mitgelinkt hast.

Edit1:

Es sollte irgendwo eine Datei Namens Angel.cpp InitShader.cpp existieren. Bei denen auf den Servern, habe ich die nicht gefunden. Dort findet man nur die Datei Angel.h, in der "Angel::InitShader(char const*, char const*)" lediglich deklariert wurde, aber keine Implementierung vorhanden ist.

Edit2:

Ah, habs gefunden InitShader.cpp (http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/CODE/Common/InitShader.cpp). Die mußt du mitkompilieren.

urpils
2013-08-29, 20:45:45
oh Mann wie blöd ich bin - auf die Idee kam ich gar nicht OO
jetzt läuft er durch - vielen vielen vielen Dank! :) hast du irgendwie Flattr oder kann ich dir sonst 1-2€ zukommen lassen?

(bzw läuft es nicht ganz - in der Konsole meint er "Failed to read vshader21.glsl" - aber da kann ich ja mich mal selbst mit beschäftigen - vielleicht bekomm ich es ja korrekt eingelesen)

edit:

Gut ist aber schon einmal, dass der Code kompiliert wird. Was du jetzt siehst sind "nur" Linker-Fehler. Kannst du mal zeigen, wie das Makefile aussieht, falls es eines gibt. Oder anders gefragt, wie kompilierst du überhaupt? Es sieht nämlich so aus, als ob du die Dateien, in denen sich z.B. die Methode "Angel::InitShader(char const*, char const*)" befindet, entweder nicht mitkompiliert hast, oder diese, falls sie bereits vorkompiliert wurden, nicht mitgelinkt hast.


ich benutze kein makefile - vielleicht ist das auch ein Problem. ich habe die Header und die *.cpp Dateien in ein neues Xcode-Projekt eingefügt.. momentan fummele ich darum, wie ich ihn dazu bekomme, dass er die Shader korrekt einliest - bzw. kompiliert(?).

edit 2:

soooo - jetzt habe ich es ENDLICH. in der "Build-Phase" musste ich noch eine neue "Phase" hinzufügen und dort die Shader in die executable kopieren, sodass er sie beim Ausführen auch finden kann.

aber mal im Ernst - das ist so ziemlich das Gegenteil von "simpel". Ich habe zwar wenig Ahnung, aber ich habe 2 komplette Tage (und die nette Hilfe von Ectoplasma gebraucht, um die Codeschnipsel zum Laufen zu bekommen. Ich glaube kaum, dass ich der Einzige bin, der diese Probleme hat... nunja - jetzt wo es läuft versuche ich das ganze nochmal in Ruhe nachzuvollziehen und mich ENDLICH mal an die wirklich spannenden Dinge zu wenden - jetzt wo es wenigstens läuft ;)

Ectoplasma
2013-08-29, 23:27:41
jetzt läuft er durch - vielen vielen vielen Dank! :) hast du irgendwie Flattr oder kann ich dir sonst 1-2€ zukommen lassen?

Ach was Quark, freut mich, dass ich helfen konnte :smile:

urpils
2013-08-31, 08:49:57
ich will nicht wieder einen neuen Thread für jedes meiner kleinen "Wehwehchen" aufmachen - ich habe wieder ein Problem.

Nachdem der Beispielcode nun läuft und ich den soweit auch überblickt habe und mein Ziel es ist, das Ganze zu verstehen und nicht nur irgendwie zusammenzukloppen, habe ich mich gestern abend daran gemacht das komplette Beispiel einmal selbst zu implementieren - und mich an dem Vorgehen des Autors zu orientieren.

in dem Header vec.h (http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/CODE/include/vec.h) hänge ich jedoch schon an der Notation des Konstruktors. Ich habe mitlerweile stundenlang Google durchsucht, aber ich komme einfach nicht darauf, was er mit dem folgendem Konstruktur WIE anstellt:


struct vec2 {

GLfloat x;
GLfloat y;

//
// --- Constructors and Destructors ---
//

vec2( GLfloat s = GLfloat(0.0) ) :
x(s), y(s) {}

vec2( GLfloat x, GLfloat y ) :
x(x), y(y) {}

vec2( const vec2& v )
{ x = v.x; y = v.y; }
...


die Notation x(s) bzw x(x) ist mir vollkommen unklar. So wie ich das sehe, sollen x & y auf 0.0 gesetzt werden, wenn vec2 ohne Argumente aufgerufen wird. wenn ja? wieso nutzt man x(s)? x ist doch keine Funktion oO

(btw. ist mir auch nicht klar, wieso dort ein Doppelpunkt genutzt wird. Diese Schreibweise habe ich auch durch Google und Nachschlagen in meinen alten C-Büchern nicht entdeckt - oder ich bin einfach blind und dumm :/

Ganon
2013-08-31, 09:03:28
classe A
{
int Attribut;

A(parameter1 = defaultWertFürParameter1) : Attribut(parameter1) {}
};


ist :


classe A
{
int Attribut;

A(parameter1 = defaultWertFürParameter1) {
this.Attribut = parameter1;
}
};


Also wenn du jetzt:
A() aufrust, dann hat das Attribut den Wert defaultWertFürParameter1. Rufst du aber A(andererWert) auf, dann hat das Attribut den Wert andererWert.

Das ist bei mir übrigens der erste Treffer, wenn ich bei Google nach "C++ Constructor" suche :D

urpils
2013-08-31, 13:03:58
classe A
{
int Attribut;

A(parameter1 = defaultWertFürParameter1) : Attribut(parameter1) {}
};


ist :


classe A
{
int Attribut;

A(parameter1 = defaultWertFürParameter1) {
this.Attribut = parameter1;
}
};


Also wenn du jetzt:
A() aufrust, dann hat das Attribut den Wert defaultWertFürParameter1. Rufst du aber A(andererWert) auf, dann hat das Attribut den Wert andererWert.

Das ist bei mir übrigens der erste Treffer, wenn ich bei Google nach "C++ Constructor" suche :D

bei mir zwar nicht, aber wahrscheinlich habe ich nur den Wald vor lauter Bäumen nicht gesehen ;)

ich danke dir vielmals!!! :)