Before I will show you how I wanted to acheive this I would like to explain expected capabilities:
- Render to texture anything like Images
- Draw to texture anything like RectFill ect.
- Apply effects like Blur (requiring Pixel access to texture)
Above steps can “occure” in random count and order.
For 1 and 2 point I need to use SDL_TEXTUREACCESS_TARGET (simply redirecting output from NULL ( screen) to texture using SDL_SetRenderTarget
For 3 I need to use SDL_TEXTUREACCESS_STREAMING
Switching from STREAMING to TARGET is quite easy - simply rendering STREAMING texture to TARGET with SDL_SetRenderTarget, but I have no idea how to “reverse” this porcess.
Here is my idea however it does not work and I don’t know why?
- Function receives “Master” Texture (TARGET one)
- Inside function I’m creating 2 textures - tex1 (TARGET) and tex2 (STREAMING)
- Switching output from screen to tex1
- Rendering Master texture to tex1
- Read Pixels from tex1 using SDL_RenderReadPixels to pixels
- Performing operations on pixels
- Updating tex2 with pixels
- Switching output from tex1 to Master texture
- Rendering tex2 to Master texture
However It looks like function SDL_RenderReadPixels is not reading pixels from texture (when output is redirected to texture - thats why to be double sure that texture is not empty im creating separate tex1 and put context inside)
Code is below - question is same - how to switch texture from TARGET to STREAMING??[Question]
Code:
using namespace std;
#include
#include
#include <time.h>
#include <SDL.h>
void fillTexture(SDL_Renderer *renderer, SDL_Texture *texture, int r, int g, int b, int a)
{
SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(renderer, r, g, b, a);
SDL_RenderFillRect(renderer, NULL);
}
void fillTexture2(SDL_Renderer *renderer, SDL_Texture *texture, int r, int g, int b, int a)
{
SDL_Texture * newt=SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 50, 50);
SDL_Texture * newt2=SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 50, 50);
cout << “SDLERROR1” << SDL_GetError() << endl;
//render to newt2
SDL_SetRenderTarget(renderer, newt2);
cout << "SDLERROR2" << SDL_GetError() << endl;
//render input texture to newt2
SDL_RenderCopyEx(renderer, texture, NULL, NULL,0,NULL,SDL_FLIP_NONE);
cout << "SDLERROR3" << SDL_GetError() << endl;
SDL_Rect q={0,0,50,50};
int pitch = 4;
int w=50;
int h=50;
int pixelCount = w*h;
void * pixels = new Uint8[w * h * pitch];
//current renderer is set newt2
if(SDL_RenderReadPixels (renderer,&q,SDL_PIXELFORMAT_RGBA8888,pixels,w*pitch)<0)
{
int i;
i=1;
}
//memset(pixels, 0, w * h * pitch);
Uint32* pixels32=(Uint32*) pixels;
cout << "SDLERROR4" << SDL_GetError() << endl;
//memset(pixels,0,w * h * pitch);
for(int i = 0; i < pixelCount/16; i++)
{
cout <<(int)pixels32[i];// << "\n";
}
int m,x;
for (int i = 0; i < pixelCount; i++)
{
x=i%2;
if(x==0)
{
pixels32[i]=m;
}
//cout <<pixels32[i] << "\n";
}
if(SDL_UpdateTexture(newt,&q,pixels,w*pitch)<0)
{
int i;
i=1;
}
cout << "SDLERROR5" << SDL_GetError() << endl;
SDL_SetRenderTarget(renderer, texture);
cout << "SDLERROR5" << SDL_GetError() << endl;
//SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(renderer, r, g, b, a);
SDL_SetTextureBlendMode(texture,SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
SDL_RenderCopyEx(renderer, newt, NULL, NULL,0,NULL,SDL_FLIP_NONE);
cout << "SDLERROR6" << SDL_GetError() << endl;
SDL_SetRenderTarget(renderer, NULL);
//SDL_RenderCopyEx(renderer, texture, NULL, NULL,0,NULL,SDL_FLIP_NONE);
SDL_DestroyTexture(newt);
SDL_DestroyTexture(newt2);
newt=NULL;
newt2=NULL;
cout << "SDLERROR7" << SDL_GetError() << endl;
}
void prepareForRendering(SDL_Renderer *renderer)
{
SDL_SetRenderTarget(renderer, NULL);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);
}
void checkSdlError()
{
const char *sdlError = SDL_GetError();
if(sdlError && *sdlError)
{
::std::cout << "SDL ERROR3: " << sdlError << ::std::endl;
}
}
int main(int argc, char *argv[])
{
srand(time(NULL));
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_HAPTIC);
SDL_Window *window = SDL_CreateWindow("SDL test",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
320, 240,
SDL_WINDOW_OPENGL);
SDL_Renderer *renderer = SDL_CreateRenderer(
window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
const int width = 50;
const int height = 50;
::std::vector<SDL_Texture*> textures;
SDL_Texture *redTexture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
textures.push_back(redTexture);
SDL_Texture *greenTexture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
textures.push_back(greenTexture);
SDL_Texture *purpleTexture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
textures.push_back(purpleTexture);
// Here is setting the blend mode for each and every used texture:
for(int i = 0; i < textures.size(); ++i)
{
SDL_SetTextureBlendMode(textures[i], SDL_BLENDMODE_BLEND);
}
int purpleAlpha = 0;
fillTexture(renderer, redTexture, 255, 0, 0, 255);
fillTexture(renderer, greenTexture, 0, 255, 0, 128);
fillTexture(renderer, purpleTexture, 255, 255, 255, 255);
prepareForRendering(renderer);
bool running = true;
while(running)
{
SDL_Rect rect;
rect.w = width;
rect.h = height;
SDL_RenderClear(renderer);
rect.x = 50;
rect.y = 50;
SDL_RenderCopy(renderer, redTexture, NULL, &rect);
rect.x = 75;
rect.y = 70;
SDL_RenderCopy(renderer, greenTexture, NULL, &rect);
rect.x = 75;
rect.y = 30;
SDL_RenderCopy(renderer, purpleTexture, NULL, &rect);
SDL_RenderPresent(renderer);
// Process events
{
SDL_Event event;
while(SDL_PollEvent(&event) == 1)
{
if(event.type == SDL_QUIT)
{
running = false;
}
else if(event.type == SDL_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
running = false;
break;
case SDLK_a:
purpleAlpha = ::std::max(purpleAlpha - 32, 0);
fillTexture(renderer, purpleTexture, 255, 255, 255, purpleAlpha);
prepareForRendering(renderer);
::std::cout << "Alpha: " << purpleAlpha << ::std::endl;
break;
case SDLK_s:
purpleAlpha = ::std::min(purpleAlpha + 32, 255);
fillTexture(renderer, purpleTexture, 255, 255, 255, purpleAlpha);
prepareForRendering(renderer);
::std::cout << "Alpha: " << purpleAlpha << ::std::endl;
break;
case SDLK_q:
purpleAlpha = ::std::max(purpleAlpha - 32, 0);
fillTexture2(renderer, purpleTexture, 255, 255, 255, purpleAlpha);
prepareForRendering(renderer);
::std::cout << "Alpha: " << purpleAlpha << ::std::endl;
break;
case SDLK_w:
purpleAlpha = ::std::min(purpleAlpha + 32, 255);
fillTexture2(renderer, purpleTexture, 255, 255, 255, purpleAlpha);
prepareForRendering(renderer);
::std::cout << "Alpha: " << purpleAlpha << ::std::endl;
break;
}
}
}
//checkSdlError();
}
}
for(int i = 0; i < textures.size(); ++i)
{
SDL_DestroyTexture(textures[i]);
}
textures.clear();
SDL_DestroyRenderer(renderer);
renderer = NULL;
SDL_DestroyWindow(window);
window = NULL;
SDL_Quit();
checkSdlError();
return 0;
}
[Question] [Question] [Question] [Question] [Question] [Question] [Question] [/code] [Question] [Question]