Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Game Development

Reply
 
LinkBack Thread Tools Display Modes
Old 02-11-2010, 06:41 PM   #1 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 53
supertaurus85 is on a distinguished road
Default Open GL: changing appearance after first rendering

Hello,
I'm new to OpenGL and I'm trying to do an X3D viewer for the iPhone. The project is opensource and here is the code you can checkout from google code:

Code:
svn checkout http://ix3d.googlecode.com/svn/trunk/ ix3d
I'm able to parse the XML and draw in the screen all the content (at the moment geometries and various types of lights, soon I'll add transformations).

The only problem is that the app draws the first frame properly and from the second is like the lights are turned off. I set the refreshing rate to 1sec so you see this clearly.

I tried many options, but I can't figure out what's the problem, so some help will be very welcome

Last edited by supertaurus85; 02-12-2010 at 04:11 AM.
supertaurus85 is offline   Reply With Quote
Old 02-12-2010, 02:49 AM   #2 (permalink)
Registered Member
 
Join Date: Feb 2010
Posts: 226
mlfarrell is on a distinguished road
Default

OpenGL is state based. You need to re-enable lighting via glEnable to turn it back on. Also the individual lights you use namely GL_LIGHT0
mlfarrell is offline   Reply With Quote
Old 02-12-2010, 04:09 AM   #3 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 53
supertaurus85 is on a distinguished road
Default

Quote:
Originally Posted by mlfarrell View Post
OpenGL is state based. You need to re-enable lighting via glEnable to turn it back on. Also the individual lights you use namely GL_LIGHT0
I do glEnable everytime I start a parent of a light node, and a glDisable everytime I end that node.
So the scene was properly lighted the first time, why it's not the second time?
supertaurus85 is offline   Reply With Quote
Old 02-12-2010, 12:43 PM   #4 (permalink)
Registered Member
 
Join Date: Feb 2010
Posts: 226
mlfarrell is on a distinguished road
Default

Paste your drawing routine
mlfarrell is offline   Reply With Quote
Old 02-12-2010, 12:46 PM   #5 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 53
supertaurus85 is on a distinguished road
Default

Quote:
Originally Posted by mlfarrell View Post
Paste your drawing routine
it's really long...

Code:
#pragma mark drawView
- (void)drawView {
	//NSLog(@"Starting to draw...");
	// provare a spostare da qualche altra parte
	if (appDelegate == nil)
		appDelegate = (iX3DAppDelegate *)[UIApplication sharedApplication].delegate;
	
	// This application only creates a single context which is already set current at this point.
	// This call is redundant, but needed if dealing with multiple contexts.
    [EAGLContext setCurrentContext:context];
    
	// This application only creates a single default framebuffer which is already bound at this point.
	// This call is redundant, but needed if dealing with multiple framebuffers.
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);
	
	glClearColor(0.5, 0.5, 0.5, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_MODELVIEW); // passo alla modalità per mettere gli oggetti nella scena
	
	/*
	 Inizio codice OpenGL per disegnare
	 */
	
	glEnable(GL_COLOR_MATERIAL);
	//glFrontFace(GL_CCW);
	
	[self drawTree: root]; // inizio a disegnare dalla radice
	
	/*
	 Fine codice OpenGL per disegnare
	 */
	
    // This application only creates a single color renderbuffer which is already bound at this point.
	// This call is redundant, but needed if dealing with multiple renderbuffers.
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewFramebuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
	
	[self stopAnimation];
}

-(void)drawTree:(X3DNode*)currentNode {
	
	X3DNode *node;
	int firstLightOfTheNode=0;
	
	//NSLog(@"starting: %@", [currentNode description]);
	
	if ( currentNode.lights > 0 ) { // i nodi figli devono essere illuminati
		//NSLog(@"i suoi figli hanno luce");
		if ( numberOfLights + currentNode.lights < 8 ) {
			firstLightOfTheNode = currentLight;
			glEnable(GL_LIGHTING);
			for (int i=0 ; i<currentNode.lights ; i++) {
				NSLog(@"GL_LIGHT0: %d - luca abilitata: %d", GL_LIGHT0, currentLight+numberOfLights+i);
				NSLog(@"currentLight: %d - numberOfLights: %d - i: %d", currentLight, numberOfLights, i);
				glEnable(currentLight+numberOfLights+i); // abilito tante luci quante ce ne sono nei figli del currentNode
			}
		}
		else {
			NSLog(@"troppe luci");
		}
		numberOfLights+=currentNode.lights; // il numero delle luci viene aumentato
	} 
	/****** vedo che tipo di nodi figli ho e chiamo le varie funzioni che utilizzeranno OpenGL  ******/
	for ( node in currentNode.sons ) {
		if ( [node isMemberOfClass:[Shape class]] ) {
			//NSLog(@"one of the sons is a shape");
			[self drawTree:node];
		}
		else if ( [node isMemberOfClass:[IndexedFaceSet class]] ) {
			//NSLog(@"one of the sons is a indexedf...");
			[self drawIndexedFaceSet:(IndexedFaceSet*)node];
		}
		else if ( [node isKindOfClass:[Light class]] ) { // appartiene ad una sottoclasse di Light
			//NSLog(@"one of the sons is a light...");
			[self setLight:(Light*)node];
		}
	}
	if ( currentNode.lights > 0 ) { // finisco il nodo i cui figli devono essere illuminati
		if ( numberOfLights < 8 ) {
			for (int i=0 ; i<currentNode.lights ; i++) {
				NSLog(@"GL_LIGHT0: %d - luca disabilitata: %d", GL_LIGHT0, firstLightOfTheNode+i);
				NSLog(@"firstLightOfTheNode: %d - i: %d", firstLightOfTheNode, i);
				glDisable(firstLightOfTheNode+i); // vengono disabilitate le luci che dovevano illuminare i figli di questo nodo.
				currentLight--;
			}
		}
		numberOfLights-=currentNode.lights;
		if ( numberOfLights == 0 ) {
			glDisable(GL_LIGHTING);
			NSLog(@"numberOfLights == 0");
		} 
	}
	//NSLog(@"I'm finishing with the node %@", [currentNode description]);
}

#pragma mark Metodi disegno ausiliari
- (void)drawIndexedFaceSet:(IndexedFaceSet *)indexedFaceSet
{
	GLfloat shapeVertices[indexedFaceSet.coordIndexSize*3-1]; // una figura non avrà mai più vetici di così
	GLfloat colorVertices[indexedFaceSet.coordIndexSize*4-1];
	GLfloat normalVertices[indexedFaceSet.coordIndexSize*3-1];
	int faceSize = 0; //Number of vertex in current face
	int currentFace = 0; // numero della faccia corrente
		
	for (int index = 0; index < indexedFaceSet.coordIndexSize; index++)
	{
		if (indexedFaceSet.coordIndex[index] != -1)
		{
			int position = (indexedFaceSet.coordIndex[index]) * 3;
			
			shapeVertices[faceSize*3] = indexedFaceSet.coord[position];
			shapeVertices[faceSize*3+1] = indexedFaceSet.coord[position + 1];
			shapeVertices[faceSize*3+2] = indexedFaceSet.coord[position + 2];
			
			if ( indexedFaceSet.normalSize == indexedFaceSet.coordSize ) { // se abbiamo a disposizione le normali
				normalVertices[faceSize*3] = indexedFaceSet.normalArray[position];
				normalVertices[faceSize*3+1] = indexedFaceSet.normalArray[position + 1];
				normalVertices[faceSize*3+2] = indexedFaceSet.normalArray[position + 2];
			}
			
			if ( indexedFaceSet.colorPerVertex && indexedFaceSet.colorSize == indexedFaceSet.coordSize ) { // un colore diverso per ogni vertice
				colorVertices[faceSize*4] = indexedFaceSet.colorArray[position];
				colorVertices[faceSize*4+1] = indexedFaceSet.colorArray[position + 1];
				colorVertices[faceSize*4+2] = indexedFaceSet.colorArray[position + 2];
				colorVertices[faceSize*4+3] = 0.8f;
			}
			
			faceSize++;
		}
		//End of a face...
		else
		{
			// un colore unico per ogni faccia
			if ( !indexedFaceSet.colorPerVertex && currentFace*4+2 < indexedFaceSet.colorSize ) {
				glColor4f(indexedFaceSet.colorArray[currentFace*4],
						  indexedFaceSet.colorArray[currentFace*4+1],
						  indexedFaceSet.colorArray[currentFace*4+2],
						  0.8f);
			}
			else { // un colore diverso per ogni vertice
				glColorPointer(4, GL_FLOAT, 0, colorVertices);
				glEnableClientState(GL_COLOR_ARRAY); // abilito il disegno con i color array
			}

			//Draw current face
			glVertexPointer(3, GL_FLOAT, 0, shapeVertices);
			glEnableClientState(GL_VERTEX_ARRAY);
			glEnableClientState(GL_NORMAL_ARRAY);
			glNormalPointer(GL_FLOAT, 0, normalVertices);
			glDrawArrays(GL_TRIANGLE_FAN, 0, faceSize);
			
			//Get ready for next face
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			faceSize = 0;
			currentFace++;
			glDisableClientState(GL_VERTEX_ARRAY);
			glDisableClientState(GL_NORMAL_ARRAY);
		}
	}
}

-(void)setLight:(Light *)light {
		
	GLfloat LightPosition[3];
	GLfloat LightAmbient[]= { 0.2f, 0.2f, 0.2f, 1.0f }; // luce ambiente (in x3d non si mette)
	GLfloat LightDiffuse[]= { light.color[0], light.color[1], light.color[2], 1.0f }; // Componente diffuse
	
	for ( int i = 0 ; i < 3 ; i++ ) {
		LightAmbient[i] *= light.ambientIntensity;
		LightDiffuse[i] *= light.intensity;
	}
	
	/*** DirectionalLight ***/
	if ( [light isMemberOfClass:[DirectionalLight class]] ) {
		DirectionalLight *dlight = (DirectionalLight *)light;
		for ( int i = 0 ; i < 4 ; i++ )
			LightPosition[i] = dlight.direction[i]; // questa è la direzione della luce, l'elemento di indice 3 è messo a 0.0f
	}
	/*** PointLight ***/
	else if ( [light isMemberOfClass:[PointLight class]] ) {
		PointLight *plight = (PointLight *)light;
		for ( int i = 0 ; i < 4 ; i++ )
			LightPosition[i] = plight.location[i]; // questa è la direzione della luce, l'elemento di indice 3 è messo a 1.0f
		// cutoff è di 180*2
		glLightf(currentLight, GL_SPOT_CUTOFF, 180.0f);
		// attenuation
		glLightf(currentLight, GL_CONSTANT_ATTENUATION, plight.attenuation[0]);
		glLightf(currentLight, GL_LINEAR_ATTENUATION, plight.attenuation[1]);
		glLightf(currentLight, GL_QUADRATIC_ATTENUATION, plight.attenuation[2]);
	}
	/*** SpotLight ***/
	else if ( [light isMemberOfClass:[SpotLight class]] ) {
		SpotLight *slight = (SpotLight *)light;
		GLfloat LightDirection[3];
		for ( int i = 0 ; i < 4 ; i++ ) {
			LightPosition[i] = slight.location[i]; // questa è la direzione della luce, l'elemento di indice 3 è messo a 1.0f
			LightDirection[i] = slight.direction[i];
		}
		// cutoff
		glLightf(currentLight, GL_SPOT_CUTOFF, slight.cutOffAngle/3.1415926536*180);
		// direction
		glLightfv(currentLight, GL_SPOT_DIRECTION, LightDirection);
		// attenuation
		glLightf(currentLight, GL_CONSTANT_ATTENUATION, slight.attenuation[0]);
		glLightf(currentLight, GL_LINEAR_ATTENUATION, slight.attenuation[1]);
		glLightf(currentLight, GL_QUADRATIC_ATTENUATION, slight.attenuation[2]);
		// beamwidth
		float ft = 0.5/(slight.beamWidth +0.1);
		if (ft>128.0) ft=128.0;
		if (ft<0.0) ft=0.0;
		glLightf(currentLight, GL_SPOT_EXPONENT,ft);
	}
	
	glLightfv(currentLight, GL_AMBIENT, LightAmbient);	
	glLightfv(currentLight, GL_DIFFUSE, LightDiffuse);				// Setup The Diffuse Light
	glLightfv(currentLight, GL_POSITION, LightPosition);			// Position The Light
	currentLight++;
}
supertaurus85 is offline   Reply With Quote
Old 02-13-2010, 01:54 PM   #6 (permalink)
Registered Member
 
Join Date: Feb 2010
Posts: 226
mlfarrell is on a distinguished road
Default

I can sort of follow this but your code does some very inefficient things we all do when starting out

Namely the
[self stopAnimation]; at the end of each drawing call. If you want asynchronous drawing, then call drawView asynchronously from tap events and don't initialize the timer.

Also, glEnable(GL_LIGHTING) inside a loop is redundant and each state call in opengl on an iphone is very costly, Do this. Remove or comment ALL glEnable/glDisable calls pertaining to lights.

Now, at the very beginning in your drawview call do
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

work? if so, add GL_LIGHT1,2,3... as necessary. If you only use one light, then stick with 0. You can go back to the dynamic stuff when you have the simple case working
mlfarrell is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 394
9 members and 385 guests
13dario13, ChrisYates, fredidf, iOS.Lover, jeroenkeij, Leslie80, Wikiboo, Yosh_K
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,670
Threads: 94,121
Posts: 402,903
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Yosh_K
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 04:41 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0