SDL_CreateTexture()
w/SDL_TEXTUREACCESS_STREAMING
+ SDL_UpdateTexture()
scheint mit dem richtigen Pixelformat gut genug zu funktionieren.
Auf meinem System den Standard-Renderer:
Renderer name: direct3d
Texture formats:
SDL_PIXELFORMAT_ARGB8888
SDL_PIXELFORMAT_YV12
SDL_PIXELFORMAT_IYUV
(obwohl die opengl
info ist die gleiche :)
Renderer name: opengl
Texture formats:
SDL_PIXELFORMAT_ARGB8888
SDL_PIXELFORMAT_YV12
SDL_PIXELFORMAT_IYUV
SDL_PIXELFORMAT_ARGB8888
gibt mir ~ 1 ms/Rahmen:
#include <SDL2/SDL.h>
#include <SDL2/SDL_render.h>
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
atexit(SDL_Quit);
SDL_Window* window = SDL_CreateWindow
(
"SDL2",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
600, 600,
SDL_WINDOW_SHOWN
);
SDL_Renderer* renderer = SDL_CreateRenderer
(
window,
-1,
SDL_RENDERER_ACCELERATED
);
SDL_RendererInfo info;
SDL_GetRendererInfo(renderer, &info);
cout << "Renderer name: " << info.name << endl;
cout << "Texture formats: " << endl;
for(Uint32 i = 0; i < info.num_texture_formats; i++)
{
cout << SDL_GetPixelFormatName(info.texture_formats[i]) << endl;
}
const unsigned int texWidth = 1024;
const unsigned int texHeight = 1024;
SDL_Texture* texture = SDL_CreateTexture
(
renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
texWidth, texHeight
);
vector< unsigned char > pixels(texWidth * texHeight * 4, 0);
SDL_Event event;
bool running = true;
while(running)
{
const Uint64 start = SDL_GetPerformanceCounter();
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
while(SDL_PollEvent(&event))
{
if((SDL_QUIT == event.type) ||
(SDL_KEYDOWN == event.type && SDL_SCANCODE_ESCAPE == event.key.keysym.scancode))
{
running = false;
break;
}
}
// splat down some random pixels
for(unsigned int i = 0; i < 1000; i++)
{
const unsigned int x = rand() % texWidth;
const unsigned int y = rand() % texHeight;
const unsigned int offset = (texWidth * 4 * y) + x * 4;
pixels[ offset + 0 ] = rand() % 256; // b
pixels[ offset + 1 ] = rand() % 256; // g
pixels[ offset + 2 ] = rand() % 256; // r
pixels[ offset + 3 ] = SDL_ALPHA_OPAQUE; // a
}
//unsigned char* lockedPixels;
//int pitch;
//SDL_LockTexture
// (
// texture,
// NULL,
// reinterpret_cast< void** >(&lockedPixels),
// &pitch
// );
//std::copy(pixels.begin(), pixels.end(), lockedPixels);
//SDL_UnlockTexture(texture);
SDL_UpdateTexture
(
texture,
NULL,
&pixels[0],
texWidth * 4
);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
const Uint64 end = SDL_GetPerformanceCounter();
const static Uint64 freq = SDL_GetPerformanceFrequency();
const double seconds = (end - start)/static_cast<double>(freq);
cout << "Frame time: " << seconds * 1000.0 << "ms" << endl;
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
Stellen Sie sicher, dass vsync nicht aktiviert ist (im Treiber erzwungen, eine Co ausgeführt wird) mpositor, etc.) oder sonst alle Ihre Rahmen Zeiten werden ~ 16ms (oder was auch immer Ihre Bildschirmaktualisierung eingestellt ist).
Ich denke, dass Pixel Manipulation selbst ist nicht die Ursache für niedrige FPS. Wenn Sie zufällig jedes Pixel auf dem Bildschirm ändern (nicht nur 1K davon), sollten Sie weit über 30FPS kommen. [Hier] (http://stackoverflow.com/a/24170211/833188) sagt, dass Sie 'SDL_Texture' für die Leistung verwenden sollten. Hast du das probiert? Hast du deinen Code trotzdem profiliert? – Sga
Ich habe eine 'SDL_Texture' mit' TEXTURE_STREAMING', dann die Textur sperren, die Manipulation an dem erhaltenen Pixel-Array vornehmen und sie dann entriegeln, wenn sie fertig ist. – Nidhoegger
Nur Profiling könnte sagen, wo der Flaschenhals ist – Sga