Problem with light in GX

Post Reply
Sheeft
Posts: 5
Joined: Fri Aug 27, 2010 11:56 pm

Problem with light in GX

Post by Sheeft » Sat Aug 28, 2010 12:07 am

Hi everybody,

I'm searching for a while now and I still can't get how to use lights correctly with GX.
The problem is that, my colors are not shown when I put lights on… And I don't get why.

If you want, here is my code :
main.cpp
wiilib.h
wiilib.cpp

And here is the dol to see the problem : lights.dol

In fact, my code draws 27 colored cubes to create a greater cube but this colors don't appear… I only see a black and white sample.
Before I tried to add lights, all colors were displayed as they had to, so I don't understand…

Could you help me finding it out ?

Thanks a lot in advance ! :D

Sheeft
Posts: 5
Joined: Fri Aug 27, 2010 11:56 pm

Re: Problem with light in GX

Post by Sheeft » Sun Aug 29, 2010 11:25 am

Well, I understand that it is not really easy to help me this way…
So I will change the format of my request :

Could you, please, give me the minimum code I need to use lights, textures, and colors (with alpha) ? And could you also give me an example of how to use more than one vertex descriptor ? (one just for colors and one for textures with normals for example).

Thanks a lot ! I really need you.

EDIT : Finally, I changed to use directly the example and I tested it on the Wii directly and it worked… In fact the problem was coming from dolphin…
My actual example (with this code) remains unworking, but now it works fine.

If you just could explain me how to use diferent vertex descriptor… Thanks ! :D

shagkur
Posts: 53
Joined: Thu Sep 08, 2005 8:40 pm

Re: Problem with light in GX

Post by shagkur » Mon Aug 30, 2010 9:39 am

Hi

To get lightning to work you need to load the inverse-transpose matrix of your modelview matrix into the normals memory matrix (GX_LoadNrmMtxImm).

regards
shagkur

shagkur
Posts: 53
Joined: Thu Sep 08, 2005 8:40 pm

Re: Problem with light in GX

Post by shagkur » Mon Aug 30, 2010 1:55 pm

Hi,

you use it pretty much the same way like you do with "GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);".
But instead of GX_VTXFMT0 you take one of the other 6, i.e GX_VTXFMT1 - 7. GX_SetVtxDesc must be used accordingly to the Vertex Attribute Format setup.
And to tell GX which VTXFMT to use us set it in GX_Begin, i.e "GX_Begin(GX_TRIANGLE,GX_VTXFMT1,3);".

regards
shagkur

Sheeft
Posts: 5
Joined: Fri Aug 27, 2010 11:56 pm

Re: Problem with light in GX

Post by Sheeft » Tue Aug 31, 2010 2:26 pm

Thanks a lot !

But what I don't understand is about GX_SetVtxDesc… How can we use it with multiple vertex desc if we cannot specify the GX_VTXFMT ?

Thanks

Samson
Posts: 35
Joined: Mon May 19, 2008 8:05 am

Re: Problem with light in GX

Post by Samson » Tue Aug 31, 2010 5:35 pm

Sheeft wrote:But what I don't understand is about GX_SetVtxDesc… How can we use it with multiple vertex desc if we cannot specify the GX_VTXFMT ?
Unfortunately you cannot... it's global for all formats. But it should be cheap enough to enable/disable individual components as required. And you'll probably do a top-level sort by vertex format anyway.

shagkur
Posts: 53
Joined: Thu Sep 08, 2005 8:40 pm

Re: Problem with light in GX

Post by shagkur » Tue Aug 31, 2010 6:29 pm

Hi,

right what Samson said, it's a global for all formats.
It finally tells the GPU what data to expect. So in a normal scenario you would do this right before GX_Begin.
And by calling GX_ClearVtxDesc, before the chain of GX_SetVtxDesc calls for the used GX_VTXFMT, the current Vertex Descriptor setup gets cleared.
As an example i paste you the way i do it in wiirrlicht.

Here from the driver initialisation:

Code: Select all

			//setup vtxfmt EVT_STANDARD
			GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);

			//setup vtxfmt EVT_2TCOORDS
			GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX1, GX_TEX_ST, GX_F32, 0);

			//setup vtxfmt EVT_TANGENT
			GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_NBT, GX_NRM_NBT, GX_F32, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
			GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);

And here how it's used later:

Code: Select all

		void CGXDriver::drawVertexPrimitiveList(const void *vertices,u32 vertexCnt,const u16 *indices,u32 primitiveCnt,E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,E_INDEX_TYPE iType)
		{
			u32 vtxfmt = GX_VTXFMT0;
			u32 vtxmode = GX_DIRECT;

			if(!primitiveCnt || !vertexCnt) return;

			CNullDriver::drawVertexPrimitiveList(vertices,vertexCnt,indices,primitiveCnt,vType,pType,iType);

			if(vertices==NULL) vtxmode = GX_INDEX16;

			GX_ClearVtxDesc();
			GX_SetVtxDesc(GX_VA_POS,vtxmode);
			GX_SetVtxDesc(GX_VA_CLR0,vtxmode);
			GX_SetVtxDesc(GX_VA_TEX0,vtxmode);

			switch(vType) {
				case EVT_STANDARD:
					vtxfmt = GX_VTXFMT0;
					GX_SetVtxDesc(GX_VA_NRM,vtxmode);
					break;
				case EVT_2TCOORDS:
					vtxfmt = GX_VTXFMT1;
					GX_SetVtxDesc(GX_VA_NRM,vtxmode);
					GX_SetVtxDesc(GX_VA_TEX1,vtxmode);
					break;
				case EVT_TANGENTS:
					vtxfmt = GX_VTXFMT2;
					GX_SetVtxDesc(GX_VA_NBT,vtxmode);	
					break;
			}

			setRenderStates3DMode();

			switch(pType) {
				case scene::EPT_TRIANGLES:
					drawVertexPrimitiveListGX(GX_TRIANGLES,vtxfmt,vertices,indices,primitiveCnt*3,vType);
					break;
				case scene::EPT_TRIANGLE_FAN:
					drawVertexPrimitiveListGX(GX_TRIANGLEFAN,vtxfmt,vertices,indices,primitiveCnt+2,vType);
					break;
				case scene::EPT_LINE_STRIP:
					drawVertexPrimitiveListGX(GX_LINESTRIP,vtxfmt,vertices,indices,primitiveCnt+1,vType);
					break;
				default:
					break;
			}
		}


		void CGXDriver::drawVertexPrimitiveListGX(u8 pType,u8 vtxfmt,const void *vertices,const u16 *indices,u16 primitiveCnt,E_VERTEX_TYPE vType)
		{
			u32 i;

			GX_Begin(pType,vtxfmt,primitiveCnt);
			switch(vType) {
				case EVT_STANDARD:
				{
					if(vertices) {
						const S3DVertex *v = reinterpret_cast<const S3DVertex*>(vertices);
						for(i=0;i<primitiveCnt;i++) {
							GX_Position3f32(v[indices[i]].pos.X,v[indices[i]].pos.Y,v[indices[i]].pos.Z);
							GX_Normal3f32(v[indices[i]].nrm.X,v[indices[i]].nrm.Y,v[indices[i]].nrm.Z);
							GX_Color4u8(v[indices[i]].col.getRed(),v[indices[i]].col.getGreen(),v[indices[i]].col.getBlue(),v[indices[i]].col.getAlpha());
							GX_TexCoord2f32(v[indices[i]].tcoord.X,v[indices[i]].tcoord.Y);
						}
					} else {
						for(i=0;i<primitiveCnt;i++) {
							GX_Position1x16(indices[i]);
							GX_Normal1x16(indices[i]);
							GX_Color1x16(indices[i]);
							GX_TexCoord1x16(indices[i]);
						}
					}
				}
				break;

				case EVT_2TCOORDS:
				{
					if(vertices) {
						const S3DVertex2TCoords *v = reinterpret_cast<const S3DVertex2TCoords*>(vertices);
						for(i=0;i<primitiveCnt;i++) {
							GX_Position3f32(v[indices[i]].pos.X,v[indices[i]].pos.Y,v[indices[i]].pos.Z);
							GX_Normal3f32(v[indices[i]].nrm.X,v[indices[i]].nrm.Y,v[indices[i]].nrm.Z);
							GX_Color4u8(v[indices[i]].col.getRed(),v[indices[i]].col.getGreen(),v[indices[i]].col.getBlue(),v[indices[i]].col.getAlpha());
							GX_TexCoord2f32(v[indices[i]].tcoord.X,v[indices[i]].tcoord.Y);
							GX_TexCoord2f32(v[indices[i]].tcoord2.X,v[indices[i]].tcoord2.Y);
						}
					} else {
						for(i=0;i<primitiveCnt;i++) {
							GX_Position1x16(indices[i]);
							GX_Normal1x16(indices[i]);
							GX_Color1x16(indices[i]);
							GX_TexCoord1x16(indices[i]);
							GX_TexCoord1x16(indices[i]);
						}
					}
				}
				break;

				case EVT_TANGENTS:
				{
					if(vertices) {
						const S3DVertexTangents *v = reinterpret_cast<const S3DVertexTangents*>(vertices);
						for(i=0;i<primitiveCnt;i++) {
							GX_Position3f32(v[indices[i]].pos.X,v[indices[i]].pos.Y,v[indices[i]].pos.Z);
							GX_Normal3f32(v[indices[i]].nrm.X,v[indices[i]].nrm.Y,v[indices[i]].nrm.Z);
							GX_Normal3f32(v[indices[i]].binrm.X,v[indices[i]].binrm.Y,v[indices[i]].binrm.Z);
							GX_Normal3f32(v[indices[i]].tangent.X,v[indices[i]].tangent.Y,v[indices[i]].tangent.Z);
							GX_Color4u8(v[indices[i]].col.getRed(),v[indices[i]].col.getGreen(),v[indices[i]].col.getBlue(),v[indices[i]].col.getAlpha());
							GX_TexCoord2f32(v[indices[i]].tcoord.X,v[indices[i]].tcoord.Y);
						}
					} else {
						for(i=0;i<primitiveCnt;i++) {
							GX_Position1x16(indices[i]);
							GX_Normal1x16(indices[i]);
							GX_Color1x16(indices[i]);
							GX_TexCoord1x16(indices[i]);
						}
					}
				}
				break;

				default:
					break;
			}
			GX_End();
		}

Sheeft
Posts: 5
Joined: Fri Aug 27, 2010 11:56 pm

Re: Problem with light in GX

Post by Sheeft » Wed Sep 01, 2010 9:55 pm

Ok thanks !

But, I have a problem actually, it works now, but when I use my vertex desc with colors, it just display grey…
What's the problem ?

shagkur
Posts: 53
Joined: Thu Sep 08, 2005 8:40 pm

Re: Problem with light in GX

Post by shagkur » Thu Sep 02, 2010 9:42 am

use

Code: Select all

GX_SetChanCtrl(GX_COLOR0,GX_ENABLE,GX_SRC_REG,GX_SRC_VTX,GX_LIGHT0,GX_DF_CLAMP,GX_AF_NONE);
instead of

Code: Select all

GX_SetChanCtrl(GX_COLOR0,GX_ENABLE,GX_SRC_REG,GX_SRC_REG,GX_LIGHT0,GX_DF_CLAMP,GX_AF_NONE);
For brief description of GX functions and it's parameters to pass look at http://libogc.devkitpro.org/

regards
shagkur

Sheeft
Posts: 5
Joined: Fri Aug 27, 2010 11:56 pm

Re: Problem with light in GX

Post by Sheeft » Thu Sep 02, 2010 1:58 pm

Oh yes great ! It works now.

Thanks a lot ! Sorry for all these questions.

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests