| Summary: | Render target implementation for GL renderer, plus basic API | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Mason Wheeler <masonwheeler> |
| Component: | video | Assignee: | Gabriel Jacobo <gabomdq> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | API change | ||
| Priority: | P2 | CC: | gabomdq, icculus |
| Version: | 2.0.0 | ||
| Hardware: | Other | ||
| OS: | All | ||
| Attachments: |
patch to implement the render targets
reworked patch for render targets Implements render targets for Open GL and GL ES Render to texture target support for OpenGL, OpenGL ES and Direct3D Render to texture target support for OpenGL, OpenGL ES 1.1 and 2.0, Direct3D Render to texture target support for OpenGL, OpenGL ES 1.1 and 2.0, Direct3D Render to texture target support for OpenGL, OpenGL ES 1.1 and 2.0, Direct3D Modified testscale.c to test render targets Fix SetRenderTarget for OpenGL ES 1.1 and 2 |
||
|
Description
Mason Wheeler
2010-04-15 20:51:07 UTC
Ken is working on this. Ken doesn't have time to work on this, so I'll take a crack at it. Created attachment 661 [details]
reworked patch for render targets
I've reworked this patch and now it applies cleanly on the hg trunk.
Adjusting it to the new code layout wasn't so much work, but still I spent a whole day trying to figure out why instead of a rendered texture I was getting a gray rectangle...it turns out that with my Nvidia card under Ubuntu Natty with propietary Nvidia drivers, if the target texture is created with TEXTURE_2D, this patch doesn't work! And I still can't figure out why...
To verify if it fails for others, apply the patch, then go to SDL_render_gl line 566 and uncomment the condition texture->access != SDL_TEXTUREACCESS_TARGET
The patch adds 3 functions:
SDL_bool SDL_RenderTargetSupported(SDL_Renderer *renderer);
int SDL_SetTargetTexture(SDL_Texture *texture);
SDL_ResetTargetTexture(SDL_Renderer *renderer);
In SetTargetTexture the texture is assigned to its renderer.
If there's interest in this I can probably extend this implementation to the OPENGL ES backend at least, or add a workaround for a non FBO dependent solution (slower as it may be).
I'll try to find some time to see about the non-GL paths. I can't put this revision control with just OpenGL support. --ryan. Created attachment 688 [details] Implements render targets for Open GL and GL ES Attaching new version of the patch with OpenGL ES support. Requires the fix for bug #1290 Created attachment 698 [details]
Render to texture target support for OpenGL, OpenGL ES and Direct3D
Uploading a new patch that adds the feature to the Direct3D backend. Is this enough for acceptance? I'll probably add OpenGL ES 2 in a couple of days as well.
Created attachment 704 [details]
Render to texture target support for OpenGL, OpenGL ES 1.1 and 2.0, Direct3D
Updated patch to support OpenGL ES 2.0
One note: Do we need SDL_ResetTargetTexture()? Is there a reason that calling SDL_SetTargetTexture(NULL) wouldn't be better? Rest of the patch looks good to me. --ryan. (In reply to comment #8) > One note: Do we need SDL_ResetTargetTexture()? Is there a reason that calling > SDL_SetTargetTexture(NULL) wouldn't be better? > > Rest of the patch looks good to me. > > --ryan. You're right, it's probably not necessary. There's a chance that the patch won't apply cleanly given recent changes done by Sam in the GL backends. I did keep my experimental repo (https://bitbucket.org/gabomdq/sdl-1.3-experimental) updated with these changes merged in, so I can (if merging the patch as is proves too complicated) make a new patch, the problem is I think I'd have to extract manually from it the rotation functions I've added in the RenderCopyEx branch as well (unless you want to incorporate that as well...hey, don't blame me for trying!) I agree that the ResetTarget is redundant. Actually, as written, SDL_ResetTargetTexture is necessary. Calling SDL_SetTargetTexture(NULL) wouldn't work, because there is no way to determine the renderer. The call would fail inside the CHECK_TEXTURE_MAGIC macro. Sam/Ryan, if you want me to rework the patch to go from: SDL_bool SDL_RenderTargetSupported(SDL_Renderer *renderer); int SDL_SetTargetTexture(SDL_Texture *texture); SDL_ResetTargetTexture(SDL_Renderer *renderer); to: SDL_bool SDL_RenderTargetSupported(SDL_Renderer *renderer); int SDL_SetTargetTexture(SDL_Texture *texture, SDL_Renderer *renderer); Where you can do SDL_SetTargetTexture(NULL, renderer) to go back to the default target, let me know and I'll handle it. Sure, if you can update it for the current hg and change the API, that would be great! The API should probably be (note the renderer is always the first parameter): SDL_bool SDL_RenderTargetSupported(SDL_Renderer *renderer); int SDL_SetTargetTexture(SDL_Renderer *renderer, SDL_Texture *texture); We should add something to SDL_RendererInfo which indicates whether render targets are supported and just return that from SDL_RenderTargetSupported() Also, the render viewport should be taken into account when resetting the viewport. Right now it looks like it's just clobbering it with the window size. Can someone make a simple program in the test directory that shows this functionality? Thanks! Created attachment 782 [details]
Render to texture target support for OpenGL, OpenGL ES 1.1 and 2.0, Direct3D
Patch updated to the apply cleanly on the current tip. I changed the API per Sam's suggestion and I had to add some cumbersome texture format mapping logic in RenderCopy of GLES2 because of the recent changes made to support additional texture formats (I suspect there's a cleaner solution somewhere out there). Also, I had to manually remove parts that are RenderCopyEx centric (rotation/flipping), so some (minor) measure of caution and testing is needed!
Created attachment 783 [details]
Render to texture target support for OpenGL, OpenGL ES 1.1 and 2.0, Direct3D
Updated patch to preserve the renderer viewport instead of clobbering it with the window size.
Created attachment 784 [details]
Modified testscale.c to test render targets
Attaching a simple test case, this is a slightly modified version of testscale.c
Okay, the first pass is in! http://hg.libsdl.org/SDL/rev/37e8d0736366 It still needs a bit in SDL_RenderInfo and a software implementation, but it looks great! Thanks guys! :) By the bit in RenderInfo, do you mean adding an entry in http://wiki.libsdl.org/moin.cgi/SDL_RendererFlags and setting that accordingly in SDL_RenderInfo? Yep, I added it: http://hg.libsdl.org/SDL/rev/240f1bced46b We also need at least a short paragraph documenting the two new functions, I can write it, should I send it to you Sam? I noticed the wiki mentions a documentation mailing list but I don't know if that's still functional. The documentation mailing list is functional, but more for discussion between contributors. If you'd like to write the wiki pages yourself, you're more than welcome to and I can add you as a contributor once you have a wiki login. Done, it's GabrielJacobo Okay, you have access! Please review the style guides and try to maintain the same form as the other pages. Let me know if you have any questions! http://wiki.libsdl.org/moin.cgi/Contributing I added a software implementation and refactored the code a bit, but I think I broke OpenGL ES 1 and 2. Can you take a quick look and see what I did? Thanks! I tried to do that Neo thing where I figured the problem by just looking at the diffs but it only works in the movies. I'll merge it with my SDL copy tonight and let you know what I get. *laugh* Thanks! Created attachment 797 [details]
Fix SetRenderTarget for OpenGL ES 1.1 and 2
This fixes OpenGL ES 1.1 and 2 under Android, I'd like to verify OpenGL but currently compilation in Linux seems to be broken, looking into that...
Comment on attachment 797 [details]
Fix SetRenderTarget for OpenGL ES 1.1 and 2
Gabriel and I went over this and it's a red herring. The existing OpenGL ES code works for him.
I just re tested everything, with SetRenderTarget setting the viewport BEFORE calling the internal implementation, that is with this patch applied:
diff -r e0521de318b2 -r 292a0bce2ae3 src/render/SDL_render.c
--- a/src/render/SDL_render.c dom ene 22 19:47:17 2012 -0300
+++ b/src/render/SDL_render.c dom ene 22 21:36:27 2012 -0300
@@ -847,9 +847,7 @@
}
renderer->target = texture;
- if (renderer->SetRenderTarget(renderer, texture) < 0) {
- return -1;
- }
+
if (texture) {
viewport.x = 0;
@@ -863,6 +861,10 @@
return -1;
}
+ if (renderer->SetRenderTarget(renderer, texture) < 0) {
+ return -1;
+ }
+
/* All set! */
return 0;
}
I got OpenGL under Linux, GLES1 and 2 under Android and D3D under Win7 working as expected. It seems the problem remains under iOS GLES1 and 2?
The documentation is available at http://wiki.libsdl.org/moin.cgi/SDL_SetRenderTarget (I couldn't figure out how to add it to the index of API by name/category...does that index need to be re generated somehow?) Hey Gabriel, can you back out your change switching the order of setting the viewport and see if this change works instead? http://hg.libsdl.org/SDL/rev/3aa24ec6bc39 Thanks for updating the documentation, it looks good! I updated the API and Render pages by using the Page Actions -> More Actions -> Delete Cache menu option on each of those pages. Sam, your change works fine here in GLES2/Android. Great, thanks! Did you figure out the magenta issue on the iPhone? Sam, if the magenta issue in iOS devices persists, there's a comment that might be useful in this StackOverflow response... http://stackoverflow.com/questions/1024603/opengl-es-render-to-texture/1024634#1024634 "Binding to Framebuffer Id 0 isn't always the Id of the one intialized as your primary framebuffer of the GL session. My ES2 session definitely stores a different one. I advise people to reference the one given upon the creation of your GL session. – Kyle Jan 26 '11 at 10:02" I can't verify as I don't have a iOS device. Oh hey, you're right! If I switch it to framebuffer 1 instead of 0 it works correctly. Now how to detect this situation... Okay, this is fixed for OpenGL ES 2.0: http://hg.libsdl.org/SDL/rev/d1ba86bc57a5 That fix didn't help with OpenGL ES 1.1, and I'm not sure why. First the good news, your fix works in GLES2 Android...however you broke GLES 1.1... I decided to give up and read the manual: http://www.khronos.org/registry/gles/extensions/OES/OES_framebuffer_object.txt http://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindFramebuffer.xml They keep mentioning that framebuffer 0 is reserved for the system window, so it may be an iPhone GLES2 quirk not using 0 as the default framebuffer. What I did notice is that calling data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &value); doesn't produce any result in Android GLES1.1 if the active framebuffer is the default one, ie, whatever is in value stays unmodified. So perhaps the solution for GLES 1.1 is just default window_framebuffer to zero ? That certainly fixes it in Android, but I'm afraid you'll be back at square one in iOS. Fixed, thanks! http://hg.libsdl.org/SDL/rev/246cde9a6cf3 |