Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
External rendering SDL2
#3
(06-27-2021, 04:32 PM)megamarc Wrote: Hi!

It would be better if you post here source code of your current attempt, so I can check why it's failing.

The "tricky" part of setting up the external rendering is not in tilengine -as it takes just one function-, but on the host side.

In SDL2, at the beginning you must:
  1. create the window
  2. create the renderer
  3. create 32-bit ARGB  backbuffer texture with "streaming" attribute (so it gets optimized for frequent writes):
Code:
SDL_Window* window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, wnd_width, wnd_height, 0);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED + SDL_RENDERER_PRESENTVSYNC);
SDL_Texture* backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, wnd_params.width, wnd_params.height);

Note:
Tilengine supports window scaling, so internal framebuffer resolution is not the same than target window size
  • wnd_width and wnd_height are target window dimensions after scaling
  • wnd_params.width and wnd.params.height are original framebuffer size (the one you set with TLN_Init())
For each rendered frame, you must:

  1. Gain write access to framebuffer by locking the texture
  2. Set render target to the locked texture
  3. Render the frame
  4. Unlock the backbuffer texture so SDL has access again
  5. Copy the backbuffer texture to the renderer, scaling it to fit window size
  6. Present the renderer to the screen:
Code:
// setup render target
static uint8_t* rt_pixels; // pointer to pixel data
static int rt_pitch;       // bytes per scanline
SDL_LockTexture (backbuffer, NULL, (void**)&rt_pixels, &rt_pitch);
TLN_SetRenderTarget (rt_pixels, rt_pitch);

// render frame
TLN_UpdateFrame(frame);

// present to screen
SDL_UnlockTexture(backbuffer);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, backbuffer, NULL, &dstrect);
SDL_RenderPresent(renderer);

This is basically what the built-in tilengine window does, you can find it in window.c source code. As you can see it is mostly SDL2 stuff, not tilengine stuff. This is different for each framework where you want to embed external rendering.

Hope this helps!

Hey Marc, I'm finally getting around to trying to get external rendering working again, but I've ran into some issues again.

I've sent up things nearly identically to the window.c in Tilengine, only I am using a C++ class instead. I thought I had everything right, but then the background was not updating at all, so I double checked and saw I was missing a few things, and now I'm sure it is setup properly, however when I go to call TLN_UpdateFrame() I get a Segmentation fault. What could I be doing wrong?

this is the code I am running in my gameloop to update the graphics:
Code:
const int CURRENT_TIME_MS = SDL_GetTicks();
       int ELAPSED_TIME_MS = CURRENT_TIME_MS - LAST_UPDATE_TIME;

       graphics.beginWindowFrame();
       TLN_UpdateFrame(std::min(ELAPSED_TIME_MS, MAX_FRAME_TIME));
       //this->update(std::min(ELAPSED_TIME_MS, MAX_FRAME_TIME));
       LAST_UPDATE_TIME = CURRENT_TIME_MS;
       graphics.endWindowFrame();

and these are the functions I am using in my graphics class:
Code:
void Graphics::endWindowFrame() {
   SDL_UnlockTexture(this->_backbuffer); // Tilengine stuff
   SDL_RenderClear(this->_renderer);
   SDL_RenderCopy(this->_renderer, this->_backbuffer, NULL, &this->dstrect);
   SDL_RenderPresent(this->_renderer);
}

void Graphics::beginWindowFrame() {
   SDL_LockTexture (this->_backbuffer, NULL, (void**)&this->_rt_pixels, &this->_rt_pitch);
   TLN_SetRenderTarget (this->_rt_pixels, this->_rt_pitch);
}

The graphics class constructor:
Code:
this->_screenWidth = 432;
   this->_screenHeight = 240;
   this->_resWidth = globals::HRES;
   this->_resHeight = globals::VRES;
   this->_maxSprites = 256;
   this->_colorCycles = 2;
   
   this->dstrect.x = 0;
   this->dstrect.y = 0;
this->dstrect.w = globals::SCREEN_WIDTH * (int)globals::SPRITE_SCALE;
this->dstrect.h = globals::SCREEN_HEIGHT * (int)globals::SPRITE_SCALE;
   this->_window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, globals::SCREEN_WIDTH * globals::SPRITE_SCALE, globals::SCREEN_HEIGHT * globals::SPRITE_SCALE, 0);
   this->_renderer = SDL_CreateRenderer(this->_window, -1, SDL_RENDERER_ACCELERATED + SDL_RENDERER_PRESENTVSYNC);
   this->_backbuffer = SDL_CreateTexture(this->_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, this->_resWidth, this->_resHeight);
   SDL_SetTextureAlphaMod(this->_backbuffer, 0);

If you could give me any insight on this it would be much appreciated! Thank you very much and happy new year to you!
Reply


Messages In This Thread
External rendering SDL2 - by RootBeerKing - 06-27-2021, 06:26 AM
RE: External rendering SDL2 - by megamarc - 06-27-2021, 04:32 PM
RE: External rendering SDL2 - by RootBeerKing - 12-29-2021, 05:28 AM
RE: External rendering SDL2 - by megamarc - 01-04-2022, 01:32 AM

Forum Jump:


Users browsing this thread: 1 Guest(s)