+ Reply to Thread
Results 1 to 25 of 25

Thread: I think my jpg code is flawed. is it?

  1. #1
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Question I think my jpg code is flawed. is it?

    I use freeimage to load jpgs, then copy the data to a direct draw surface (dx7). This works fine for 95% of my users, but for 5%, they get white textures. No error messages, just white textures. is this code ok to you?:

    Code:
    	DebugOut("Creating JPG file");
    	FIBITMAP* fimage = FreeImage_Load(FIF_JPEG,szImage,JPEG_DEFAULT);
    	if(!fimage)
    	{
    		DebugOut("failed loading jpg");
    		return;
    	}
    
    	DWORD bpp;
    	if(BFallBack)
    	{
    		bpp = (DWORD)AppliedColorDepth;
    	}
    	else
    	{
    		D3DX->GetNumBits(&bpp,NULL,NULL,NULL);
    	}
    
    	if(bpp == 16)
    	{
    		fimage = FreeImage_ConvertTo16Bits565(fimage);
    		DebugOut("Converting JPG to 16 bits");
    	}
    
    	//create the surface
    	DDSCAPS2				ddsCaps;	
    	DDSURFACEDESC2			ddsd;	
    
    	ZeroMemory(&ddsd,sizeof(ddsd));
    	ddsd.dwSize=sizeof(ddsd);
    	ZeroMemory(&ddsCaps,sizeof(ddsCaps));
    
    	ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
    	ddsd.dwHeight = FreeImage_GetHeight(fimage); 
    	ddsd.dwWidth = FreeImage_GetWidth(fimage);
    	ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; 
    
    
    	// Create Surface
    	HRESULT hr = GetD3DEngine()->GetDDObject()->CreateSurface( &ddsd, lplpDDS, NULL ); 
    	if( hr == DD_OK)
    	{
    		DebugOut("Created jpg surface");
    	}
    	else
    	{
    		char debug[256];
    		sprintf_s(debug,256,"Failed to create jpg surface");
    		DebugOut(debug);
    		D3DEngineError(hr,debug);
    		return;
    	}
    
    	//copy data to it
        LPDIRECTDRAWSURFACE7 psurf = *lplpDDS;
    	DDSURFACEDESC2 ds;
    	ds.dwSize = sizeof(ds);//initialize it
    	hr = psurf->Lock(NULL,&ds,DDLOCK_WAIT,NULL);
    	if(FAILED(hr))
    	{
    		return;
    	}
    
    	BYTE* pdest = (BYTE*)ds.lpSurface;
    	for(int y = 0; y < ds.dwHeight; y++)
    	{
    		BYTE* srcbits = FreeImage_GetScanLine(fimage,ds.dwHeight - y - 1);
    		DWORD pitch = (ds.lPitch * y);
    		for(int x = 0; x < ds.dwWidth; x++)
    		{
    			if(bpp == 32)
    			{
    				//get data at screen pos xy
    				DWORD offset = pitch + (x * 4);
    				BYTE* pbyte = &pdest[offset];
    				*pbyte = srcbits[x * 3];pbyte++;
    				*pbyte = srcbits[(x * 3) + 1];pbyte++;
    				*pbyte = srcbits[(x * 3) + 2];pbyte++;
    				*pbyte = 0;				
    			}
    			if(bpp == 16)
    			{
    				//get data at screen pos xy
    				DWORD offset = pitch + (x * 2);
    				BYTE* pbyte = &pdest[offset];
    				*pbyte = srcbits[x * 2];
    				pbyte++;
    				*pbyte = srcbits[(x * 2) + 1];
    			}
    		}
    	}
    	psurf->Unlock(NULL);
    	FreeImage_Unload(fimage);
    I'm presuming the Lock() prior to copying the data is failing (silly me didn't put error check code there), but why would this happen?
    Cheers.

  2. #2
    Moderator
    Join Date
    Nov 2004
    Location
    France
    Posts
    864

    Default

    I don't see anything seriously wrong with the jpeg code, but do you create your target surfaces systematically in 32bpp or 565 format for instance? Some cards don't support 32bpp textures (like the i810/i815), some don't support RGB565. The i810 interestingly doesn't fail when creating a texture it doesn't support, it just refuses to render it and returns an error in DrawPrimitive, DrawPrimitiveVB or whatever.

    Best regards,
    Emmanuel
    Emmanuel Marty
    Programmer/designer, Azada: Ancient Magic, Azada, Atlantis Sky Patrol, Mystic Inn, Fairies and Atlantis. iPhone: Atlantis Sky Patrol, Azada
    Creator, Kanji game engine, powering Serpent of Isis 2, Dark parables, Relics of fate and many topselling games

  3. #3
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default

    well if the player has an intel card, it will be in 16 bit mode and create a 16 bit surface, but you are suggesting that even then, the 565 mode isn't supported?
    i thought it was just intel cards but 1 user had white jpg textures on a NVIDIA RIVA TNT2 Model 64.
    in fact, anyone here have that card?

  4. #4
    Member
    Join Date
    Jul 2004
    Location
    Sweden
    Posts
    65

    Default

    You can use GetPixelFormat to get the correct pixelformat after you created the surface. Something like:

    DDPIXELFORMAT ddpf;
    DDRAW_INIT_STRUCT(ddpf);
    surface->GetPixelFormat(&ddpf);

    Then you've got
    red = ddpf.dwRBitMask
    green = ddpf.dwGBitMask
    blue = ddpf.dwBBitMask

    And I think this is the numbers to look for:

    R is 63488 = 5 bits
    G is 2016 = 6 bits
    B is 31 = 5 bits

    R is 31744 = 5 bits
    G is 992 = 5 bits
    B is 31 = 5 bits

    edit: But usually when you have this problem you get the wrong colors, not a white texture.
    Mikael Linusson
    Nordic Software for Entertainment
    http://www.nordicsoftware.se

  5. #5
    Moderator
    Join Date
    Nov 2004
    Location
    France
    Posts
    864

    Default

    I did encounter cards that do not support 565 mode at all (only 555) but I think intel 810's do support it.

    If it happens on TNT2's, it might be because those cards don't support non-rectangular or non-pow2 textures (intel's don't, either).. ie. all textures must be 128x128, 256x256, 512x512 and whatnot. A 512x256 texture will show all white. I used to have that exact problem on a RIVA TNT2 64 when I started using ptk. Hopefully that's what your issue is!

    Best regards,
    Emmanuel
    Emmanuel Marty
    Programmer/designer, Azada: Ancient Magic, Azada, Atlantis Sky Patrol, Mystic Inn, Fairies and Atlantis. iPhone: Atlantis Sky Patrol, Azada
    Creator, Kanji game engine, powering Serpent of Isis 2, Dark parables, Relics of fate and many topselling games

  6. #6
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default

    aha that could be it, as I'm loading in 1024 by 768 textures now I think about it. I thought they got upscaled to 1024 by 1024s. hmmmmm
    in theory if I shipped 1024 by 1024 stretched ones, it should load?
    pesky old cards...

    edit : i bet they don't support textures that big either. anyone know a good online caps database for older cards?

  7. #7
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default

    it looks like it is a power of 2 problem. what are other people doing when you want to display a full screen image? padding it to 1024? tiling it?

  8. #8
    Senior Member
    Join Date
    Aug 2004
    Posts
    947

    Default

    Padding to 1024x1024 and adjusting the UV coordinates accordingly. I often try and fill in the space with smaller things I'll be drawing at the same time to save wasting VRam.

  9. #9
    Administrator
    Join Date
    Jul 2004
    Posts
    3,401

    Default

    You've been asking a few engine questions and DX questions lately. It confuses me. I mean there's PTK, the Popcap engine, Playfirst has a thing out, garagegames has some engines etc.. In the state of the industry thread you were quick to point out how wonderful it is that we have all these great tools at our disposable and how much easier it is to make a game nowdays. Why are mucking around in the code at such a low level still? I haven't written or looked at a directx function in close to 6 years.
    Steve Verreault - Twilight Games
    http://www.twilightgames.com --- http://www.indiegamer.com

    "Do you really think it is weakness that yields to temptation? I tell you that there are terrible temptations which it requires strength, strength and courage to yield to.” - Oscar Wilde

  10. #10
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default

    well I do some stuff that might be a bit tricky using one of those engines, I use lots of vertex buffers and tons of text, way mroe than 99% of casual games. I know lots of people use PTK, and popcaps engine, but most people are doing casual games, and mine are a bit different in terms of what they need. Plus, you stick with what you know, and I'm not keen to relearn a whole API to use someone else's engine. The one thing d3DX has taught me is that if there is a bug in your code, you can fix it. If there is a bug in 3rd party code, you are generally screwed.
    I do use 3rd party code to load textures and do my sounds though.

    Its my own fault, I shouldn't have assumed non pow2 textures were ok these days.

  11. #11
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default

    Does this mean that using texture sizes say, 256*128, or 128*64 is a bad idea??

    I should only use textures that are power of 2, AND square? (non square textures showing white on some cards)?

  12. #12
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default

    from what I can see, the number of cards objecting to nonpower2 are much higher than those fussed about them being square. There is a spreadsheet of card caps in the dx9 sdk

  13. #13
    Senior Member
    Join Date
    Oct 2005
    Location
    Montreal, Quebec
    Posts
    797

    Default

    Quote Originally Posted by cliffski View Post
    Its my own fault, I shouldn't have assumed non pow2 textures were ok these days.
    They are, but the TNT2 is really really old.
    "Don't lose your loose change."
    Jason Maskell, Tamed Tornado Software

  14. #14
    Senior Member
    Join Date
    Feb 2005
    Posts
    2,050

    Default

    Yeah non power of 2 are not okay. Even if modern cards will let you load them you don't really know how they will mangle them afterward, because the cards internally work with power of two, so you risk incompatibility with older cards and I don't know what effect on performance with modern cards.
    I try to create my pics in P.O.2 from the start, if not possible I rescale them, apply them to a polygon and rescale the polygon to have the original ratio. If the picture is really special, I'll use more than one polygon.

    As for non-square texture you should be okay with most cards, as already said riva tnt2 is very old, I wouldn't consider offering support for this hardware, this person is probably running windows 95 too.

  15. #15
    Administrator
    Join Date
    Jul 2004
    Posts
    3,401

    Default

    Quote Originally Posted by cliffski View Post
    Plus, you stick with what you know, and I'm not keen to relearn a whole API to use someone else's engine. The one thing d3DX has taught me is that if there is a bug in your code, you can fix it. If there is a bug in 3rd party code, you are generally screwed.
    Well I can understand sticking with what you know. With regards to bugs I havent worried too much about using popcap engine because all the source code is provided.
    Steve Verreault - Twilight Games
    http://www.twilightgames.com --- http://www.indiegamer.com

    "Do you really think it is weakness that yields to temptation? I tell you that there are terrible temptations which it requires strength, strength and courage to yield to.” - Oscar Wilde

  16. #16
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default

    If I was starting out now, I'd code in java probably, and probably use a 3rd party engine, but of course, i have all the baggage that comes from having built up a codebase without a plan. I use my engine because its the one I know. i also quite like engine optimising.

  17. #17
    Senior Member
    Join Date
    Aug 2004
    Posts
    947

    Default

    Quote Originally Posted by electronicStar View Post
    Yeah non power of 2 are not okay. Even if modern cards will let you load them you don't really know how they will mangle them afterward, because the cards internally work with power of two, so you risk incompatibility with older cards and I don't know what effect on performance with modern cards.
    I try to create my pics in P.O.2 from the start, if not possible I rescale them, apply them to a polygon and rescale the polygon to have the original ratio. If the picture is really special, I'll use more than one polygon.

    As for non-square texture you should be okay with most cards, as already said riva tnt2 is very old, I wouldn't consider offering support for this hardware, this person is probably running windows 95 too.
    I wholeheartedly second this. Non Power of 2 are not okay. Non-Square, on the other hand, is such a rare issue that I wouldn't lift a finger to do anything about it, particularly when it can really make life quite difficult.

    I would say just add that I stay within 1:8 or 8:1 width/height ratios. That is, I never use a texture which is more than 8 times as wide as it is high, or vice versa.

  18. #18
    Senior Member
    Join Date
    Feb 2007
    Location
    USA/Mexico
    Posts
    309

    Default

    Quote Originally Posted by Sybixsus View Post
    I wholeheartedly second this. Non Power of 2 are not okay. Non-Square, on the other hand, is such a rare issue that I wouldn't lift a finger to do anything about it, particularly when it can really make life quite difficult.

    I would say just add that I stay within 1:8 or 8:1 width/height ratios. That is, I never use a texture which is more than 8 times as wide as it is high, or vice versa.
    Is the 1:8 an arbitrary ratio that you just prefer, or is there some reasoning behind this? I have never had issues with textures as wide and short as 1024 x 8, but that portion of code was never widely tested. I am curious to know...

  19. #19
    Senior Member
    Join Date
    Jul 2004
    Location
    Isle of Wight, UK
    Posts
    3,773

    Default

    Here's the current state of play aiui.

    Non-power 2 is never supported optimally by anything. What happens when you load an awkward size is that the driver makes a linear format unswizzled texture internally. This works, but is way from optimal as linear formats kill your texture cache. (Which is what the hardware swizzling is designed to reduce).

    So on modern cards, non-pow-2 will work, just won't be ideal.

    On older cards, they just don't have the option to support non-pow-2 as they rely on bit masking for the texture strides and store all their data linearly so said masking can actually work.

    Square has not been a requirement since the very early days - voodoo 2 maybe was the last, certainly something of that distant vintage. Just don't worry about it - a computer that old won't run your game anyway as it's probably is a Pentium 1 with DX5 installed at best.
    Regards,
    Paul Johnson

    [Great BIG War Game: iOS | Android] [Great Little War Game: iOS | Android] [Fruit Blitz: iOS | Android] [Yachty Deluxe: iOS | Android]

  20. #20
    Senior Member
    Join Date
    Feb 2005
    Posts
    2,050

    Default

    Another precaution that I use:
    I try not to use textures larger than 512 at maximum, I know there have been problem with not so recent cards that couldn't load textures of 1024X1024 for example.
    If required I use several textures.
    Hopefully I will abandon this limitation in a few years...

  21. #21
    Senior Member
    Join Date
    Aug 2004
    Posts
    947

    Default

    Quote Originally Posted by MFS View Post
    Is the 1:8 an arbitrary ratio that you just prefer, or is there some reasoning behind this? I have never had issues with textures as wide and short as 1024 x 8, but that portion of code was never widely tested. I am curious to know...
    It's advice I was given which came from one of the guys at FutureMark ( I figured they would know a lot about variations with videocards! ) Since I was pretty inexperienced at the time, I decided to go with it, and it's done well by me. I've never really felt that I was very restricted by the 8:1 ratio so I was never tempted to ignore the advice. Which means I don't have any examples of videocards that didn't like it. Sorry I can't be of more help.

  22. #22
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default

    as I recall from the dx caps database, even the card that cant do my game (tnt2) can handle 1024 by 1024. Of course, its fill rate might not be that stellar, but it can handle it.
    In future games, I'm going all pow2, and my 1024 768 textures are just being stretched to square, then in game code stretched back. They look fine.

  23. #23
    Senior Member
    Join Date
    Jun 2007
    Location
    Winston-Salem, NC
    Posts
    370

    Default

    Shouldn't this be in the Game Development and Technical forum? How does one move a thread?

  24. #24
    Moderator
    Join Date
    Nov 2004
    Posts
    2,882

    Default

    I'd still stick with 256x256 square textures for anything trying to support older cards. No matter what, you should be safe with those.

    These days we're going up to something pretty big (8096 square I believe on my current card).

    Anyway, point being, cant go wrong with power 2 < 256 square.
    www.mindflock.com - social AI-based games

  25. #25
    Senior Member
    Join Date
    Jul 2004
    Location
    Isle of Wight, UK
    Posts
    3,773

    Default

    Shouldn't this be in the Game Development and Technical forum? How does one move a thread?
    One doesn't, that's the mod's job if they see fit.
    Regards,
    Paul Johnson

    [Great BIG War Game: iOS | Android] [Great Little War Game: iOS | Android] [Fruit Blitz: iOS | Android] [Yachty Deluxe: iOS | Android]

+ Reply to Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts