Hello! Sorry for bad english. My post “Control nultiple window om different
display” stay withou answers, but i solve problems. Now I have example
(corrected testsprite2.c) - his draw in different windows (each on the own
display). But i have massive memory leaks (approbed in valgrind)! Please view
my example and help if error in the source. Leaks appears in GL_LockTexture
(SDL_renderer_gl.c:666) - i found what a function GL_UnlockTexture -
unimplemented (have a void body), i kill allocated textures
SDL_DestroyTexture() - but this not solve problem! Please help.
/* Simple program: Move N sprites around on the screen as fast as possible */
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include “common.h”
#define NUM_SPRITES 100
static SDL_TextureBlendMode blendMode = SDL_TEXTUREBLENDMODE_MASK;
static SDL_TextureScaleMode scaleMode = SDL_TEXTURESCALEMODE_NONE;
static int num_sprites;
static CommonState *state;
static SDL_TextureID sprites_displ0[260];
static SDL_TextureID sprites_field[1];
static SDL_bool cycle_color;
static SDL_bool cycle_alpha;
static int cycle_direction = 1;
static int current_alpha = 0;
static int current_color = 0;
static int sprite_w, sprite_h;
int current_frame=0;
int result=0;
SDL_WindowID win_1, win_2;
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void
quit(int rc)
{
int im;
for(im=0; im<26; ++im){
SDL_DestroyTexture(sprites_displ0[im]);
}
CommonQuit(state);
exit(rc);
}
int
LoadSprite(char *file_name, SDL_TextureID *sprites, SDL_WindowID win_id)
{
int i, j;
SDL_Surface *temp;
/* Load the sprite image */
temp = SDL_LoadBMP(file_name);
if (temp == NULL) {
fprintf(stderr, "Couldn't load %s: %s", file_name, SDL_GetError());
return (-1);
}
sprite_w = temp->w;
sprite_h = temp->h;
/*
// Set transparent pixel as the pixel at (0,0)
if (temp->format->palette) {
SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels);
}
*/
SDL_SetAlpha(temp, SDL_SRCALPHA, 0);
/* Create textures from the image */
// for (i = 0; i < state->num_windows; ++i) {
SDL_SelectRenderer(win_id);
*sprites =
SDL_CreateTextureFromSurface(0, SDL_TEXTUREACCESS_REMOTE, temp); //
0
if (!(*sprites)) {
fprintf(stderr, “Couldn’t create texture: %s\n”, SDL_GetError());
SDL_FreeSurface(temp);
return (-1);
}
SDL_SetTextureBlendMode(*sprites, SDL_TEXTUREBLENDMODE_NONE); //
SDL_TEXTUREBLENDMODE_MASK
SDL_SetTextureScaleMode(*sprites, SDL_TEXTURESCALEMODE_NONE);
// }
SDL_FreeSurface(temp);
return (0);
}
void
MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
{
SDL_SelectRenderer(window);
// SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL);
result=SDL_RenderCopy(sprite, NULL, NULL);
if (result<0) printf("—>error in SDL_RenderCopy()\n");
}
int
main(int argc, char *argv[])
{
int i, done;
SDL_Event event;
Uint32 then, now, frames;
/* Initialize test framework */
state = CommonCreateState(argv, SDL_INIT_VIDEO);
if (!state) {
return 1;
}
for (i = 1; i < argc;) {
int consumed;
consumed = CommonArg(state, i);
if (consumed == 0) {
consumed = -1;
if (SDL_strcasecmp(argv[i], "--blend") == 0) {
if (argv[i + 1]) {
if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
blendMode = SDL_TEXTUREBLENDMODE_NONE;
consumed = 2;
} else if (SDL_strcasecmp(argv[i + 1], "mask") == 0) {
blendMode = SDL_TEXTUREBLENDMODE_MASK;
consumed = 2;
} else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
blendMode = SDL_TEXTUREBLENDMODE_BLEND;
consumed = 2;
} else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
blendMode = SDL_TEXTUREBLENDMODE_ADD;
consumed = 2;
} else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
blendMode = SDL_TEXTUREBLENDMODE_MOD;
consumed = 2;
}
}
} else if (SDL_strcasecmp(argv[i], "--scale") == 0) {
if (argv[i + 1]) {
if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
scaleMode = SDL_TEXTURESCALEMODE_NONE;
consumed = 2;
} else if (SDL_strcasecmp(argv[i + 1], "fast") == 0) {
scaleMode = SDL_TEXTURESCALEMODE_FAST;
consumed = 2;
} else if (SDL_strcasecmp(argv[i + 1], "slow") == 0) {
scaleMode = SDL_TEXTURESCALEMODE_SLOW;
consumed = 2;
} else if (SDL_strcasecmp(argv[i + 1], "best") == 0) {
scaleMode = SDL_TEXTURESCALEMODE_BEST;
consumed = 2;
}
}
} else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
cycle_color = SDL_TRUE;
consumed = 1;
} else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
cycle_alpha = SDL_TRUE;
consumed = 1;
} else if (SDL_isdigit(*argv[i])) {
num_sprites = SDL_atoi(argv[i]);
consumed = 1;
}
}
if (consumed < 0) {
fprintf(stderr,
"Usage: %s %s [--blend none|mask|blend|add|mod] [--scale
none|fast|slow|best] [–cyclecolor] [–cyclealpha]\n",
argv[0], CommonUsage(state));
quit(1);
}
i += consumed;
}
// SDL_putenv(“SDL_VIDEO_RENDERER=software”);
SDL_putenv(“SDL_VIDEO_RENDERER=opengl”);
// SDL_putenv(“SDL_VIDEO_RENDERER=x11”);
if (!CommonInit(state)) {
quit(2);
}
SDL_SelectVideoDisplay(0);
result=SDL_CreateWindow(NULL, 0, 0, 1024, 768, SDL_WINDOW_SHOWN |
SDL_WINDOW_OPENGL);
if (result==0){
printf(“error create window 1\n”);
}
else
printf(“window 1 create - have id: %ul\n”, win_1);
win_1=result;
result=SDL_CreateRenderer(win_1, 0, 0);
if (result<0)
printf(“error in creating renderer for win
1(%s)!\n”,SDL_GetError());
SDL_SelectVideoDisplay(1);
result=SDL_CreateWindow(NULL, 0, 0, 1280, 1024, SDL_WINDOW_SHOWN |
SDL_WINDOW_OPENGL);
if (result==0){
printf(“error create window 2\n”);
}
else
printf(“window 2 create - have id: %ul\n”, win_2);
win_2=result;
result=SDL_CreateRenderer(win_2, 0, 0);
if (result<0)
printf(“error in creating renderer for win
2(%s)!\n”,SDL_GetError());
SDL_HideWindow(state->windows[0]);
// SDL_SetWindowPosition(win_1, 0, 0);
// SDL_SetWindowPosition(win_2, 1100, 50);
/*
SDL_SelectVideoDisplay(0);
SDL_SetWindowFullscreen(win_1, 1);
SDL_SelectVideoDisplay(1);
SDL_SetWindowFullscreen(win_2, 1);
/
/
sprites_field = (SDL_TextureID *) SDL_malloc(state->num_windows *
sizeof(*sprites_field));
if (!sprites_field){
fprintf(stderr, “Out of memory - get memory for
sprites_field\n”);
quit(2);
}
*/
for (i = 0; i < state->num_windows; ++i) {
SDL_SelectRenderer(state->windows[i]);
SDL_RenderFill(0xA0, 0xA0, 0xA0, 0XFF, NULL);
}
SDL_SelectVideoDisplay(0);
/*
if (LoadSprite("./bmp/V_20000.bmp", sprites_displ0, win_1) < 0){
quit(2);
}
*/
char name[50], tmp[50];
int im=0;
// for(im=0; im<259; ++im){
for(im=0; im<26; ++im){
strcpy(name, “./bmp/V_20”);
sprintf(tmp, “%03d.bmp”, im);
strcat(name, tmp);
printf("loading %s ...", name);
if (LoadSprite(name, &(sprites_displ0[im]), win_1) < 0){
printf("error\n");
quit(2);
}
printf("ok\n");
}
SDL_SelectVideoDisplay(1);
if (LoadSprite("field_2_24.bmp", &(sprites_field[0]), win_2) < 0){
quit(2);
}
srand(time(NULL));
/* Main render loop */
frames = 0;
then = SDL_GetTicks();
done = 0;
while (!done) {
/* Check for events */
++frames;
while (SDL_PollEvent(&event)) {
CommonEvent(state, &event, &done);
if (event.type & SDL_KEYDOWN){
done=1;
break;
}
switch (event.type) {
/*
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_EXPOSED:
SDL_SelectRenderer(event.window.windowID);
SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL);
SDL_RenderPresent();
break;
}
break;
*/
default:
break;
}
}
SDL_SelectVideoDisplay(0);
// current_frame=0;
MoveSprites(win_1, sprites_displ0[current_frame]);
current_frame=(current_frame!=25)? current_frame+1: 0;
SDL_RenderPresent();
// if (current_frame%10){
result=SDL_SelectVideoDisplay(1);
if (result<0) printf("—>error in SDL_SelectVideoDisplay()\n");
MoveSprites(win_2, sprites_field[0]);
SDL_RenderPresent();
//if (result<0) printf("—>error in SDL_RenderPresent()\n");
// }
}
now = SDL_GetTicks();
if (now > then) {
printf("%2.2f frames per second\n", ((double) frames * 1000) / (now -
then));
}
quit(0);
}