47 / 36 / 14
Регистрация: 23.12.2015
Сообщений: 187
1

Компиляция кода с SDL2 под Windows в MinGW

31.01.2018, 21:23. Показов 4714. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня виндовс семь, система 64битная. Компилятор брал сравнительно недавно (после перестановки винды) отсюда http://www.msys2.org/ (расписываю это, так как есть подозрения, что чего-то "недоставил").
Тогда после выполнения их (по ссылке) инструкций, выяснилось, что собственно компилятора то и нет, но поставил в MSYS2 пакет mingw-w64-x86_64-gcc - компилятор появился, начал работать.
На днях захотелось поэкспериментировать с SDL2, когда-то под линуксом с ним работал, там он тривиально компилился.
Поставил у себя пакет mingw-w64-x86_64-SDL2
Уже второй день не могу собрать простейшую тестовую программу(((
Вот она
C++
1
2
3
4
5
6
7
8
9
#include<stdio.h>
#include<math.h>
 
#include<SDL2\SDL.h>
 
int main()
{
    return 0;
}
Никак не хочет собраться в экзешник.
Что сделано для решения проблемы.
Выяснил, что видимо необходимы флаги -lmingw32 -lSDL2main -lSDL2
Выяснил, что возможно надо прописать пути к библиотекам.
Но в моем случае компиляция, сводящаяся к этой строке

c++ -I"C:/msys64/mingw64/include/SDL2" -L"C:/msys64/mingw64/lib" C:\SDL2\sdl2.cpp -lmingw32 -lSDL2main -lSDL2

Дает вывод ошибок (см. скрин):
Миниатюры
Компиляция кода с SDL2 под Windows в MinGW  
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.01.2018, 21:23
Ответы с готовыми решениями:

Компиляция серьезной графики под Mingw
Возьмем для примера gdi+ (c всем остальным у меня получалось абсолютно тоже. только winapi из...

Компиляция кода под конкретную ОС
Есть ОС Windows, Linux, Android. Хочу понять базовые знание по тому как делается библиотека...

MinGW подключение библиотеки lib из под Windows
Подскажите, как подключить библиотеку в формате lib на MinGW. Использую Windows 7 x64 + MinGW....

Компиляция простейшего кода на C++ под GNU/Linux
Проблема в компиляции простейшего кода на c++ под Linux: void hello(){ rintf(&quot;Hello!\n&quot;); ...

16
17111 / 9130 / 2236
Регистрация: 30.01.2014
Сообщений: 15,917
31.01.2018, 21:45 2
Лучший ответ Сообщение было отмечено Новичок как решение

Решение

Ajir, Если -lSDL2main линкуется, то точка входа должна быть такой:
C++
1
2
3
4
int SDL_main(int argc, char *argv[])
{
    return 0;
}
2
47 / 36 / 14
Регистрация: 23.12.2015
Сообщений: 187
31.01.2018, 21:54  [ТС] 3
DrOffset, Попробовал, сразу собралось, появился экзешник! Уже большое спасибо, но:
1. Это что, получается если хочу большую программу писать, то она будет не с main, а с SDL_main как главной функцией?
2. Почему под линухой такого не требовало, SDL же кроссплатформа? И что будет если я под виндой так напишу, а потом под линуху код перемещу? Он там такой скомпилится или это чисто для винды вещь?!
0
17111 / 9130 / 2236
Регистрация: 30.01.2014
Сообщений: 15,917
31.01.2018, 22:04 4
Цитата Сообщение от Ajir Посмотреть сообщение
1. Это что, получается если хочу большую программу писать, то она будет не с main, а с SDL_main как главной функцией?
main определяется внутри библиотеки SDL2main, и вызывает внутри себя функцию SDL_main, которую пользователю предлагается определить в качестве точки входа. Сделано это для того, чтобы не заставлять пользователя вручную выполнять инициализацию и деинициализацию библиотеки. Если это не требуется, то пожалуйста, можно использовать main, но инициализацию управляющих структур библиотеки в этом случае следует выполнить самостоятельно (и, естественно, линковать SDL2main уже не нужно).

Цитата Сообщение от Ajir Посмотреть сообщение
2. Почему под линухой такого не требовало, SDL же кроссплатформа? И что будет если я под виндой так напишу, а потом под линуху код перемещу? Он там такой скомпилится или это чисто для винды вещь?!
Вероятно, SDL2main "под линухой" не линковалась (в некоторых дистрибутивах она и вовсе отсутствует).
1
47 / 36 / 14
Регистрация: 23.12.2015
Сообщений: 187
01.02.2018, 05:54  [ТС] 5
DrOffset, Спасибо, все постепенно проясняется. Но что писать, чтобы скомпилировать просто main(), где самому включать SDL2? Собственно флаги
Цитата Сообщение от Ajir Посмотреть сообщение
-lmingw32 -lSDL2main -lSDL2
прописал лишь потому, что когда писал просто -lSDL2, выводило "нету WinMain"((

Цитата Сообщение от DrOffset Посмотреть сообщение
Вероятно, SDL2main "под линухой" не линковалась (в некоторых дистрибутивах она и вовсе отсутствует).
Ну да, я же точно не писал под линухой в строке компиляции такого флага...
0
3545 / 2215 / 402
Регистрация: 09.09.2017
Сообщений: 9,228
01.02.2018, 11:42 6
Цитата Сообщение от DrOffset Посмотреть сообщение
Если -lSDL2main линкуется, то точка входа должна быть такой:
int SDL_main(int argc, char *argv[])
А вот и не обязательно. Так тоже работает. Собственно, лучше так и писать, ибо стандарт Си.
C
1
int main(int argc, char **argv)
Еще советую выставлять такие флаги (по крайней мере у меня они прекрасно работают в OpenGL)
Linux:
Код
LDFLAGS += -lSDL2 -lGL -lGLU
MinGW:
Код
LDFLAGS += -lSDL2 -static-libgcc -static-libstdc++ -lmingw32 -lSDL2main -lopengl32 -lglu32 -lgdi32 -mconsole -mwindows
Подробнее:
-static-libgcc -static-libstdc++ чтобы не таскать gcc-шные либы отдельно на те машины где их нет. У меня проект смешанный, С/С++ так что подключаю обе
-lmingw32 какие-то mingw-шные библиотеки, вроде бы для GUI
-lSDL2 -lSDL2main внутренности SDL (кстати, никто не знает как подключить SDL статически?)
-lopengl32 -lglu32 очевидно, OpenGL+GLU. То что обычно подключается просто через -lGL -lGLU
-lgdi32 предположительно, библиотека для WinAPI
-mconsole -mwindows обозначают что приложение обладает и оконным и консольным интерфейсом. Что мешало включить их по умолчанию как в Linux мне неизвестно. Возможно, "особенности" архитектуры windows или возможность создания невидимых приложений.
Кстати, порядок аргументов имеет значение!
Если хотите, могу выложить свой makefile для кроссплатформенной сборки, lin32 + lin64 + win32 + win64

Добавлено через 5 минут
Собственно, вот. Если кто предложит как его улучшить буду благодарен
Кликните здесь для просмотра всего текста
Код
progname := res/prog
srcdir = src

files = main

CFLAGS  = -Os -Wall -MD -MP -MT build/$(*F).$(arch).o -MF build/dep/$(@F).mk

CXXFLAGS = $(CFLAGS) -std=c++11

LDFLAGS = -lm  -lSDL2

# Выбор архитектуры
#arch := arch_lin32
arch := arch_lin64
#arch := arch_win32
#arch := arch_win64

# Выбор режима
mode := mode_debug
#mode := mode_release



##############################################################################################
##############################################################################################
#  Реализации
##############################################################################################
##############################################################################################

CC = $(COMP_PREFIX)gcc$(COMP_SUFFIX)
CXX= $(COMP_PREFIX)g++$(COMP_SUFFIX)
AR = $(COMP_PREFIX)gcc-ar$(COMP_SUFFIX)
RLIB=$(COMP_PREFIX)gcc-ranlib$(COMP_SUFFIX)

#разделитель слов в одной записи
_flagdiv_ = _.~№!string_to_split_parameters_of_different_architectures!№~._
_divider_ = _.~№!I_hope_there_will_not_be_this_string_in_flags_or_file_names!№~._
#немного черной магии чтобы получить символ пробела
SPACE := $(subst O_O, ,O_O)

compiler =	$(_flagdiv_)arch_win32 i686-w64-mingw32- -win32\
		$(_flagdiv_)arch_win64 x86_64-w64-mingw32- -win32\
		
		
spec_cflags  =	$(_flagdiv_)arch_lin32 -m32 -isystem /usr/include
spec_cflags +=	$(_flagdiv_)arch_lin64
spec_cflags +=	$(_flagdiv_)arch_win32
spec_cflags +=	$(_flagdiv_)arch_win64
		
spec_ldflags  =	$(_flagdiv_)arch_lin32 -m32 -B/usr/lib/gcc/i686-linux-gnu/6 -lGL -lGLU
spec_ldflags +=	$(_flagdiv_)arch_lin64 -lGL -lGLU
spec_ldflags +=	$(_flagdiv_)arch_win32 -static-libgcc -static-libstdc++ -lmingw32 -lSDL2main -lopengl32 -lglu32 -lgdi32 -mconsole -mwindows -lmingw32 -lSDL2main -lSDL2 -mwindows -lSDL2.dll
spec_ldflags +=	$(_flagdiv_)arch_win64 -static-libgcc -static-libstdc++ -lmingw32 -lSDL2main -lopengl32 -lglu32 -lgdi32 -mconsole -mwindows

res_flags =	$(_flagdiv_)mode_debug -gdwarf-2 -DTODO_WARN

prognames =	arch_lin32$(_divider_)32\
		arch_lin64$(_divider_)64\
		arch_win32$(_divider_)32.exe\
		arch_win64$(_divider_)64.exe\

#Еще черная магия с подстановками. Рассмотрим на примере CFLAGS с добавлением псевдо-переменных
# VAR_A = $(subst $(SPACE),$(_divider_),$(spec_cflags)) - заменяем в исходной строке пробелы на $(_divider_). Теперь пробелов в строке нет
# VAR_B = $(subst $(_flagdiv_), ,$(VAR_A)) - в полученной строке заменяем $(_flagdiv_) на пробелы. Теперь переменная разделена пробелами на длинные строки с arch_ в начале
# VAR_C = $(filter $(arch)$(_divider_)%,$(VAR_B)) - выделяем из переменной строки, начинающиеся на $(arch), то есть на заданную архитектуру. Например, на arch_lin32. Теперь строка содержит только нужные для данной архитектуры параметры,но они все еще разделены $(_divider_)'ами
# VAR_D = $(subst $(_divider_), ,$(VAR_C)) - меняем $(_divider_)'ы на пробелы. Теперь параметры разделены как надо, пробелами. Но в начале все еще есть $(arch), который компилятору не нужен
# CFLAGS = $(filter-out $(arch),$(VAR_D)) - отбрасываем $(arch)
#Теперь переменная содержит только нужные флаги
COMP_PREFIX = $(word 2,$(subst $(_divider_), ,$(filter $(arch)$(_divider_)%,$(subst $(_flagdiv_), ,$(subst $(SPACE),$(_divider_),$(compiler))))))
COMP_SUFFIX = $(word 3,$(subst $(_divider_), ,$(filter $(arch)$(_divider_)%,$(subst $(_flagdiv_), ,$(subst $(SPACE),$(_divider_),$(compiler))))))
CFLAGS += $(filter-out $(arch),$(subst $(_divider_), ,$(filter $(arch)$(_divider_)%,$(subst $(_flagdiv_), ,$(subst $(SPACE),$(_divider_),$(spec_cflags))))))
CFLAGS += $(filter-out $(mode),$(subst $(_divider_), ,$(filter $(mode)$(_divider_)%,$(subst $(_flagdiv_), ,$(subst $(SPACE),$(_divider_),$(res_flags))))))
LDFLAGS := $(filter-out $(arch),$(subst $(_divider_), ,$(filter $(arch)$(_divider_)%,$(subst $(_flagdiv_), ,$(subst $(SPACE),$(_divider_),$(spec_ldflags)))))) $(LDFLAGS)
#тут это извращение уже не нужно, параметры простые
resname := $(progname)$(word 2,$(subst $(_divider_), ,$(filter $(arch)$(_divider_)%,$(prognames))))

objects = $(addprefix build/,$(addsuffix .$(arch).o,$(files)))

.PHONY: clean cleanall

all:	$(objects)
	mkdir -p res
	$(CXX) $(objects) $(LDFLAGS) -o $(resname)
remake: clean all
clean:
	rm -f $(objects)
	rm -f $(resname)
	rm -rf build/dep
release:	allarch
	rm -rf build
	
cleanall:
	rm -rf build
	rm -f $(progname)*
allarch:
#	make -r -j 10 arch=arch_lin32
	make -r -j 10 arch=arch_lin64
	make -r -j 10 arch=arch_win32
	make -r -j 10 arch=arch_win64

build/%.$(arch).o: $(srcdir)/%.c
	mkdir -p build
	$(CC) -c $(CFLAGS) $< -o $@
build/%.$(arch).o: $(srcdir)/%.cpp
	mkdir -p build
	$(CXX) -c $(CXXFLAGS) $< -o $@

-include $(shell mkdir -p build/dep) $(wildcard build/dep/*)
1
17111 / 9130 / 2236
Регистрация: 30.01.2014
Сообщений: 15,917
01.02.2018, 13:54 7
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Так тоже работает.
Это становится возможным благодаря макросу
C++
1
#define main SDL_main
который находится в заголовочном файле "SDL_main.h", этот макрос и "переименовывает" main в SDL_main в этом случае.

Цитата Сообщение от Ajir Посмотреть сообщение
выводило "нету WinMain"((
Вообще, описание всей этой ситуации, а также того, какими способами она может быть решена находится в файле SDL_main.h - можно полюбопытствовать.
В частности, если пользователь предоставляет свою версию main, то перед включением SDL.h ему потребуется определить макрос SDL_MAIN_HANDLED. Вот как-то так:

C++
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <math.h>
 
#define SDL_MAIN_HANDLED
 
#include <SDL2\SDL.h>
 
int main()
{
    return 0;
}
Вот цитатка оттуда на всякий случай:
On Windows SDL provides WinMain(), which parses the command line and passes
the arguments to your main function.

If you provide your own WinMain(), you may define SDL_MAIN_HANDLED
Также приведу кусочек этого файла, касательно функции SDL_main,
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 *  \file SDL_main.h
 *
 *  The application's main() function must be called with C linkage,
 *  and should be declared like this:
 *  \code
 *  #ifdef __cplusplus
 *  extern "C"
 *  #endif
 *  int main(int argc, char *argv[])
 *  {
 *  }
 *  \endcode
 */
 
#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE)
#define main    SDL_main
#endif
 
/**
 *  The prototype for the application's main() function
 */
extern C_LINKAGE int SDL_main(int argc, char *argv[]);
1
3545 / 2215 / 402
Регистрация: 09.09.2017
Сообщений: 9,228
01.02.2018, 14:36 8
Цитата Сообщение от DrOffset Посмотреть сообщение
Это становится возможным благодаря макросу
Значит разработчики SDL молодцы, сохранили совместимость и со стандартом и умудрились добавить противоречащий ему WinMain.
1
47 / 36 / 14
Регистрация: 23.12.2015
Сообщений: 187
01.02.2018, 19:38  [ТС] 9
COKPOWEHEU, DrOffset, Спасибо за содержательные ответы! Ставлю плюсы. По сути отвечу позже, наверно завтра, сейчас нет не сколько времени, сколько сил во всем разобраться основательно.

Добавлено через 2 минуты
COKPOWEHEU, Блин, по непонятной причине не могу "плюсануть" тебя. Придется счас отписаться о ситуации на подфоруме соответствующем.

Добавлено через 2 минуты
А не, все в порядке)
0
47 / 36 / 14
Регистрация: 23.12.2015
Сообщений: 187
10.10.2018, 22:14  [ТС] 10
COKPOWEHEU, DrOffset, Еще раз спасибо, что помогли. Снова вернулся к экспериментам с SDL2

На данный момент умею следующей программой запускать графику в разрешении не заданном системой, а какое я хочу и выводить картинку в заданный прямоугольник.
Моя программа
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include<stdio.h>
#include<math.h>
 
#include<time.h>
 
#include<iostream>
#include<string>
using namespace std;
 
#define SDL_MAIN_HANDLED
 
#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>
#include<SDL2/SDL_mixer.h>
 
//int SDL_main(int argc, char *argv[])
 
SDL_Window *win=nullptr;
SDL_Renderer *ren=nullptr;
 
int SetGraph()
{
    
    if (SDL_Init(SDL_INIT_EVERYTHING)!=0)
    {
        cout<<"SDL_Init Error: "<<SDL_GetError()<<endl;
        return 1;
    }
    
    win = SDL_CreateWindow("Hello World!",0,0,1024-1,768-1,SDL_WINDOW_SHOWN /*| SDL_WINDOW_FULLSCREEN*/);
    if (win==nullptr)
    {
        cout<<"SDL_CreateWindow Error: "<<SDL_GetError()<<std::endl;
        return 1;
    }
    SDL_SetWindowFullscreen(win,SDL_WINDOW_FULLSCREEN);
 
    ren = SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (ren == nullptr)
    {
        cout<<"SDL_CreateRenderer Error: "<<SDL_GetError()<<std::endl;
        return 1;
    }
    
}
 
int DrawPNG(const int x1,const int y1,const int x2,const int y2,const string fname)
{
    
    SDL_Rect pic_RECT;
    pic_RECT.x=x1;   //Смещение полотна по Х
    pic_RECT.y=y1;   //Смещение полотна по Y
    pic_RECT.w=x2-x1; //Ширина полотна
    pic_RECT.h=y2-y1; //Высота полотна
    
    SDL_Texture *pic =  IMG_LoadTexture(ren,fname.c_str());
    SDL_RenderClear(ren); //Очистка рендера
    ///SDL_RenderCopy(ren,background,NULL,&background_RECT); //Копируем в рендер фон
    SDL_RenderCopy(ren, pic, NULL, &pic_RECT); //Копируем в рендер персонажа
    SDL_RenderPresent(ren); //Погнали!!
    
}
 
int main()
{
 
    SetGraph();
 
    DrawPNG(400,100,1000,700,"camp008.png");
    
    int t1=clock();
    
    for(;;)
    {
        int t2=clock();
        if((t2-t1)/CLOCKS_PER_SEC>10){return 0;}
    }   
 
    return 0;
 
}
Вопрос следующий теперь. Если я хочу покрыть заданный прямоугольник текстурой, то мне ничего не остается, кроме как подключать OpenGL в связку с SDL2, как-то конвертировать текстуру SDL2 в текстуру OpenGL, и ее накладывать, или есть гораздо более простой путь средствами самого SDL2 ?
0
Неэпический
17807 / 10579 / 2042
Регистрация: 27.09.2012
Сообщений: 26,609
Записей в блоге: 1
10.10.2018, 22:41 11
Ajir, так SDL_RenderCopy не справляется?
1
47 / 36 / 14
Регистрация: 23.12.2015
Сообщений: 187
10.10.2018, 22:53  [ТС] 12
Croessmah, Посмотрел код по ссылке. Там что, реализовано путем вывода нужных одинаковых картинок по очереди циклами?
0
3545 / 2215 / 402
Регистрация: 09.09.2017
Сообщений: 9,228
11.10.2018, 11:52 13
Цитата Сообщение от Ajir Посмотреть сообщение
Если я хочу покрыть заданный прямоугольник текстурой, то мне ничего не остается, кроме как подключать OpenGL в связку с SDL2
А чего вы хотите добиться в конечном итоге? Потому что игры с разрешением экрана (кстати, было бы неплохо восстанавливать за собой!) больше похожи на разработку игры. А там лучше сразу использовать OpenGL (возможно, уже Vulkan), а тот же SDL для общения с операционкой, но не для графики.
1
47 / 36 / 14
Регистрация: 23.12.2015
Сообщений: 187
12.10.2018, 17:19  [ТС] 14
COKPOWEHEU,
>А чего вы хотите добиться в конечном итоге? Потому что игры с разрешением экрана (кстати, было бы неплохо >восстанавливать за собой!) больше похожи на разработку игры. А там лучше сразу использовать OpenGL (возможно, уже >Vulkan), а тот же SDL для общения с операционкой, но не для графики.
Ну да, я занят любительской разработкой игры.
Мне в итоге для "счастья" нужны функции немногие, особых спецэффектов в игре пока не хочу
1. Запустить графику и в заданном разрешении (из-за этого связался с SDL)
2. Нарисовать точку/линию/прямоугольник нужного цвета.
3. Вывести на экран текст, включая русский, размером буквы 8 на 10 или кратный.
4. Нарисовать в прямоугольник картинку из файла png так чтобы она была растянута по размерам прямоугольник.
5. Покрыть прямоугольник текстурой по размеру текстуры.
6. Сохранить/восстановить из сохранения экран.

Большинство этого давно есть через следующую кривую реализацию. Взял себя библиотеку отсюда

MinGW + Graphics.h It's work)
MinGW + Graphics.h It's work)

И для png добавил свои функции на gdiplus.
НО:
1. Так не изменишь разрешение. Пробовал экспериментировать с счас не помню имен какими функциями winapi которые выставляют разрешение экрана, а при выходе восстанавливать прежнее, но в лучшем случае это меняет расположение иконок на рабочем столе, что ни к чему...
2. Я по хорошему не могу такой чисто учебный и не свободный код вставлять в будущий готовый проект.
3. Также эта "либа" не умеет хорошо работать с размером шрифта, то что могу - текст растягивается только по вертикали, но не по горизонтали.

Вот. Чего хочу добиться в конечном итоге. Что тогда посоветуете?!

Добавлено через 1 час 37 минут
Добавка. Забыл написать. Разумеется хочу и функции работы с мышью, чтение текущих координат и нажата ли в данный момент левая/правая кнопка мыши.
0
3545 / 2215 / 402
Регистрация: 09.09.2017
Сообщений: 9,228
12.10.2018, 19:21 15
Цитата Сообщение от Ajir Посмотреть сообщение
2. Нарисовать точку/линию/прямоугольник нужного цвета.
Не уверен что в SDL есть функции рисования линий. Хотя мне они и не были нужны, поэтому утверждать не буду. Про openGL могу сказать точно - умеет.
Цитата Сообщение от Ajir Посмотреть сообщение
3. Вывести на экран текст, включая русский, размером буквы 8 на 10 или кратный.
SDL_ttf умеет создавать текстуры (SDL-ные) с текстом любого размера, в том числе в кодировке unicode (то есть не только русский и английский текст).
Цитата Сообщение от Ajir Посмотреть сообщение
4. Нарисовать в прямоугольник картинку из файла png так чтобы она была растянута по размерам прямоугольник.
Опять же, не уверен на счет SDL, но вот OpenGL с растяжением и прочими изменениями картинки справляется. Для загрузки можно использовать тот же SDL_image, что использовали вы.
Цитата Сообщение от Ajir Посмотреть сообщение
6. Сохранить/восстановить из сохранения экран.
Вот это довольно странное требование. Может, проще сохранять расположение всех объектов на экране и при загрузке просто отрисовывать их? Впрочем, SDL вроде бы умеет сохранять текстуру (surface), в которую проводилось рисование.
Цитата Сообщение от Ajir Посмотреть сообщение
Добавка. Забыл написать. Разумеется хочу и функции работы с мышью, чтение текущих координат и нажата ли в данный момент левая/правая кнопка мыши.
SDL вполне справляется с этим.
.
В общем, использование SDL (или SFML, возможно - я с ним дела не имел, ничего сказать не могу) вполне оправдано. Ну разве что для вывода графики я бы все-таки использовал OpenGL. Благо вот как раз OpenGL'ные библиотеки поставляются прямо с системой и лишних зависимостей не потащат. В отличие от SDL, где тащить библиотеки все-таки придется. Я не нашел способа встраивать их статически.
Могу ошибаться, но кажется, вы воспринимаете OpenGL и SDL как "конкурентов"? Это не так, у них разные ниши и они хорошо дополняют друг друга. OpenGL это работа с графикой и только с ней. Там нет даже средств загрузки текстур или создания окон, не говоря уж про шрифты, сетевое взаимодействие, звук и тому подобное. Вот для этого вполне можно использовать SDL.
0
47 / 36 / 14
Регистрация: 23.12.2015
Сообщений: 187
18.11.2018, 08:49  [ТС] 16
Почему такой код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include<stdio.h>
#include<math.h>
 
#include<time.h>
 
#include<iostream>
#include<string>
using namespace std;
 
#define SDL_MAIN_HANDLED
 
#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>
#include<SDL2/SDL_mixer.h>
 
//int SDL_main(int argc, char *argv[])
 
SDL_Window *win=nullptr;
SDL_Renderer *ren=nullptr;
 
int SetGraph()
{
    
    if (SDL_Init(SDL_INIT_EVERYTHING)!=0)
    {
        cout<<"SDL_Init Error: "<<SDL_GetError()<<endl;
        return 1;
    }
    
    win = SDL_CreateWindow("Hello World!",0,0,1024-1,768-1,SDL_WINDOW_SHOWN /*| SDL_WINDOW_FULLSCREEN*/);
    if (win==nullptr)
    {
        cout<<"SDL_CreateWindow Error: "<<SDL_GetError()<<std::endl;
        return 1;
    }
    SDL_SetWindowFullscreen(win,SDL_WINDOW_FULLSCREEN);
 
    ren = SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (ren == nullptr)
    {
        cout<<"SDL_CreateRenderer Error: "<<SDL_GetError()<<std::endl;
        return 1;
    }
    
}
 
int DrawPNG(const int x1,const int y1,const int x2,const int y2,const string fname)
{
    
    SDL_Rect pic_RECT;
    pic_RECT.x=x1;   //Смещение полотна по Х
    pic_RECT.y=y1;   //Смещение полотна по Y
    pic_RECT.w=x2-x1; //Ширина полотна
    pic_RECT.h=y2-y1; //Высота полотна
    
    SDL_Texture *pic =  IMG_LoadTexture(ren,fname.c_str());
    SDL_RenderClear(ren); //Очистка рендера
    SDL_RenderCopy(ren, pic, NULL, &pic_RECT); //Копируем в рендер персонажа
    SDL_RenderPresent(ren); //Погнали!!
    
}
 
int main()
{
 
    SetGraph();
 
    DrawPNG(400,100,1000,700,"camp008.png");
    DrawPNG(100,100,200,200,"camp008.png");
    int t1=clock();
    
    for(;;)
    {
        int t2=clock();
        if((t2-t1)/CLOCKS_PER_SEC>10){return 0;}
    }   
 
    return 0;
 
}
работает "почти правильно"? Т.е. проблема - если один раз рисовать png, то все ок, но как только попробовал тот же png нарисовать в меньшем размере вверху экрана - выяснилось, что первая нарисованная картинка куда-то девается, остается только вторая(((
0
Неэпический
17807 / 10579 / 2042
Регистрация: 27.09.2012
Сообщений: 26,609
Записей в блоге: 1
19.11.2018, 00:28 17
Ваша функция DrawPNG очищает всё, что было нарисованно до её вызова и потом рисует изображение, причем зачем-то еще содержимое рендера выводит.
Уберите из нее вызовы SDL_RendeClear и SDL_RenderPresent.
Соответственно, в main:
C++
SDL_RenderClear(ren);//Очищает рендер перед выводом изображений
DrawPNG(400,100,1000,700,"camp008.png");
DrawPNG(100,100,200,200,"camp008.png");
SDL_RenderPresent(ren); //Выводит нарисованное
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.11.2018, 00:28
Помогаю со студенческими работами здесь

Компиляция под Windows x64
Здравствуйте есть 2 компьютера на 1 стоит х32 на котором компилируется программа а на другом х64...

Компиляция проекта под linux из windows
Скорее всего раздел не подходит, просто не знаю к какому это относится больше... Вот есть проект...

Компиляция в g++ из MinGW
Добрый день! После скачивания и установки MinGW пытаюсь скомпилировать простую программу из...

Компиляция в MSYS (MinGW)
Всем приветы! Подскажите, есть папка с примерами, там makefile. Я в MSYS захожу в эту папку и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru