Warning: Can't synchronize with the repository (Couldn't open Subversion repository /home/crystal/scm/crystal: SubversionException: ("Expected FS format between '1' and '3'; found format '4'", 160043)). Look in the Trac log for more information.

Ticket #698 (closed defect: wontfix)

Opened 8 years ago

Last modified 3 years ago

Problem with rendering text to a procedual texture

Reported by: eventhorizon5 Owned by: thebolt
Priority: major Milestone:
Component: renderer Version: V1.4
Keywords: Cc:

Description (last modified by sunshine) (diff)

There's a bug involving drawing text to a procedural texture and has to do with the code giving the text a negative vertical position, due to it getting the smaller viewport (texture) size instead of the canvas size, and subtracting the given Y value from that (which includes the clipping offset).

Here's some basic code I'm using to render to a texture:

int vleft, vtop, vwidth, vheight;
g2d->GetViewport(vleft, vtop, vwidth, vheight);
g2d->Write(font, vleft, vtop, g2d->FindRGB(255, 255, 255), -1, text);

GetViewport() needs to be used to get the clipping offset used for the texture; otherwise the Write() call fails due to the position being outside the clipping region. For a texture that has a 128x128 size, and if vtop is let's say 320, the Write() function will try to use a Y offset of 128 minus about 320.

The issue generally involves both lines 654 and 655 of libs/csplugincommon/opengl/glfontcache.cpp - I made a patch that fixes line 655, but I'm unsure if it's the proper way to do it (seems to work fine though).

Ryan Thoryk

Attachments

cs_texturefont_fix.patch Download (0.6 KB) - added by eventhorizon5 8 years ago.
skyscraper-text.jpg Download (98.1 KB) - added by eventhorizon5 8 years ago.
Picture showing a line and text rendered onto a tiled procedural texture, using my patch
cs_texturefont_fix2.patch Download (0.6 KB) - added by eventhorizon5 8 years ago.
This might be better - this doesn't require getting the render view size beforehand, and simply fixes the check so that it only runs if the vertical framebuffer and viewport sizes are the same (is this fine?)
flarge.jpg Download (55.6 KB) - added by eventhorizon5 8 years ago.
Example of simplept using the flarge map on a "bad" system - Thinkpad T43 laptop, Radeon X300, XP (works fine in Linux on the same machine)
corruption_issue.jpg Download (42.8 KB) - added by eventhorizon5 8 years ago.
Example of texture rendering problems caused by trunk rev 28504
proctex2.jpg Download (21.7 KB) - added by eventhorizon5 8 years ago.
Example of problems using Video.OpenGL.FontCache.UseAFP=true
cs_afp_text_fix.patch Download (0.7 KB) - added by eventhorizon5 8 years ago.
AFP text fix - simply reverses the color definitions

Change History

Changed 8 years ago by eventhorizon5

  Changed 8 years ago by sunshine

  • description modified (diff)

Changed 8 years ago by eventhorizon5

Picture showing a line and text rendered onto a tiled procedural texture, using my patch

Changed 8 years ago by eventhorizon5

This might be better - this doesn't require getting the render view size beforehand, and simply fixes the check so that it only runs if the vertical framebuffer and viewport sizes are the same (is this fine?)

  Changed 8 years ago by eventhorizon5

Something else is happening with this issue. Certain machines seem to be unable to properly render pixmaps and text onto textures even with the patch (only happens when using SetRenderTarget), and simplept shows up with a black texture (unless the "flarge" map is used, which then you see a few of the 3D objects, but no textured walls, etc). This all works fine in CS 1.2.1, but not 1.4. I traced through the related code, and can't yet figure out what's going on.

Changed 8 years ago by eventhorizon5

Example of simplept using the flarge map on a "bad" system - Thinkpad T43 laptop, Radeon X300, XP (works fine in Linux on the same machine)

  Changed 8 years ago by eventhorizon5

I've just pinpointed the change that caused the issue. It's SVN rev #29602 which inverted the 3D depth range (figured it out by building a bunch of different versions of CS until I got it pinpointed).

Ryan Thoryk

  Changed 8 years ago by eventhorizon5

And finally, I just found the change that is causing the final issue with text rendering. Trunk rev 28504 causes text rendering to textures to corrupt both the text and graphics on certain machines. I'm attaching a picture showing the before and after effects of that change on an affected machine.

Changed 8 years ago by eventhorizon5

Example of texture rendering problems caused by trunk rev 28504

in reply to: ↑ description ; follow-up: ↓ 6   Changed 8 years ago by eventhorizon5

Finally found the change in rev 28504 that caused the problems. In plugins/video/render3d/opengl/gl_r2t_framebuf.cpp, at the end of the GrabFramebuffer() function there's a mipmap regeneration line - "tex_mm->RegenerateMipmaps();". Commenting out that line fixes the issue. I'll be making a patch to fix the depth reversal and mipmap problem for the CS bundled with my simulator.

in reply to: ↑ 5   Changed 8 years ago by eventhorizon5

Obviously removing the mipmap regeneration line caused problems, but at least I know where the problem is happening.

follow-up: ↓ 8   Changed 8 years ago by eventhorizon5

It looks like the culprit is the glGenerateMipmapEXT call in csGLBasicTextureHandle::RegenerateMipmaps(), and has to do with the graphics driver drawing all of the mip levels together onto the texture, creating corruption. Since the code before rev 28504 used that function, I don't really know why that change would've broken it (I tried reverting as much of it as I could, and didn't get very far). I also tried moving csGLTextureHandle::CreateMipMaps() and a related function into the csGLBasicTextureHandle namespace (including iImage-related stuff), but that wasn't working either. Here's some stuff I found about issues with glGenerateMipmapEXT mainly on ATI hardware:

 http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=251072&page=1

 http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=237052

this one's the exact issue that CS is having:  http://www.gamedev.net/community/forums/topic.asp?topic_id=533365

this has a nice alternative method - I don't know if I could get that working, since I'm not very good at OpenGL:  http://forum.beyond3d.com/showthread.php?t=25031

So does anyone have any ideas on how to fix this issue? I'm really almost at the point of giving up (and almost wish I was using CS 1.2.1 instead of 1.4, since it works fine, but can't exactly due to technical issues). The only way for it to semi-work is to set the no_mipmaps flag on the related texture, but obviously the texture doesn't look very good at a distance due to the lack of mipmaps.

in reply to: ↑ 7 ; follow-up: ↓ 9   Changed 8 years ago by res

Replying to eventhorizon5:

this has a nice alternative method - I don't know if I could get that working, since I'm not very good at OpenGL:  http://forum.beyond3d.com/showthread.php?t=25031

I don't see how this related to the problem here at all.

So does anyone have any ideas on how to fix this issue? I'm really almost at the point of giving up (and almost wish I was using CS 1.2.1 instead of 1.4, since it works fine, but can't exactly due to technical issues). The only way for it to semi-work is to set the no_mipmaps flag on the related texture, but obviously the texture doesn't look very good at a distance due to the lack of mipmaps.

If root of the problem is really faulty drivers the way to go is to create a gldrivers.xml entry that tweaks the configuration to enable a workaround (in this case the Video.OpenGL.DisableGenerateMipmap option).

in reply to: ↑ 8 ; follow-up: ↓ 10   Changed 8 years ago by eventhorizon5

Replying to res:

I don't see how this related to the problem here at all.

It's indirectly related, and the thing I was pointing out is a little over half-way down the page. It just shows a recommendation for using glTexImage2D for each mip instead of glGenerateMipmapEXT, due to the reported bug in some graphics drivers (it was just something I found online when trying to see if other projects had similar issues). This whole situation started when I added a new and greatly anticipated feature to my simulator (which basically involved generating text and rendering it to textures, instead of using over 1500 pre-generated texture files); and after releasing a testing version, about half of the users reported an issue with the text rendering; so I had to temporarily revert back to the old method, and have been trying everything to get the issue fixed.

If root of the problem is really faulty drivers the way to go is to create a gldrivers.xml entry that tweaks the configuration to enable a workaround (in this case the Video.OpenGL.DisableGenerateMipmap option).

I'll look into that, but I don't want to disable mipmaps for the textures I'm generating, since the main use is for generating elevator buttons, and they can easily become unreadable without proper mipmapping. What I've been doing is since it seems like most of the CS texture processing uses csGLTextureHandle::CreateMipMaps() instead of the glGenerateMipmapEXT call within csGLBasicTextureHandle::RegenerateMipmaps() (which explains why mipmaps for everything else work fine on this machine), I've been moving CreateMipMaps (and a couple related items) into the csGLBasicTextureHandle class in order for the csGLRender2TextureFramebuf::GrabFramebuffer()'s tex_mm object to be able to use CreateMipMaps instead (I tried changing the object type of tex_mm and fixing it up, but that caused some deallocation issues and other things). So far the code's in place, but has a handle leak, and doesn't work yet (I still need to look over the code closely to understand the process of what it's doing, in order to get it working properly, especially since I'm still fairly new to GL mipmapping). I can post an in-progress patch if you'd like to look it over.

in reply to: ↑ 9 ; follow-up: ↓ 11   Changed 8 years ago by res

Replying to eventhorizon5:

Replying to res:

I don't see how this related to the problem here at all.

It's indirectly related, and the thing I was pointing out is a little over half-way down the page. It just shows a recommendation for using glTexImage2D for each mip instead of glGenerateMipmapEXT,

As far as I understood it it says that each mip level has to be specified manually first before glGenerateMipmapEXT would generate these. This is already the case in CS, though.

If root of the problem is really faulty drivers the way to go is to create a gldrivers.xml entry that tweaks the configuration to enable a workaround (in this case the Video.OpenGL.DisableGenerateMipmap option).

I'll look into that, but I don't want to disable mipmaps for the textures I'm generating,

Video.OpenGL.DisableGenerateMipmap does not disable automatic mipmap generation at all, only the use of glGenerateMipmapEXT. There's an alternative way to have mipmaps generated automatically available on most hardware (the GL_SGIS_generate_mipmap extension) which is used, if available. Mipmaps are only disabled if no way to automatically generate mipmaps is available.

What I've been doing is since it seems like most of the CS texture processing uses csGLTextureHandle::CreateMipMaps()

CreateMipMaps() is software-based. So to generate mipmaps you would have to download the texture data from the GPU, generate mipmaps on the CPU and upload the mips to the GPU again. This is slow and inefficient compared to the automatic mipmap generation which is happening entirely on the GPU.

in reply to: ↑ 10   Changed 8 years ago by eventhorizon5

Replying to res:

Video.OpenGL.DisableGenerateMipmap does not disable automatic mipmap generation at all, only the use of glGenerateMipmapEXT. There's an alternative way to have mipmaps generated automatically available on most hardware (the GL_SGIS_generate_mipmap extension) which is used, if available. Mipmaps are only disabled if no way to automatically generate mipmaps is available.

I just tried using that (reverted my other changes) and it doesn't seem to do anything. It does skip the glGenerateMipmapEXT, but the same corruption is still visible. I looked through the r3dopengl.cfg file (should've done that before) and played around with some of the options - the one that is somewhat working is Video.OpenGL.FontCache.UseAFP, which is the recommended one for multitexture text-rendering problems. The corruption is gone, but the text layer's colors are inverted on all machines (I'm posting a pic showing that - the text should be white). I'll trace through the code and try to see why that's happening. Also, just so you know, I haven't been able to find any workarounds for the rev #29602 issue (GL depth range change), and both graphics and text will only render to textures if the change is reverted (possibly due to coordinate inversion, but I wasn't able to find anything like that before).

CreateMipMaps() is software-based. So to generate mipmaps you would have to download the texture data from the GPU, generate mipmaps on the CPU and upload the mips to the GPU again. This is slow and inefficient compared to the automatic mipmap generation which is happening entirely on the GPU.

Yeah I know - but from my perspective it was either that or possibly not having it work at all.

Changed 8 years ago by eventhorizon5

Example of problems using Video.OpenGL.FontCache.UseAFP=true

Changed 8 years ago by eventhorizon5

AFP text fix - simply reverses the color definitions

  Changed 5 years ago by Fedwqbfo

We invite you to an unforgettable holiday in the Canary ostrovah.S more information here can follow any responses poznokomitsya  http://www.tenerife-excursions.ru/

  Changed 3 years ago by philwyett

  • status changed from new to closed
  • resolution set to wontfix
Note: See TracTickets for help on using tickets.