Discussion:
SDL2 and Software Rendering
(too old to reply)
Jonathan Dearborn
2013-04-07 23:44:55 UTC
Permalink
Even if SDL_UpdateTexture() says that it is slow, I would try it anyway.
You might get a decent speed boost if you don't have to create texture
memory each frame. If you were using OpenGL, I'd say the same thing about
glTexSubImage2D().

Jonny D
You might be interested in this<http://wiki.libsdl.org/moin.fcg/SDL_CreateSoftwareRenderer?highlight=%28%5CbCategoryRender%5Cb%29%7C%28CategoryEnum%29%7C%28CategoryStruct%29%7C%28SGFunctions%29>
.
I'm working on porting my Wolfenstein 3D source port from SDL1 over to
SDL2. One thing that isn't clear in the migration guide is how to handle
8-bit software rendering with SDL2.
Currently I have a 8-bit off screen surface which the engine renders to.
Previously I would just call SDL_BlitSurface to bring it on screen and
then finally SDL_Flip. Now it seems I have to use
SDL_CreateTextureFromSurface, SDL_RenderCopy, SDL_RenderPresent, and
finally SDL_DestroyTexture. On the surface this seems a lot less
efficient, but it could very well be what SDL1 was doing the whole time any
way since the performance seems to be roughly the same.
Is this the correct way to do things or is there a way I can reuse a
texture between frames? The other solutions I could think of are to either
write my own 8-bit to 32-bit code and use a streaming texture, possibly
avoiding the SDL_Surface altogether. I could also blit to an intermediate
surface to do the conversion and hope that the texture's pitch matches the
surface pitch and memcpy.
- Blzut3
______________________________**_________________
SDL mailing list
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.org<http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org>
_______________________________________________
SDL mailing list
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
David Gow
2013-04-08 02:14:18 UTC
Permalink
Just as an interesting aside, this is both how wine handles 8-bit
rendering in ddraw and how Microsoft's new Age of Empires II HD game
works (though with d3d9). It's a really cool technique, and it allows
you to change palettes easily and do some other cool tricks, too.

-- David
But yeah, you'll need to convert from 8-bit to 32-bit on the fly.
I was in the same boat with Postal 1; it always writes to a 640x480,
8-bit, paletted surface.
I had moved it from SDL 1.2 to SDL 2.0, using an 8-bit shadow surface,
which I would blit to the window surface. Postal uses dirty rects and
such, so it would do this reasonably efficiently, at least on the
application side of things.
This worked, but it used a lot of CPU on the Mac I tried it on. I hadn't
debugged it or even sanity-checked the code to make sure I wasn't doing
something stupid.
- We keep a 640x480 memory buffer. The game renders into this, 8 bits
per pixel, thinking it's the usual SDL 1.2 video surface.
- We also have a 640x480 GL_R8 texture, which we update once a frame
with glTexSubImage2D() from that memory buffer. We don't try to do dirty
rectangles. At the end of the frame, the whole texture is updated,
unconditionally, because it was easier this way.
- We have an 256x1 GL_RGBA texture. It's the palette.
- There's a VBO that has the vertex array we use to draw a single quad
with this texture.
- There's GLSL to make it take the 8-bit texture and the palette
texture, and render the proper colors to the framebuffer.
- For extra credit, we have an FBO that we can then do a GL_LINEAR
stretch-blit to the real window system framebuffer, so the game doesn't
have to be 640x480 anymore. Since the 8-bit values have to line up
exactly for the palette to work, that _has_ to render at 640x480 to get
the right colors, but then you can do a nice linear filter when going to
the screen. Now it looks like it would if you dropped your monitor's
resolution to 640x480 to fill the whole display, but the Steam Overlay
still renders at full resolution.
This took a few hours to implement, got some cool benefits, and this Mac
uses about 4% of the CPU to play the game.
--ryan.
_______________________________________________
SDL mailing list
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Braden Obrzut
2013-04-07 21:23:02 UTC
Permalink
I'm working on porting my Wolfenstein 3D source port from SDL1 over to
SDL2. One thing that isn't clear in the migration guide is how to
handle 8-bit software rendering with SDL2.

Currently I have a 8-bit off screen surface which the engine renders
to. Previously I would just call SDL_BlitSurface to bring it on screen
and then finally SDL_Flip. Now it seems I have to use
SDL_CreateTextureFromSurface, SDL_RenderCopy, SDL_RenderPresent, and
finally SDL_DestroyTexture. On the surface this seems a lot less
efficient, but it could very well be what SDL1 was doing the whole time
any way since the performance seems to be roughly the same.

Is this the correct way to do things or is there a way I can reuse a
texture between frames? The other solutions I could think of are to
either write my own 8-bit to 32-bit code and use a streaming texture,
possibly avoiding the SDL_Surface altogether. I could also blit to an
intermediate surface to do the conversion and hope that the texture's
pitch matches the surface pitch and memcpy.

- Blzut3
Ryan C. Gordon
2013-04-08 00:26:35 UTC
Permalink
But yeah, you'll need to convert from 8-bit to 32-bit on the fly.
I was in the same boat with Postal 1; it always writes to a 640x480,
8-bit, paletted surface.

I had moved it from SDL 1.2 to SDL 2.0, using an 8-bit shadow surface,
which I would blit to the window surface. Postal uses dirty rects and
such, so it would do this reasonably efficiently, at least on the
application side of things.

This worked, but it used a lot of CPU on the Mac I tried it on. I hadn't
debugged it or even sanity-checked the code to make sure I wasn't doing
something stupid.

I decided to move it to OpenGL directly:

- We keep a 640x480 memory buffer. The game renders into this, 8 bits
per pixel, thinking it's the usual SDL 1.2 video surface.
- We also have a 640x480 GL_R8 texture, which we update once a frame
with glTexSubImage2D() from that memory buffer. We don't try to do dirty
rectangles. At the end of the frame, the whole texture is updated,
unconditionally, because it was easier this way.
- We have an 256x1 GL_RGBA texture. It's the palette.
- There's a VBO that has the vertex array we use to draw a single quad
with this texture.
- There's GLSL to make it take the 8-bit texture and the palette
texture, and render the proper colors to the framebuffer.
- For extra credit, we have an FBO that we can then do a GL_LINEAR
stretch-blit to the real window system framebuffer, so the game doesn't
have to be 640x480 anymore. Since the 8-bit values have to line up
exactly for the palette to work, that _has_ to render at 640x480 to get
the right colors, but then you can do a nice linear filter when going to
the screen. Now it looks like it would if you dropped your monitor's
resolution to 640x480 to fill the whole display, but the Steam Overlay
still renders at full resolution.

This took a few hours to implement, got some cool benefits, and this Mac
uses about 4% of the CPU to play the game.

--ryan.
Sam Lantinga
2013-04-17 07:37:30 UTC
Permalink
Hey Ryan, this is a great trick! :)
But yeah, you'll need to convert from 8-bit to 32-bit on the fly.
I was in the same boat with Postal 1; it always writes to a 640x480,
8-bit, paletted surface.
I had moved it from SDL 1.2 to SDL 2.0, using an 8-bit shadow surface,
which I would blit to the window surface. Postal uses dirty rects and such,
so it would do this reasonably efficiently, at least on the application
side of things.
This worked, but it used a lot of CPU on the Mac I tried it on. I hadn't
debugged it or even sanity-checked the code to make sure I wasn't doing
something stupid.
- We keep a 640x480 memory buffer. The game renders into this, 8 bits per
pixel, thinking it's the usual SDL 1.2 video surface.
- We also have a 640x480 GL_R8 texture, which we update once a frame with
glTexSubImage2D() from that memory buffer. We don't try to do dirty
rectangles. At the end of the frame, the whole texture is updated,
unconditionally, because it was easier this way.
- We have an 256x1 GL_RGBA texture. It's the palette.
- There's a VBO that has the vertex array we use to draw a single quad
with this texture.
- There's GLSL to make it take the 8-bit texture and the palette texture,
and render the proper colors to the framebuffer.
- For extra credit, we have an FBO that we can then do a GL_LINEAR
stretch-blit to the real window system framebuffer, so the game doesn't
have to be 640x480 anymore. Since the 8-bit values have to line up exactly
for the palette to work, that _has_ to render at 640x480 to get the right
colors, but then you can do a nice linear filter when going to the screen.
Now it looks like it would if you dropped your monitor's resolution to
640x480 to fill the whole display, but the Steam Overlay still renders at
full resolution.
This took a few hours to implement, got some cool benefits, and this Mac
uses about 4% of the CPU to play the game.
--ryan.
______________________________**_________________
SDL mailing list
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.org<http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org>
Sik the hedgehog
2013-04-07 22:03:52 UTC
Permalink
My game is software rendered and it does pretty much what you said in
the last paragraph: I copy the framebuffer to a streaming texture and
then call SDL_RenderCopy with it (bonus for allowing scaling to be
done by the GPU). I don't use surfaces at all. It seems the optimal
route.

But yeah, you'll need to convert from 8-bit to 32-bit on the fly. You
could try also just converting all sprites to 32-bit when loaded and
save time, but then you lose the ability to do palette tricks (though
then you aren't limited to 256 colors anymore).
I'm working on porting my Wolfenstein 3D source port from SDL1 over to
SDL2. One thing that isn't clear in the migration guide is how to
handle 8-bit software rendering with SDL2.
Currently I have a 8-bit off screen surface which the engine renders
to. Previously I would just call SDL_BlitSurface to bring it on screen
and then finally SDL_Flip. Now it seems I have to use
SDL_CreateTextureFromSurface, SDL_RenderCopy, SDL_RenderPresent, and
finally SDL_DestroyTexture. On the surface this seems a lot less
efficient, but it could very well be what SDL1 was doing the whole time
any way since the performance seems to be roughly the same.
Is this the correct way to do things or is there a way I can reuse a
texture between frames? The other solutions I could think of are to
either write my own 8-bit to 32-bit code and use a streaming texture,
possibly avoiding the SDL_Surface altogether. I could also blit to an
intermediate surface to do the conversion and hope that the texture's
pitch matches the surface pitch and memcpy.
- Blzut3
_______________________________________________
SDL mailing list
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Braden Obrzut
2013-04-08 18:09:44 UTC
Permalink
Looking at the rest of the replies this does indeed look like the way to
go. It's kind of a shame that SDL2 doesn't have a function to
automatically do the conversion, but obviously it's not that difficult
to do manually.

I suppose this way I could also switch to using a column major off
screen buffer and potentially gain a little extra performance out of the
renderer while rendering walls and sprites. Not sure if the
floor/ceiling drawing code will simply negate this advantage though.

I do like Ryan's suggestion to do the palette conversion in OpenGL,
however, I will still need the pure software fallback where OpenGL is
not available. When working on a game like Wolfenstein 3D, you're kind
of expected to support old hardware. (Speaking of, does SDL2 drop
support for Windows 9x? Haven't tried it out on Windows yet.)

With that said, due to issues with the input system in ECWolf, I'll
still have to stick with SDL 1.2 for awhile, so I won't really be able
to test performance of the various methods suggested.

- Blzut3
Sik the hedgehog
2013-04-08 18:27:36 UTC
Permalink
Doesn't Wolfstein 3D just render two filled rectangles for the floor
and ceiling? :P

And I think SDL2 demands Windows XP minimum, but you may want to try,
maybe it still works on Windows 9x (albeit with some functionality not
being usable). It still supports DX9 so at least that part should be
covered for Windows 98 (95 is out of luck though, at least for audio
support).
Post by Braden Obrzut
Looking at the rest of the replies this does indeed look like the way to
go. It's kind of a shame that SDL2 doesn't have a function to
automatically do the conversion, but obviously it's not that difficult
to do manually.
I suppose this way I could also switch to using a column major off
screen buffer and potentially gain a little extra performance out of the
renderer while rendering walls and sprites. Not sure if the
floor/ceiling drawing code will simply negate this advantage though.
I do like Ryan's suggestion to do the palette conversion in OpenGL,
however, I will still need the pure software fallback where OpenGL is
not available. When working on a game like Wolfenstein 3D, you're kind
of expected to support old hardware. (Speaking of, does SDL2 drop
support for Windows 9x? Haven't tried it out on Windows yet.)
With that said, due to issues with the input system in ECWolf, I'll
still have to stick with SDL 1.2 for awhile, so I won't really be able
to test performance of the various methods suggested.
- Blzut3
_______________________________________________
SDL mailing list
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Braden Obrzut
2013-04-08 18:51:19 UTC
Permalink
Vanilla Wolf3D does indeed just clear the frame buffer before drawing.
However, my source port, ECWolf ( http://maniacsvault.net/ecwolf/ ), is
designed to be a general purpose ray casting engine and supports full
texture mapping among many other graphical improvements. :P

I suppose I could give SDL2 a try on Windows 98 and report back. I'm not
especially concerned about Windows 95 as it seems all the 9x hold offs
are using 98. Ultimately if SDL2 does drop 9x I may end up supporting
both SDL 1 and 2 and using SDL2 on 64-bit Windows builds or something to
keep things simple.

- Blzut3
Sik the hedgehog
2013-04-08 18:53:20 UTC
Permalink
Well, as far as I know textured floors and ceilings are still done
vertically, so hopefully it shouldn't be much of an issue... (really
this is a case where doing it horizontally or vertically is not going
to change much, cache locality aside)
Post by Braden Obrzut
Vanilla Wolf3D does indeed just clear the frame buffer before drawing.
However, my source port, ECWolf ( http://maniacsvault.net/ecwolf/ ), is
designed to be a general purpose ray casting engine and supports full
texture mapping among many other graphical improvements. :P
I suppose I could give SDL2 a try on Windows 98 and report back. I'm not
especially concerned about Windows 95 as it seems all the 9x hold offs
are using 98. Ultimately if SDL2 does drop 9x I may end up supporting
both SDL 1 and 2 and using SDL2 on 64-bit Windows builds or something to
keep things simple.
- Blzut3
_______________________________________________
SDL mailing list
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Ryan C. Gordon
2013-04-09 04:05:39 UTC
Permalink
Post by Braden Obrzut
I do like Ryan's suggestion to do the palette conversion in OpenGL,
For those that are curious, here's the code for that...


// call prepareOpenGLShaders() after setting up your GL context.

struct OpenGLVertexAttribs
{
GLfloat x;
GLfloat y;
GLfloat u;
GLfloat v;
};

static bool prepareOpenGLShaders(const int w, const int h)
{
static const char *glslVertexShader =
"#version 110\n"
"attribute vec2 pos;"
"attribute vec2 tex;"
"void main() {"
"gl_Position = vec4(pos.xy, 0.0, 1.0);"
"gl_TexCoord[0].xy = tex;"
"}"
;

static const char *glslFragmentShader2D =
"#version 110\n"
"uniform sampler2D image;"
"uniform sampler2D palette;"
"void main() {"
"gl_FragColor = texture2D(palette, vec2(texture2D(image,
gl_TexCoord[0].xy).x, 0.0));"
"}"
;

static const char *glslFragmentShaderRect =
"#version 110\n"
"#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect image;"
"uniform sampler2DRect palette;"
"void main() {"
"gl_FragColor = texture2DRect(palette,
vec2(texture2DRect(image, gl_TexCoord[0].xy).x * 255.0, 0.0));"
"}"
;

GLuint vertex = 0;
GLuint fragment = 0;
GLuint program = 0;
GLint ok = 0;
GLint shaderlen = 0;

ok = 0;
shaderlen = (GLint) strlen(glslVertexShader);
vertex = pglCreateShader(GL_VERTEX_SHADER);
pglShaderSource(vertex, 1, (const GLchar **) &glslVertexShader,
&shaderlen);
pglCompileShader(vertex);
pglGetShaderiv(vertex, GL_COMPILE_STATUS, &ok);
if (!ok)
{
char errbuf[256];
GLsizei len = 0;
pglGetShaderInfoLog(vertex, sizeof (errbuf), &len, (GLchar *)
errbuf);
printf("POSTAL1 vertex shader compile error:\n%s\n\n", errbuf);
pglDeleteShader(vertex);
return false;
} // if

const bool isTextureRect = (OpenGLTextureTarget ==
GL_TEXTURE_RECTANGLE_ARB);
const char *glslFragmentShader = isTextureRect ?
glslFragmentShaderRect : glslFragmentShader2D;

ok = 0;
shaderlen = (GLint) strlen(glslFragmentShader);
fragment = pglCreateShader(GL_FRAGMENT_SHADER);
pglShaderSource(fragment, 1, (const GLchar **) &glslFragmentShader,
&shaderlen);
pglCompileShader(fragment);
pglGetShaderiv(fragment, GL_COMPILE_STATUS, &ok);
if (!ok)
{
char errbuf[256];
GLsizei len = 0;
pglGetShaderInfoLog(fragment, sizeof (errbuf), &len, (GLchar *)
errbuf);
printf("POSTAL1 fragment shader compile error:\n%s\n\n", errbuf);
pglDeleteShader(vertex);
pglDeleteShader(fragment);
return false;
} // if

ok = 0;
OpenGLProgram = pglCreateProgram();
pglAttachShader(OpenGLProgram, vertex);
pglAttachShader(OpenGLProgram, fragment);
pglBindAttribLocation(OpenGLProgram, 0, "pos");
pglBindAttribLocation(OpenGLProgram, 1, "tex");
pglLinkProgram(OpenGLProgram);
pglDeleteShader(vertex);
pglDeleteShader(fragment);
pglGetProgramiv(OpenGLProgram, GL_LINK_STATUS, &ok);
if (!ok)
{
pglDeleteProgram(OpenGLProgram);
OpenGLProgram = 0;
return false;
} // if

pglUseProgram(OpenGLProgram);
pglUniform1i(pglGetUniformLocation(OpenGLProgram, "image"), 0);
pglUniform1i(pglGetUniformLocation(OpenGLProgram, "palette"), 1);

const float left = -1.0f;
const float right = 1.0f;
const float top = 1.0f;
const float bottom = -1.0f;

OpenGLVertexAttribs verts[4] = {
{ left, top, 0.0f, 0.0f },
{ right, top, 1.0f, 0.0f },
{ left, bottom, 0.0f, 1.0f },
{ right, bottom, 1.0f, 1.0f }
};

if (isTextureRect)
{
for (int i = 0; i < (sizeof (verts) / sizeof (verts[0])); i++)
{
verts[i].u *= (GLfloat) w;
verts[i].v *= (GLfloat) h;
}
}

pglGenBuffers(1, &OpenGLVBO);
pglBindBuffer(GL_ARRAY_BUFFER, OpenGLVBO);
pglBufferData(GL_ARRAY_BUFFER, sizeof (verts), verts, GL_STATIC_DRAW);

const OpenGLVertexAttribs *ptr = NULL; // it's a bound VBO.

pglVertexAttribPointer(0, 2, GL_FLOAT, 0, sizeof (verts[0]), &ptr->x);
pglEnableVertexAttribArray(0);

pglVertexAttribPointer(1, 2, GL_FLOAT, 0, sizeof (verts[0]), &ptr->u);
pglEnableVertexAttribArray(1);

return true;
}


// Make sure your image texture and palette texture are on texunits 0
// and 1. Everything else is all set up in here, so other than making
// sure the textures are set up, here's how you get it to the screen:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
SDL_GL_SwapBuffers(); // this is SDL_GL_SwapWindow() in SDL2.


The FBOs to stretch-blit add another dozen or two lines of code, but
that's the gist otherwise.
Post by Braden Obrzut
however, I will still need the pure software fallback where OpenGL is
not available. When working on a game like Wolfenstein 3D, you're kind
of expected to support old hardware.
Id Software's original build is still available for people still running
DOS. :P

--ryan.
Sik the hedgehog
2013-04-09 04:10:46 UTC
Permalink
Post by Ryan C. Gordon
Post by Braden Obrzut
however, I will still need the pure software fallback where OpenGL is
not available. When working on a game like Wolfenstein 3D, you're kind
of expected to support old hardware.
Id Software's original build is still available for people still running
DOS. :P
He's working on a modified version of the engine with things like
textured floors and such, so that was probably a poor excuse :P
Mason Wheeler
2013-04-07 22:12:50 UTC
Permalink
SDL2 has render targets, special textures that can be bound in place of the screen as the current rendering target and drawn to.  You can use them for offscreen rendering.

Mason



________________________________
From: Braden Obrzut <***@maniacsvault.net>
To: ***@lists.libsdl.org
Sent: Sunday, April 7, 2013 2:23 PM
Subject: [SDL] SDL2 and Software Rendering

I'm working on porting my Wolfenstein 3D source port from SDL1 over to SDL2.  One thing that isn't clear in the migration guide is how to handle 8-bit software rendering with SDL2.

Currently I have a 8-bit off screen surface which the engine renders to.  Previously I would just call SDL_BlitSurface to bring it on screen and then finally SDL_Flip.  Now it seems I have to use SDL_CreateTextureFromSurface, SDL_RenderCopy, SDL_RenderPresent, and finally SDL_DestroyTexture.  On the surface this seems a lot less efficient, but it could very well be what SDL1 was doing the whole time any way since the performance seems to be roughly the same.

Is this the correct way to do things or is there a way I can reuse a texture between frames?  The other solutions I could think of are to either write my own 8-bit to 32-bit code and use a streaming texture, possibly avoiding the SDL_Surface altogether.  I could also blit to an intermediate surface to do the conversion and hope that the texture's pitch matches the surface pitch and memcpy.

- Blzut3
Alex Barry
2013-04-07 22:27:10 UTC
Permalink
You might be interested in
this<http://wiki.libsdl.org/moin.fcg/SDL_CreateSoftwareRenderer?highlight=%28%5CbCategoryRender%5Cb%29%7C%28CategoryEnum%29%7C%28CategoryStruct%29%7C%28SGFunctions%29>
.
I'm working on porting my Wolfenstein 3D source port from SDL1 over to
SDL2. One thing that isn't clear in the migration guide is how to handle
8-bit software rendering with SDL2.
Currently I have a 8-bit off screen surface which the engine renders to.
Previously I would just call SDL_BlitSurface to bring it on screen and
then finally SDL_Flip. Now it seems I have to use
SDL_CreateTextureFromSurface, SDL_RenderCopy, SDL_RenderPresent, and
finally SDL_DestroyTexture. On the surface this seems a lot less
efficient, but it could very well be what SDL1 was doing the whole time any
way since the performance seems to be roughly the same.
Is this the correct way to do things or is there a way I can reuse a
texture between frames? The other solutions I could think of are to either
write my own 8-bit to 32-bit code and use a streaming texture, possibly
avoiding the SDL_Surface altogether. I could also blit to an intermediate
surface to do the conversion and hope that the texture's pitch matches the
surface pitch and memcpy.
- Blzut3
______________________________**_________________
SDL mailing list
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.org<http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org>
Sik the hedgehog
2013-04-08 00:22:44 UTC
Permalink
It's slow in the sense that "data needs to be transferred to the video
hardware". It shouldn't be noticeable worse than blitting to screen,
if at all (provided you're using a streaming texture).
Post by Jonathan Dearborn
Even if SDL_UpdateTexture() says that it is slow, I would try it anyway.
You might get a decent speed boost if you don't have to create texture
memory each frame. If you were using OpenGL, I'd say the same thing about
glTexSubImage2D().
Jonny D
You might be interested in
this<http://wiki.libsdl.org/moin.fcg/SDL_CreateSoftwareRenderer?highlight=%28%5CbCategoryRender%5Cb%29%7C%28CategoryEnum%29%7C%28CategoryStruct%29%7C%28SGFunctions%29>
.
On Sun, Apr 7, 2013 at 5:23 PM, Braden Obrzut
I'm working on porting my Wolfenstein 3D source port from SDL1 over to
SDL2. One thing that isn't clear in the migration guide is how to handle
8-bit software rendering with SDL2.
Currently I have a 8-bit off screen surface which the engine renders to.
Previously I would just call SDL_BlitSurface to bring it on screen and
then finally SDL_Flip. Now it seems I have to use
SDL_CreateTextureFromSurface, SDL_RenderCopy, SDL_RenderPresent, and
finally SDL_DestroyTexture. On the surface this seems a lot less
efficient, but it could very well be what SDL1 was doing the whole time any
way since the performance seems to be roughly the same.
Is this the correct way to do things or is there a way I can reuse a
texture between frames? The other solutions I could think of are to either
write my own 8-bit to 32-bit code and use a streaming texture, possibly
avoiding the SDL_Surface altogether. I could also blit to an intermediate
surface to do the conversion and hope that the texture's pitch matches the
surface pitch and memcpy.
- Blzut3
______________________________**_________________
SDL mailing list
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.org<http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org>
_______________________________________________
SDL mailing list
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
RodrigoCard
2013-04-08 02:48:54 UTC
Permalink
This whole discussion makes me think:
For software rendering, SDL 1.2 is still the best bet?
I mean, does the software rendering within SDL2 (eighter using SDL_CreateSoftwareRender or the software fall back of the SDL_CreateRender, not sure if there is differences) performs WORSE than the one in SDL 1.2? I really want to know the answer...

Cheers!

------------------------
Rodrigo Cardoso Rocha
@RodrigoRodrigoR - twitter.com/RodrigoRodrigoR
Chibata Creations - chibatacreations.com
Gabriele Greco
2013-04-08 08:43:26 UTC
Permalink
This post might be inappropriate. Click to display it.
Nathaniel J Fries
2013-04-08 12:26:13 UTC
Permalink
In your case, you almost have to use SDL 1.2. That isn't to say that SDL 2 couldn't be patched fairly easily to support palettes on textures.

Shy of doing this, the other best option is to use a streaming texture, but you'd still need to convert pixel format on the CPU every frame.

------------------------
Nate Fries
Sik the hedgehog
2013-04-08 16:23:59 UTC
Permalink
Considering modern hardware doesn't support palettes at all (VGA
compatibility aside, and even that is thrown away on UEFI systems),
I'd say that letting the software handle the palettes on its own is a
better option in the long term. It will avoid headaches later when
there isn't any other option but to go true color.

Gabriele: how is the performance of that on phones? Just curious about
how much CPU it uses up. I assume the framebuffer is low resolution?

Oh, I just remembered: my game normally uses the GPU to do the
scaling, but there's a switch that forces it to use the software
renderer. On desktop systems it's still pretty much full framerate
(even on my mum's crappy computer), on netbooks it seems to get tricky
though. I know because I accidentally swapped those at some point and
had to showcase the game on a netbook... Yeah, bad idea. Bonus for
debug SDL build (so no optimizations!). Though when the media player
in the background stopped playing it went back to 60FPS... Still, you
have been warned. Stick with the GPU for the final scaling if you can,
even integrated chips will be fast for something like this (it's just
a quad after all!).
Post by Nathaniel J Fries
In your case, you almost have to use SDL 1.2. That isn't to say that SDL 2
couldn't be patched fairly easily to support palettes on textures.
Shy of doing this, the other best option is to use a streaming texture, but
you'd still need to convert pixel format on the CPU every frame.
------------------------
Nate Fries
Gabriele Greco
2013-04-08 16:56:25 UTC
Permalink
Post by Sik the hedgehog
Gabriele: how is the performance of that on phones? Just curious about
how much CPU it uses up. I assume the framebuffer is low resolution?
The framebuffer size is set by aspect ratio and device.

On an iphone is 480 x 320, on iphone5 is 568x320, on an ipad it's 512 x
384, on an android device, it may be from 320 x 240 to 800 x 480.

I keep the aspect ratio correct and try to keep the objects big enough to
be easy distinguishable, if the scaling is not pixel perfect (like it is in
iOS) I use:

SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");

... to improve the quality.

Scaling is obviously done by the GPU.

I get a decent 30fps also on the lower end phone I've tried, an HTC hero,
iOS phones (3GS+) have no problem to reach 60fps.

Desktop speed is not an issue.

This game is born 15 years ago with a 14mhz amiga 1200 as target that has
to do at least 25fps in 320x256, the SDL portable port I made in y2k was a
bit heavier but it was able to achieve 50fps in 640x480 on a 90mhz pentium
(50fps was the frame cap being the game thought for pal displays).

Actually the game in my 8 year old linux desktop (P4Dual) take 5% of one
CPU in a 640x480 window with SDL2 backend.

Anyway here is the code of the video module, it's a bit "dirty" but the
fact it has 15 years and the various porting layers made it a bit messy, I
have resisted the need to rewrite it because sadly I've no time to do it :)

http://etw.svn.sourceforge.net/viewvc/etw/trunk/etw/os_video.c?revision=345&view=markup
--
Bye,
Gabry
Jared Maddox
2013-04-08 22:48:54 UTC
Permalink
Date: Mon, 08 Apr 2013 14:51:19 -0400
Subject: Re: [SDL] SDL2 and Software Rendering
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Vanilla Wolf3D does indeed just clear the frame buffer before drawing.
However, my source port, ECWolf ( http://maniacsvault.net/ecwolf/ ), is
designed to be a general purpose ray casting engine and supports full
texture mapping among many other graphical improvements. :P
I suppose I could give SDL2 a try on Windows 98 and report back. I'm not
especially concerned about Windows 95 as it seems all the 9x hold offs
are using 98. Ultimately if SDL2 does drop 9x I may end up supporting
both SDL 1 and 2 and using SDL2 on 64-bit Windows builds or something to
keep things simple.
- Blzut3
I doubt that Sam or Ryan are interested in providing official Win9x
support, but if SDL won't work straight out of the box there, then I'm
sure they'd accept any patches that provide support for it (and it
shouldn't be too hard, since at least some of what's missing should be
grabbable from SDL 1.2).

As for OpenGL, have you tried using TinyGL, or something similar? I
don't know that there are any software OpenGL implementations that
provide programmable shaders, but there is a TinyGL port to SDL
underway, so if nothing else you could write your own shader
abstraction so that you just use TinyCC to compile C shaders when you
can't use proper ones.
Ryan C. Gordon
2013-04-08 23:38:08 UTC
Permalink
Post by Jared Maddox
I doubt that Sam or Ryan are interested in providing official Win9x
support, but if SDL won't work straight out of the box there,
It almost certainly won't, and I doubt the time and mess it would
require is worth it.

There is NO reason to be supporting any Windows older than XP in 2013
(and it's sad that I can't say "Vista" there, but oh well).

--ryan.
Sik the hedgehog
2013-04-08 23:44:45 UTC
Permalink
These days many programs won't even support XP, they demand 7
(technically most of those demand Vista since that's when the big API
additions were made, but that's beyond the point). And Microsoft's XP
support ends in 2014. That said, for Windows 98 there are hacks that
backport some of the XP new features that allow XP programs to run on
it, and if you're still running 98 for non-legacy programs you
probably are using that.

What I wonder though, is SDL going to drop support for 32-bit Windows
if XP support is killed in the far future? I'm not sure that even
matters with the current code, but it'd be interesting to see. On XP
most people use 32-bit, but on 7 most people use 64-bit. In
particular, this'd affect which DirectX versions are available.
Post by Ryan C. Gordon
Post by Jared Maddox
I doubt that Sam or Ryan are interested in providing official Win9x
support, but if SDL won't work straight out of the box there,
It almost certainly won't, and I doubt the time and mess it would
require is worth it.
There is NO reason to be supporting any Windows older than XP in 2013
(and it's sad that I can't say "Vista" there, but oh well).
--ryan.
_______________________________________________
SDL mailing list
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Braden Obrzut
2013-04-11 18:48:28 UTC
Permalink
"That said, for Windows 98 there are hacks that backport some of the XP
new features that allow XP programs to run on it"

I believe at the moment this is practically the only way to even get a
fully updated Windows 98 system since Windows update infinite refresh
loops last I tried. I installed the "unofficial Windows 98 service
pack" on mine (since it claims to include all the official updates) and,
according to dependency walker, it looks like only a handful of
functions are missing from the OS.

KERNEL32.DLL
* GetFileSizeEx
* SetFilePointerEx
OLE32.DLL (This one might not even be relevant since it's under SHLWAPI.DLL)
* CoWaitForMultipleHandles
SHELL32.DLL
* SHBindToParent
USER32.DLL
* GetRawInputData
* RegisterRawInputDevices

I'll have to play with this more when I'm not quite as busy, but from
the surface it looks like it's feasible to get SDL2 running acceptably
on patched Windows 98 systems. All of the unicode functions seem
resolve at least.

- Blzut3
Nathaniel J Fries
2013-04-09 04:04:28 UTC
Permalink
For starters, SDL2 would need to be modified to dynamically load the unicode WinAPI functions (from unicows.dll if on Win9x, user32.dll otherwise), and the Direct3D renderer would need to be disabled (DirectX 8.0a is the last version supported by Windows 95, although I guess Windows 98 supports DirectX 9?). Also, any code using NT kernel or XP+ features like XInput, Raw Input, or IOCP would need to be altered to dynamically load the function calls (also define the structures in-code), which would bloat the source code, and either report an error or use some other method as a fallback (for example, a fallback for IOCP would be a restructured implementation using select() ).

This is just what I know from fixing my own code to run on Windows 98 (I've never actually developed for Windows 98 directly), so SDL will most likely need other modifications as well.

------------------------
Nate Fries
Continue reading on narkive:
Loading...