How to correctly aply UV coords for texture?

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

How to correctly aply UV coords for texture?

Post by Ghoti »

Hi folks,

I use an .obj file to render on the screen. Now that my vertex problems are over i'm having problems with my texture coordinates :(

see the pictures below. the first is how it should be and the second is how it is displayed on my psp :S

good:
Image

and the wrong one:
Image

Here is the code is use for loading and rendering the obj file (obj file is triangulated)

Code: Select all

void LoadObjectTriangles(const char *filename, MeshC *tmpObj) {

		// loop through the mesh and find groups.
		char ReadBuffer[256];
		unsigned int vc=0,nc=0,tc=0, fc=0;
		unsigned int i=0;
		unsigned int iNumberOfFaces, iNumberOfVertices, iNumberOfTexCoords;

		iNumberOfGroups = 0;
		iNumberOfFaces = 0;

		FILE *fp = NULL;
		if ((fp = fopen(filename, "rb")) == NULL) { iNumberOfGroups = -1; return; }
		while(!feof(fp))
		{
			fgets(ReadBuffer, 256, fp);
			if (strncmp("g default", ReadBuffer, 9) == 0 )
			{
				iNumberOfGroups++;
			}
			else if (strncmp("v ", ReadBuffer, 2) == 0 )
			{
				vc++;
			}
			else if (strncmp("vt ", ReadBuffer, 3) == 0 )
			{
				tc++;
			}
			else if (strncmp("f ", ReadBuffer, 2) == 0 )
			{
				fc++;
			}
		}
		fclose(fp);

		iNumberOfFaces = fc;
		iNumberOfVertices = vc;
		iNumberOfTexCoords = tc;

		ObjVertex		Vertices[ iNumberOfVertices ];
		ObjTexCoord		TexCoords[ iNumberOfTexCoords ];
		ObjFaceNew		Faces[ iNumberOfFaces ];


		iNumberOfGroups = 0;

		vc=0;
		nc=0;
		tc=0;
		fc=0;

		if ((fp = fopen(filename, "rb")) == NULL) { iNumberOfGroups = -1; return; }
		while(!feof(fp))
		{
			fgets(ReadBuffer, 256, fp);
			if (strncmp("g default", ReadBuffer, 9) == 0 )
			{
				if (iNumberOfGroups == 0) {

				}
				else {
					iNumberOfGroups++;
				}
			}
			else if (strncmp("v ", ReadBuffer, 2) == 0 )
			{
				sscanf((ReadBuffer+2), "%f%f%f",&Vertices[ vc ].x, &Vertices[ vc ].y, &Vertices[ vc ].z); 
				vc++;
			}
			else if (strncmp("vt ", ReadBuffer, 3) == 0 )
			{
				sscanf((ReadBuffer+3), "%f%f",&TexCoords[ tc ].u, &TexCoords[ tc ].v); 
				tc++;
			}

			else if (strncmp("f ", ReadBuffer, 2) == 0 )
			{
				
				char *pSplitString = NULL;
				int Waste;
				i=0;
				pSplitString = strtok((ReadBuffer+2)," \t\n");

				do {

					sscanf((pSplitString), "%d/%d/%d",&Faces[ fc ].vertices[ i ], &Faces[ fc ].textc[ i ],&Waste); 
					Faces[ fc ].textc[ i ] -= 1;		// 1 down because the obj file objects start at 1 and arrays start at 0
					Faces[ fc ].vertices[ i ] -= 1;
					pSplitString = strtok(NULL," \t\n");
					i += 1;
				}
				while( pSplitString );
				
				
				
				
				fc++;
			}
		}
		fclose(fp);


		// All is read now for the optimization :)
		
		tmpObj->Faces = (ObjFaceC*)malloc(iNumberOfFaces * sizeof(ObjFaceC));
		tmpObj->Vertices = (ObjVertexB*)malloc(iNumberOfFaces * 3 * sizeof(ObjVertexB));
		tmpObj->iNumberOfFaces = iNumberOfFaces;

		int j,k,l;
		l = 0;

		for &#40;j=0;j<iNumberOfFaces;j++&#41;
		&#123;
			for &#40;k=0; k<3; k++&#41;
			&#123;
				tmpObj->Vertices&#91;l&#93;.u = TexCoords&#91;Faces&#91;j&#93;.textc&#91;k&#93;&#93;.u;
				tmpObj->Vertices&#91;l&#93;.v = TexCoords&#91;Faces&#91;j&#93;.textc&#91;k&#93;&#93;.v;
				tmpObj->Vertices&#91;l&#93;.color = 0xffffff00;
				tmpObj->Vertices&#91;l&#93;.x = Vertices&#91;Faces&#91;j&#93;.vertices&#91;k&#93;&#93;.x;
				tmpObj->Vertices&#91;l&#93;.y = Vertices&#91;Faces&#91;j&#93;.vertices&#91;k&#93;&#93;.y;
				tmpObj->Vertices&#91;l&#93;.z = Vertices&#91;Faces&#91;j&#93;.vertices&#91;k&#93;&#93;.z;
				l++;
			&#125;
		&#125;

		sprintf&#40;sBuffer, "Textures/UVtexturesHousePlatDak1024type3.png"&#41;;
		tmpObj->texture = loadImage&#40;sBuffer&#41;;

		sceKernelDcacheWritebackInvalidateAll&#40;&#41;;

	&#125;

	
	void RenderObjectTriangles&#40;MeshC *tmpObj&#41; &#123;

		matrix_identity&#40;&#40;float*&#41;&world&#41;;
		matrix_translate&#40;&#40;float*&#41;&world,0,0,0&#41;;
		sceGuSetMatrix&#40;GU_MODEL,&world&#41;;

		sceGuTexMode&#40;GU_PSM_8888, 0 ,0 ,0&#41;;
		sceGuTexImage&#40;0,tmpObj->texture->textureWidth,tmpObj->texture->textureHeight, tmpObj->texture->textureWidth, &#40;void*&#41;tmpObj->texture->data&#41;;
		sceGuTexFunc&#40;GU_TFX_REPLACE, GU_TCC_RGB&#41;;
		sceGuTexFilter&#40;GU_LINEAR, GU_LINEAR&#41;;
		sceGuTexScale&#40;1.0f, 1.0f&#41;;
		sceGuTexOffset&#40;0.0f, 0.0f&#41;;

		//float u = 1.0f / &#40;&#40;float&#41;tmpObj->texture->textureWidth&#41;;
		//float v = 1.0f / &#40;&#40;float&#41;tmpObj->texture->textureHeight&#41;;

		//float u = &#40;&#40;float&#41;tmpObj->texture->textureWidth&#41;;
		//float v = &#40;&#40;float&#41;tmpObj->texture->textureHeight&#41;;
		//sceGuTexScale&#40;u, v&#41;;

		sceGuDrawArray&#40;GU_TRIANGLES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,tmpObj->iNumberOfFaces*3,0,tmpObj->Vertices&#41;;
		
	&#125;
Hope someone can help me out

greets ghoti

PS the blueish is because of lighting that is not the problem i mean its the strange way the texture is projected on my mesh.

scaling does not seem to work the way i commented out.
memon
Posts: 63
Joined: Mon Oct 03, 2005 10:51 pm

Post by memon »

This is kinda common problem. The problem is that different APIs define the texture in different ways. Some assume that the 0,0 texture coordinates are top-left, some bottom-left.

First make sure your texture loading stuff loads the texture the right way, and then adjust the texture coordinates to match it, flipping the V coordinate as needed. -V or 1-V should both do the trick.

Unfortunately I cant remember if the psp uses the same origin as opengl (bottom-left) or was it one of those top-left things.
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Thanks, that did the trick, its funny i tried everything with offsets and scaling but i forgot the v flip of which i have read so much in pc programming :S

thanks
Post Reply