I just started programming with C++ and SLD2. I’ve a certain idea, what I would like to realize but first I try several smaller samples for training. I use DevC++ and MinGW on Windows 7. With the following code I’ve the problem, that colors on the screen are not as expected. Blue and red have changed somehow. But when I use SDL_SaveBMP to save my surface as a BMP-file, the colors are right when I view this BMP with any picture viewer. Can anyone tell me, what my problem is?
Code:
#include “SDL2\SDL.h”
#include
#include <time.h>
#include
SDL_Event event;
SDL_Window *my_window;
SDL_Renderer *my_renderer;
SDL_Texture *my_texture;
SDL_Surface *my_surface;
///////////////////////////////
void putpixel(SDL_Surface *surface, int x, int y, Uint32 color) // I use this function to display single pixels on my surface
{ int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = color; break;
case 2:
*(Uint16 *)p = color; break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (color >> 16) & 0xff;
p[1] = (color >> 8) & 0xff;
p[2] = color & 0xff;
} else {
p[0] = color & 0xff;
p[1] = (color >> 8) & 0xff;
p[2] = (color >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = color; break;
}
}
///////////////////////////////
int main(int argc, char* argv[])
{
Uint32 rmask, gmask, bmask, amask;
int screenWidth, screenHeight;
int k, i, j;
Uint16 r, g, b;
int display;
float qx, qy;
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
{ std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl; return 1; }
SDL_DisplayMode current;
screenWidth = screenHeight = 0;
for(k = 0; k < SDL_GetNumVideoDisplays(); ++k) // if several displays are available
{ // look for the largest one and use it
SDL_GetCurrentDisplayMode(k, ¤t);
if (current.w > screenWidth or current.h > screenHeight) {screenWidth = current.w; screenHeight = current.h; display = k;}
}
my_window = SDL_CreateWindow(“MyMandel”, SDL_WINDOWPOS_UNDEFINED_DISPLAY(display) ,
SDL_WINDOWPOS_UNDEFINED_DISPLAY(display) ,
screenWidth,
screenHeight,
SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_FULLSCREEN_DESKTOP );
if (my_window == nullptr) { std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl; return 1;}
my_renderer = SDL_CreateRenderer(my_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (my_renderer == nullptr) { std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl; return 1;}
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff;
#else
rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000;
#endif
my_surface = SDL_CreateRGBSurface(0, screenWidth, screenHeight, 32, rmask, gmask, bmask, amask);
if (my_surface == nullptr) { std::cout << "SDL_CreateRGBSurface Error: " << SDL_GetError() << std::endl; return 1;}
my_texture = SDL_CreateTextureFromSurface(my_renderer, my_surface);
if (my_texture == nullptr) { std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl; return 1; }
SDL_RenderClear(my_renderer);
SDL_RenderCopy(my_renderer, my_texture, NULL, NULL);
SDL_RenderPresent(my_renderer);
for(i=0; i < screenWidth; i++) // just a simple picture in different colors is created
{
for(j=0; j < screenHeight; j++)
{ qx = (float) i / screenWidth ;
qy = (float) j / screenHeight ;
r = 255 * qx;
g = 0;
b = 255 * qy;
putpixel(my_surface, i, j, SDL_MapRGBA(my_surface->format, r, g, b, 255));
}
}
SDL_UpdateTexture(my_texture, NULL, my_surface->pixels, my_surface->pitch);
SDL_RenderClear(my_renderer);
SDL_RenderCopy(my_renderer, my_texture, NULL, NULL);
SDL_RenderPresent(my_renderer);
while(1==1)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_KEYDOWN:
{
switch(event.key.keysym.sym)
{ case SDLK_ESCAPE: // Program can be stopped with ESC key
{ SDL_DestroyRenderer(my_renderer);
SDL_DestroyWindow(my_window);
SDL_Quit();
exit(0);
break;
}
}
case SDLK_s: // s saves the picture as BMP-File
{ char filename [20];
time_t rawtime;
struct tm *timeinfo;
SDL_RWops *pFile;
time (&rawtime);
timeinfo = localtime (&rawtime); // Current timestamp is used for file name
strftime (filename, 20, "J%Y%m%d%H%M%S.bmp", timeinfo);
SDL_SaveBMP(my_surface, filename);
break;
}
}
}
}
}