Précédent   Forum des professionnels en informatique > Applications > Développement 2D, 3D et Jeux > API graphiques > OpenGL
OpenGL Forum d'entraide sur le développement en OpenGL. Avant de poster -> FAQ OpenGL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 31/01/2012, 23h24   #1
Invité de passage
 
Homme Pascal
Développeur de jeux vidéo
Inscription : janvier 2012
Messages : 10
Détails du profil
Informations personnelles :
Nom : Homme Pascal
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2012
Messages : 10
Points : 2
Points : 2
Par défaut [VBO/Shaders] L'art d'obtenir un écran noir :/

Bonsoir !

Je travaille actuellement sur un projet personnel dans lequel je dois obtenir les meilleures performances.

Après avoir suivi plusieurs tutoriels, il s'avère que je me retrouve nez à nez avec un écran noir une fois de plus.

Rendu : OpenGL ES 2 + VBO
Langage : C++
Lib : GLM

Voici le code actuel avec les explications :

Je dispose d'une classe "Caméra" contenant les attributs vue et la projection que j'initialise tout au début :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void Camera::initView()
{
	// Profondeur
	glDisable( GL_DEPTH_TEST );			
	glDisable( GL_CULL_FACE );
 
	// Transparence
	glEnable( GL_BLEND );
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
	glm::vec3 eye( 0.0f, 0.0f, 1.5f );
	glm::vec3 center( 0.0f, 0.0f, -5.0f );
	glm::vec3 up( 0.0f, 1.0f, 0.0f );
 
	myView = glm::lookAt( eye, center, up );
}
 
/////////////////////////////////////////////////
/// Change le viewport
/////////////////////////////////////////////////
void Camera::initProjection( unsigned int w, unsigned int h )
{
	float w2 = w / 2.f;
	float h2 = h / 2.f;
 
	// Mise à l'échelle
	glViewport(0, 0, w, h);	
 
	// Mise en place de la projection
	myProjection = glm::ortho( -w2, w2, -h2, h2, 0.01f, 100.0f);
}
Je dispose d'un objet "Drawable" qui possède plusieurs attributs :
- GLuint myVertexBuffer;
- GLuint* myIndicesBuffer;

J'ai choisis d'avoir un pointeur vers le buffer d'indices car plusieurs objet auront le même buffer pour les indices (l'ordre des indices ne change pas, je ne vois pas l'utilité d'avoir plusieurs copie).

Voici les méthodes utilisés pour les crées :
Code :
1
2
3
4
5
6
7
8
void Drawable::createVBO()
{
    std::vector<Vertex>& vertices = myVertices.getVertices();
 
    glGenBuffers(1, &myVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, myVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &(vertices[0]), GL_STATIC_DRAW);}
}
et pour les indices, je fais appel au ShapeCreator :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
void ShapeCreator::init()
{
    const GLubyte indices[] = {
		0, 1, 2,
		2, 3, 0
	};
 
    glGenBuffers(1, &mySquareIndices);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mySquareIndices);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
}
 
 
/////////////////////////////////////////////////
/// 
/////////////////////////////////////////////////
void ShapeCreator::buildRectangle( VertexArray& vertexArray, unsigned int w, unsigned int h )
{		
	vertexArray.append( Vertex( 0, 0 ) );
	vertexArray.append( Vertex( w, 0 ) );
	vertexArray.append( Vertex( 0, h ) );
	vertexArray.append( Vertex( w, h ) );
}
Après vérification, j'ai dans mon drawable à ce moment là ces valeurs :
myVerticesBuffer = 3
myIndicesBuffer = 2
Donc j'imagine que la génération des buffers c'est correctement faite.


2 - Le code qui me permet d'afficher mon Drawable est assez simple , j'ai commenté le code inutile pour le moment :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
void Drawable::draw()
{
	// Vector center	 = Vector( (myPosition.x + 150) * 0.5f, (myPosition.y + 150 ) * 0.5f );
 
	// Equivaut à un setIdentity avec OpenGL
	myModel = glm::mat4(1.0);
 
	// Déplacement
	myModel = glm::translate( myModel, glm::vec3( 0, 0, 0 ) );
 
	// Rotation et changement d'echelle
	/*myModel = glm::translate( myModel, glm::vec3( center.x, center.y, 0 ) );
	myModel = glm::rotate( myModel, 360.0f, glm::vec3( 0, 0, 1 ) );
	myModel = glm::scale( myModel, glm::vec3( 0, 0, 0 ) );
	myModel = glm::translate( myModel, glm::vec3( -center.x, -center.y, 0 ) );*/
 
	myProgram->draw( this );
}
Enfin, j'appelle "Program" qui est un objet générant les Shaders :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
void Program::draw( Drawable *drawable ) 
{
	Camera* camera	= GraphicEngine::getInstance()->getScreen()->getCamera();	
	GLuint* indicesBuffer = drawable->getIndicesBuffer();
	GLuint* verticesBuffer = drawable->getVertexBuffer();
 
	glm::mat4 mvp	= camera->getProjection() * camera->getView() * (*(drawable->getModel()));
 
       // Temps pour debuger
	const GLubyte indices[] = {
		0, 1, 2,
		2, 3, 0
	};
 
	// Lancement du programme
	glUseProgram( myId );
 
	// Activation du programme	
	glUniformMatrix4fv( myId, 1, GL_FALSE, glm::value_ptr(mvp) );
 
	// Bind du vertex buffer
	glBindBuffer(GL_ARRAY_BUFFER, *verticesBuffer);
 
        // Activation des attributs
	glVertexAttribPointer( myAttrPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(Vertex), 0 );
	glEnableVertexAttribArray( myAttrPosition );
	glVertexAttribPointer( myAttrColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4 * sizeof(Vertex), (void*)3 );
	glEnableVertexAttribArray( myAttrColor );
 
	// Bind des indices et affichage de la forme
	glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, *indicesBuffer );
	glDrawElements( GL_TRIANGLE_STRIP, sizeof(indices) / sizeof(GLubyte), GL_UNSIGNED_BYTE, indices);
 
	disableArrays();
	glUseProgram(0);
}
Et voilà c'est tout. là encore, le verticesBuffer vaut 3 et le indicesBuffer vaut 2.
De plus, les shaders sont compilés sans erreurs et sont correct puisque je les ai déjà utilisés sur un autre projet pour android.

Merci d'avance à ceux qui prendront le temps de se pencher sur mon problème.
Bonne journée/soirée à vous.
Pascal.

Ps: j'espere avoir été assez clair, je peux vous donner d'autres informations si besoin.

Voici d'autres informations supplémentaires concernant la classe Program puis les indices et vertex :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 
 
/////////////////////////////////////////////////
/// Compile les shaders
/////////////////////////////////////////////////
int Program::createShader( const char** sourceCode, const int shaderType )
{		
	int shaderId = glCreateShader( shaderType );		
 
	glShaderSource( shaderId, 1, sourceCode, NULL );
	glCompileShader( shaderId );
 
#if defined(DEBUG)	
	Log::getInstance()->add( Log::INFORMATION, "-> Compile un Shader." );
	GLint logLength;
	glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logLength);
 
	if (logLength > 0)
	{
		GLchar *log = (GLchar *)malloc(logLength);
		glGetShaderInfoLog(shaderId, logLength, &logLength, log);
		Log::getInstance()->add( Log::ERROR, log );
		free(log);
	}
#endif
 
	return shaderId;
}
 
/////////////////////////////////////////////////
/// Link les shaders
/////////////////////////////////////////////////
bool Program::linkShaders()
{
	myId = glCreateProgram();	
		glAttachShader( myId, myVertexShaderId );
		glAttachShader( myId, myFragmentShaderId );	
	glLinkProgram( myId );
 
	// ------------------------------------------------
	// TODO: Supprimer les shaders ici si tout est bon.
	// ------------------------------------------------
 
#if defined(DEBUG)
	Log::getInstance()->add( Log::INFORMATION, "-> Link le programme." );
 
	GLint logLength;
	glGetProgramiv(myId, GL_INFO_LOG_LENGTH, &logLength);
 
	if (logLength > 0)
	{
		GLchar *log = (GLchar *)malloc(logLength);
		glGetProgramInfoLog(myId, logLength, &logLength, log);
		Log::getInstance()->add( Log::ERROR, log );
		free(log);
	}
 
#endif
 
    return true;
}
 
 
////////////////////////////////////////////////////////////
/// Active les paramètres
////////////////////////////////////////////////////////////
void Program::linkAttributes() 
{
	myUniformMVP		= glGetUniformLocation( myId, "uMvp");
 
	myAttrPosition 		= glGetAttribLocation( myId, "aPosition" );
	myAttrColor			= glGetAttribLocation( myId, "aColor" );
}
 
#define FRAGMENT_SHADER "varying lowp vec4 vColor;          \n"\
						"void main(void) {					\n"\
							"gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);			\n"\
						"}									\n"\
 
#define VERTEX_SHADER	"uniform mat4 uMvp;\n"\
						"attribute vec4  aPosition;\n"\
						"attribute vec4  aColor;\n"\
						"varying vec4 vColor;\n"\
						"void main() {\n"\
							"gl_Position  = uMvp * aPosition;\n"\
							"vColor 	  = aColor;\n"\
						"}\n"\
La Classe Vertex
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Vertex
{
public:
 
	/////////////////////////////////////////////////
	/// Constructeur
	/////////////////////////////////////////////////
	Vertex();
	Vertex( float newX, float newY );
 
 
public:
 
    //< Position 
    GLfloat x;	//< Position en abscisse
    GLfloat y;	//< Position en ordonnée
 
    //< Couleurs
    GLubyte r;	//< Rouge
    GLubyte g;	//< Vert
    GLubyte b;	//< Bleu
    GLubyte a;	//< Transparence
 
};
Solaroid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/02/2012, 13h41   #2
Membre confirmé
 
Inscription : février 2006
Messages : 341
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 341
Points : 230
Points : 230
Je n'ai pas encore regardé en détail ton code mais j'ai une petite question pour orienter l'axe de recherche.

Si tu désactive le rendu avec shader, est ce que tu n'as plus l'écran noir et est ce que la géométrie affichée est correcte?
drcd est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/02/2012, 21h17   #3
Invité de passage
 
Homme Pascal
Développeur de jeux vidéo
Inscription : janvier 2012
Messages : 10
Détails du profil
Informations personnelles :
Nom : Homme Pascal
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2012
Messages : 10
Points : 2
Points : 2
Bonjour !

Merci d'avoir pris le temps de vous pencher sur mon problème.

Je m'apprêtais à désactiver le rendu avec shader et je suis finalement tombé sur une erreur (à l'aide de glGetError() ) :

glUniformMatrix4fv( myId, 1, GL_FALSE, glm::value_ptr(mvp) );
Error 1282 (GL_INVALID_OPERATION)

myId a pour valeur 6, ce qui est logiquement correct puisque différent de "-1".

C'est une petite avancé mais ce n'est pas encore ça :/

EDIT: J'ai trouvé pour cette erreur, je transmetais "myId" au lieu de "myMVPLocation". En revanche, toujours un écran noir.
Solaroid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/02/2012, 21h29   #4
Membre confirmé
 
Inscription : février 2006
Messages : 341
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 341
Points : 230
Points : 230
Tu as un écran noir avec les shaders désactivé?
On est bien d'accord que tu utilise le pipeline fixe?
drcd est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 12h12   #5
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 350
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 350
Points : 2 510
Points : 2 510
Bonjour.

Avant toute chose, merci de m'avoir fait rire avec ce titre. L'écran désespérément noir, nous avons tous connu ça.

Ensuite, je n'ai pas le temps d'examiner le code pour l'instant mais voici un conseil appris à la dure : toujours commencer simplement. Met en commentaire autant de code que possible jusqu'à revenir au triangle RGB de base à coups de glVertex. Puis utilise un VBO, passe ensuite à ton rectangle au lieu du triangle de base, et enfin active ton shader. Cela semble fastidieux mais en cinq minutes tu auras ta réponse.

Deux autres conseils :
* gDebugger est ton nouveau meilleur ami.
* Écrire une macro THROW_GL_ERROR qu'on ajoutera partout dans le code et qui ne sera active qu'en mode debug.


EDIT : Mention rayée vu qu'on est sur ES.
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 02/02/2012, 13h47   #6
Invité de passage
 
Homme Pascal
Développeur de jeux vidéo
Inscription : janvier 2012
Messages : 10
Détails du profil
Informations personnelles :
Nom : Homme Pascal
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2012
Messages : 10
Points : 2
Points : 2
Merci pour vos réponses !

@drcd: J'essaye sans les Shaders ce soir, je vais voir comment je dois m'y prendre. Etant avec opengl ES 2, je n'ai pas la méthode glVertexPointer, seulement glVertexAttribPointer.

@DonQuiche: En effet, je vais faire ça pour voir au fur et à mesure.
Concernant gDebugger, j'ai voulu l'utiliser seulement il n'est pas compatible avec Lion mais seulement Snow Leopard :/.
(Je suis récemment passé sur mac pour pouvoir développer sur les Idevices -_-')

Pour vous donner plus de détails, je travail sur un moteur de jeu en C++ que j'utilise ensuite dans mon projet Iphone (J'accroche pas du tout à l'objective C ^^). Le context opengl est crée depuis le code de base du SDK en objective C, j'appelle ensuite le moteur pour gérer les shaders et autres.

Je me suis donc dit que le rendu fait dans le moteur ne se faisait pas du coup sur l'affichage du SDK. Y a t-il un moyen de savoir si cela fonctionne ? Pour le moment j'ai tenté un "glClearColor()" depuis le moteur et l'écran se met dans la bonne couleur, j'imagine donc que ça fonctionne.

Dans un tutoriel j'ai trouvé une notion de renderBuffer et colorBuffer (http://www.raywenderlich.com/3664/op...phone-tutorial). Cela n'est pas présent dans mon code et j'ai lu sur un autre site que c'était facultatif, c'est vraiment le cas ?

(Concernant les shaders, je suis pratiquement sûr qu'ils sont bons puisque je les ai utilisés sur une application Android juste avant).

J'essaye cela dès que je rentre chez moi
Solaroid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 15h00   #7
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 350
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 350
Points : 2 510
Points : 2 510
Erf, développement sur mac en obj-c pour OGL ES, la totale... Bon courage.

Concernant les render buffers, je n'ai jamais expérimenté sur iPhone mais je vois que le site d'Apple précise :
Citation:
To correctly create a framebuffer:
* Create a framebuffer object.
* Create one or more targets (renderbuffers or textures), allocate storage for them, and attach each to an attachment point on the framebuffer object.
* Test the framebuffer for completeness.
Donc, oui, ça semble obligatoire. Maintenant je ne serais pas surpris que l'implémentation te laisse en réalité zapper la création du renderbuffer et le fait que glClearColor fonctionne me fait dire que c'est bien optionnel. En tout cas côté OPEN GL sur Windows ce n'est pas nécessaire et les frame buffers par défaut sont créés lors de l'appel à SetPixelFormat.

Enfin, les shaders sont sans doute corrects, c'est plutôt sur tout ce qu'il y avant ça que porte le risque.


PS : Il n'y a pas de pipeline fixe en OGL ES 2, que du programmable. Cf. correction apportée à mon précédent message, j'avais zappé le "ES".
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 22h34   #8
Invité de passage
 
Homme Pascal
Développeur de jeux vidéo
Inscription : janvier 2012
Messages : 10
Détails du profil
Informations personnelles :
Nom : Homme Pascal
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2012
Messages : 10
Points : 2
Points : 2
Me revoilà,

Toujours un écran noir, je commence à croire que ce n'est pas possible, je n'ai pas vraiment le moyen de tester avec des appels sans shaders et aucun moyen de debugguer (Vive Apple -_-)

J'ai eu l'idée d'utiliser mon moteur dans un projet opengl ES iphone existant pour voir ce que ça donnait.

Par défaut, l'application affiche un simple carré qui tourne. Dès que j'appelle mon moteur plus rien ne s'affiche à l'écran. J'ai donc fait étape par étape des tests histoires de voir ce qui posait problème. A ma surprise, en commentant la ligne suivante, le carré est de nouveau présent.

Code :
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
J'en conclue donc que c'est cette ici que ça coince le futur affichage. En revanche aucun soucis l'hors de la generation du buffer pour les indices.

J'ai donc cherché et j'ai remarqué que sur IOS, il y avait une méthode différente :

Code :
1
2
glGenVertexArraysOES(1, &myVertexBuffer);
glBindVertexArrayOES(myVertexBuffer);
au dessus de
Code :
1
2
3
glGenBuffers(1, &myVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, myVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);

J'ai vu que cette méthode était présent dans "gl2ext.h", j'ai beau l'inclure celle-ci n'est toujours pas présente.

Avez-vous des informations à ce sujet ? Merci d'avance !
Solaroid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2012, 11h46   #9
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 350
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 350
Points : 2 510
Points : 2 510
D'abord, à quoi sert cette ligne : les vertex array objects (VAO) sont différents des vertex arrays (VA), ces derniers étant obsolètes. Les VAO ont été introduits dans OGL3. Concernant OGL ES 2, je crois qu'ils ne sont qu'une extension, à vérifier.

Un VAO est simplement une astuce pour économiser des commandes. Aujourd'hui, quand tu te prépares à dessiner, tu as besoin de lier divers VBO à tes attributs de shaders, ce qui implique plusieurs commandes (glBindBuffer, glEnableVertexAttribArray, glVertexAttribPointer). Au lieu de cela, tu peux simplement regrouper une fois pour toutes ces commandes dans un VAO et, lors du rendu, n'utiliser qu'une seule commande (glBindVertexArray) pour rétablir tous les états correspondants et passer directement à glDraw***.

Tout cela est optionnel et tu peux très bien t'en passer. Maintenant, si tu souhaites les utiliser, concernant l'absence de glGenVertexArraysOES, si j'ai raison il ne s'agit que d'une extension (vérifier les specs pour s'en assurer) et tu dois alors voir comment les extensions sont utilisées sous OGL ES. Et traiter le cas des machines qui n'ont pas cette extension.
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2012, 22h29   #10
Invité de passage
 
Homme Pascal
Développeur de jeux vidéo
Inscription : janvier 2012
Messages : 10
Détails du profil
Informations personnelles :
Nom : Homme Pascal
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2012
Messages : 10
Points : 2
Points : 2
Merci pour ces informations .

Je viens de corriger le problème precedent, j'ai simplement inversé la création du VertexBuffer et celui de l'indiceBuffer Oo.

Le carré en rotation de l'animation de base s'affiche donc correctement. En revanche, voilà désormais une nouvelle erreur plus explicite :

"EXC_BAD_ACCESS"

À la ligne :
Code :
glDrawElements(GL_TRIANGLE_STRIP, sizeof(indices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, (void*)0);
Solaroid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2012, 23h02   #11
Invité de passage
 
Homme Pascal
Développeur de jeux vidéo
Inscription : janvier 2012
Messages : 10
Détails du profil
Informations personnelles :
Nom : Homme Pascal
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2012
Messages : 10
Points : 2
Points : 2
Bonsoir,

Problème precedent réglé, il s'agissait d'une erreur avec les sommets renseignés.

En revanche, retour au problème initial :
Code :
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
C'est cette ligne là qui pose problème, à chaque fois que je l'appelle, le reste de l'application ne fonctionne plus.

Cette ligne correspond à une allocatione, je ne vois pas ce qui l'empêcherait. Surtout que l'allocation pour les indices fonctionne très bien plus haut.

Bref, je commence à croire que ce n'est pas possible à faire .
Solaroid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2012, 11h34   #12
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 350
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 350
Points : 2 510
Points : 2 510
Bonjour.

Ton code initial ne montre pas le détail de l'assignation de myVertices et le contenu de getVertices, ni la façon dont ils sont articulés avec ShapeCreator. Toutefois, le reste semble correct.

As-tu vérifié au déboguage le contenu de vertices juste avant l'appel à glBufferData ? Ne serait-ce que vertices.size() ? Par ailleurs, quelle est l'erreur reçue ?

PS : Tu veux bien dire qu'en plaçant un glGetError juste après cette ligne tu obtiens une erreur ? Ou voulais-tu dire autre chose par "mon application ne fonctionne plus" ?
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2012, 12h53   #13
Invité de passage
 
Homme Pascal
Développeur de jeux vidéo
Inscription : janvier 2012
Messages : 10
Détails du profil
Informations personnelles :
Nom : Homme Pascal
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2012
Messages : 10
Points : 2
Points : 2
Bonjour,

Voici la classe contenant les Sommets :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
	class VertexArray
	{
	public:
 
		/////////////////////////////////////////////////
		/// Ajoute un vertex à la suite du tableau
		/////////////////////////////////////////////////
		void append( Vertex vertex );
 
		/////////////////////////////////////////////////
		/// Récupère les vertex
		/////////////////////////////////////////////////
		std::vector<Vertex>& getVertices();
 
	private:
 
		//< Tableau de vertex 
		std::vector<Vertex> myVertices;
 
	};
 
	/////////////////////////////////////////////////
	/// Ajoute un vertex au tableau
	/////////////////////////////////////////////////
	void VertexArray::append( Vertex vertex )
	{
		myVertices.push_back( vertex );
	}
 
	/////////////////////////////////////////////////
	/// Récupère les vertex
	/////////////////////////////////////////////////
	std::vector<Vertex>& VertexArray::getVertices()
	{
		return myVertices;
	}
L'assignation des vertex ce fait à ce moment la :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
// Depuis "Shape"
ShapeCreator::buildRectangle( myVertices, 100, 100);
 
// Dans le Shape Creator
void ShapeCreator::buildRectangle( VertexArray& vertexArray, unsigned int w, unsigned int h )
{		
	vertexArray.append( Vertex( 0, 0 ) );
	vertexArray.append( Vertex( w, 0 ) );
	vertexArray.append( Vertex( 0, h ) );
	vertexArray.append( Vertex( w, h ) );
}
J'ai ensuite affiché les différentes valeurs avant le "glBufferDate" :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
void Drawable::createVBO()
{
	std::vector<Vertex>& vertices = myVertices.getVertices();
 
    glGenBuffers(1, &myVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, myVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
 
	GLuint error = glGetError();
	Log::getInstance()->add( Log::INFORMATION, "-------");
	Log::getInstance()->add( Log::INFORMATION, "glGetError() : " + to_string(error));
	Log::getInstance()->add( Log::INFORMATION, "vertices.size() : " + to_string(vertices.size()));
	Log::getInstance()->add( Log::INFORMATION, "sizeof(Vertex) : " + to_string(sizeof(Vertex)));
	Log::getInstance()->add( Log::INFORMATION, "vertices.size() * sizeof(Vertex) : " + to_string(vertices.size() * sizeof(Vertex)));
	Log::getInstance()->add( Log::INFORMATION, "myVertexBuffer : " + to_string(myVertexBuffer));
 
	Log::getInstance()->add( Log::INFORMATION, "-------");
	Log::getInstance()->add( Log::INFORMATION, "Vertices : " );
	for( int i = 0; i < vertices.size(); i++)
	{
		Log::getInstance()->add( Log::INFORMATION, "vertices[" + to_string(i) + "] : " + to_string(vertices[i].x) + ", " + to_string(vertices[i].y));
	}
	Log::getInstance()->add( Log::ERROR, "-------");
}
Ce qui donne :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
INFORMATION : -------
INFORMATION : glGetError() : 0
INFORMATION : vertices.size() : 4
INFORMATION : sizeof(Vertex) : 12
INFORMATION : vertices.size() * sizeof(Vertex) : 48
INFORMATION : myVertexBuffer : 2
INFORMATION : -------
INFORMATION : Vertices : 
INFORMATION : vertices[0] : 0, 0
INFORMATION : vertices[1] : 100, 0
INFORMATION : vertices[2] : 0, 100
INFORMATION : vertices[3] : 100, 100
La classe Vertex contient :
Code :
1
2
3
4
5
6
7
8
9
    //< Position 
    GLfloat x;	//< Position en abscisse
    GLfloat y;	//< Position en ordonnée
 
    //< Couleurs
    GLubyte r;	//< Rouge
    GLubyte g;	//< Vert
    GLubyte b;	//< Bleu
    GLubyte a;	//< Transparence
Citation:
Par ailleurs, quelle est l'erreur reçue ?

PS : Tu veux bien dire qu'en plaçant un glGetError juste après cette ligne tu obtiens une erreur ? Ou voulais-tu dire autre chose par "mon application ne fonctionne plus" ?
Le "glGetError" ne retourne aucune erreur (Toujours "0").

Voici un résumé de l'application en plus simple :
1. J'ai crée un nouveau projet OpenGL sous Xcode pour iphone. Le code de base me donne ceci :


2. Je ne supporte pas trop l'ObjectiveC, il est par ailleurs possible de mélanger l'ObjectiveC avec du c++. Après quelques tests, il s'avère que tout fonctionne en C++. J'ai donc commencé à créer un moteur de jeu en C++ que j'utilise depuis ce sample (pour les tests).

3. Le problème : Dès que j'appelle mon moteur, il n'y a plus d'affichage à l'écran (Le carré de base du projet). Après quelques tests, j'ai remarqué que c'était le cas au moment ou je faisait mon "glBufferData". Il suffit que je commente cette ligne pour que le carré de base soit présent à l'écran.

En partant de ce constat, je me suis dit que le moteur n'avait pas accès au context opengl. Seulement ça ne semble pas être le cas puisque :
- glGenBuffer me retourne bien un numéro
- glBufferData, Pour les indices ne pose pas de problème puisque le carré de base est toujours présent.
- J'arrive à charger et compiler les shaders sans problème.
- glClearColor change bien la couleur de fond de l'application.

Du coup je pense vraiment que ça vient de "glBufferData" mais j'ai aucune erreur lors de son appel.

EDIT: Je viens de tester le glBufferData dans le projet de base OpenGL, il y a déjà l'erreur, ça ne vient donc pas du moteur.
Avec le code suivant :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
GLuint error;
	GLuint myVertexBuffer;
	std::vector<sx::Vertex> vertices;
	vertices.push_back( sx::Vertex( 0, 0 ) );
	vertices.push_back( sx::Vertex( 100, 0 ) );
	vertices.push_back( sx::Vertex( 0, 100 ) );
	vertices.push_back( sx::Vertex( 100, 100 ) );
 
	glGenBuffers(1, &myVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, myVertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(sx::Vertex), &vertices[0], GL_STATIC_DRAW);
EDIT 2: C'est encore pire que ce que je pensais, ça vient du projet de base qui est bizarre.
Je viens de tester avec un autre projet utilisant les VBO (trouvé sur le net). Quand je crée mes VBO ça fonctionne cette fois-ci ... seulement l'application utilise opengl ES 1. Dès que je passe à opengl ES2, plus rien O_O.
Solaroid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2012, 14h11   #14
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 350
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 350
Points : 2 510
Points : 2 510
Avant toute chose, je pense avoir trouvé le problème. Les deux lignes suivantes sont erronées. Le 4ème paramètre devrait être le stride en octets, or l'opérateur sizeof renvoie déjà la taille en octets, et non nombres de floats. Autrement dit il faut virer le "*4". Qui plus est l'offset pour les couleurs est également faux : la couleur est spécifiée après les composants X et Y qui mesurent chacun 4 octets, il faut donc spécifier 8 et non 3.
Code :
1
2
	glVertexAttribPointer( myAttrPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(Vertex), 0 );
	glVertexAttribPointer( myAttrColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4 * sizeof(Vertex), (void*)3 );
Maintenant, pour la petite histoire, quand tu mettais en commentaires glBufferData, le buffer des sommets n'était jamais initialisé. Dès lors OGL devait zapper les lignes erronée que j'ai relevé et l'appel à DrawElements (ou alors avec le buffer spécifié par le code d'origine puisqu'apparemment tu as un autre code de rendu en amont).


EDIT : Tu ferais mieux de virer ce projet de base et partir d'un projet vide.
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/02/2012, 10h22   #15
Invité de passage
 
Homme Pascal
Développeur de jeux vidéo
Inscription : janvier 2012
Messages : 10
Détails du profil
Informations personnelles :
Nom : Homme Pascal
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : janvier 2012
Messages : 10
Points : 2
Points : 2
Merci beaucoup pour ces précisions .

J'ai finalement réussi, il y a plusieurs choses qui posaient problèmes :
- Le projet OpenGL offert (gentiment) par Apple est faux, il vaut mieux partir d'un projet vide.
- Le quatrième paramètre est en effet en Byte, mais je l'avais corrigé entre temps en utilisant "offsetof(Vertex, r)"
- Le troisième paramètre n'est pas la taille total de "vertices" mais la taille pour un Vertex.

Si ça peut aider/sauver quelques jours de recherche à quelqu'un .

En tout cas, merci encore pour votre aide !
Solaroid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 11h18   #16
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 350
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 350
Points : 2 510
Points : 2 510
De rien.

Cela dit, pour le projet Appel, vu ce que tu nous en as dit je pense que le problème est que tu as pris une ancienne version, destinée aux premiers iPhones qui tournaient sous OGL ES 1.
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2012, 17h23   #17
Membre Expert
 
Inscription : juillet 2006
Messages : 1 396
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 1 396
Points : 1 335
Points : 1 335
Citation:
Envoyé par DonQuiche Voir le message
Deux autres conseils :
* gDebugger est ton nouveau meilleur ami.
* Écrire une macro THROW_GL_ERROR qu'on ajoutera partout dans le code et qui ne sera active qu'en mode debug.
Un peu en retard, mais merci pour ça.
deadalnix est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h35.


 
 
 
 
Partenaires

Hébergement Web