LINUX.ORG.RU

OpenGL Programming Guide (Red Book), 9th Ed: чёрное окно в примерах

 ,


3

2

Я нуб, хочу приобщиться к OpenGL, посмотреть-почитать учебник. На офиц. сайте сабжевой книжки есть ссылка на их гитхаб. Скачал, compilation errors (авторы виндузятники). Вижу 2 пул-реквеста для линукс-порта (2 года уже висят). С обоими фиксами (и elmindreda, и jhannemann) — компилится ок, но почти все примеры показывают чёрное окно.

Видеокарта HD7750 (GCNv1), открытый драйвер radeon (Деб 9 64 stable), xserver-xorg-video-radeon 1:7.8.0

Уважаемые телепаты, и просто умные товарищи, посмотрите пожалуйста, в чём дело? Спасибо.

★★

Ответ на: комментарий от anonymous

Ну я немного против вулкана (opengl использует годот, который я буду юзать), но именно немного :) Посоветуйте толковую книжку аналогичного уровня (чтобы не примитивно-многословная была), с примерами (опять же, на фундаменте от которых можно было бы что-то реальное строить).

the1 ★★
() автор топика
Ответ на: комментарий от anonymous

На гейос нет игр и практически нет железа, поддерживающего игры. Не понимаю, зачем они так заморачиваются. Или у них на мобилках тоже метал?

anonymous
()
Ответ на: комментарий от anonymous

А ты как думал, они усердно унифицируют свои платформы

annulen ★★★★★
()

OpenGL сейчас официально deprecated и имеет смысл только в узких нишах, где достаточно OpenGL 1.x. Осваивай сразу Vulkan.

Quasar ★★★★★
()
Ответ на: комментарий от Quasar

OpenGL сейчас официально deprecated

Весь, целиком? Пожалуйста ссылку на авторитетный источник.

https://godotengine.org/article/abandoning-gles3-vulkan-and-gles2

Анон, большое спасибо, не знал.

Но вулкан, судя по вики, не для меня. Low-level 3D API — это для framework/engine разрабов. Я тут мимокрокодил.

the1 ★★
() автор топика
Ответ на: комментарий от the1

Весь, целиком? Пожалуйста ссылку на авторитетный источник.

Квазар весть такой Порядочный, Интеллигентный, Заботливый, Деловой Аналитик Большого Отделения ЛОРа.

anonymous
()

Я тут подумал, надо ведь было предложить уже готовые исходники! Выбросил директорию с текстурами, ещё кое-что: 01-triangles из 1-ой гл., всего 500кБ. Компилится просто:

cd build
cmake ..
make
../bin/01-triangles
Посмотрите пожалуйста.

the1 ★★
() автор топика
Ответ на: комментарий от the1

В этом проекте было несколько ошибок:

  1. Программа не могла найти шейдеры, так как путь к ним указан был относительно директории bin/, а программа запускалась из директории build/. Но самое главное, что программа не сообщала об ошибке компиляции шейдеров, но почему? Заглянув в код lib/LoadShaders.cpp можно увидеть, что сообщение об ошибке выводится только если определен макрос _DEBUG. Пришлось добавить его в CMakeLists (сразу говорю, в cmake я не силен). Это конечно субъективно, но мне кажется, что текущая директория должна быть в корне проекта, поэтому я компилировал так:
    cd build
    cmake -DCMAKE_BUILD_TYPE=Debug ../
    cd -
    make -C build/
    bin/01-triangles_d
    
    После этого проект перестал компилироваться из-за использования WinApi-шной функции - пришлось ее закомментировать и раскомментировать, как я понял, то, что там было до этого.
  2. Нужно явно указывать версию контекста OpenGL перед созданием. В этом случае версия 4.5, так как используется glCreateBuffers. Для этого используем функцию glfwWindowHint.

Патч:

diff -ur opengl_pg_9ed/CMakeLists.txt abc/CMakeLists.txt
--- opengl_pg_9ed/CMakeLists.txt	2018-11-27 20:06:06.000000000 +0200
+++ abc/CMakeLists.txt	2018-11-27 23:28:20.781854654 +0200
@@ -80,5 +80,6 @@
 include_directories( include )
 include_directories(lib/glfw/include)
 
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
 ADD_CUSTOM_TARGET(debug ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=Debug ${PROJECT_SOURCE_DIR})
 ADD_CUSTOM_TARGET(release ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=Release ${PROJECT_SOURCE_DIR})
diff -ur opengl_pg_9ed/include/vapp.h abc/include/vapp.h
--- opengl_pg_9ed/include/vapp.h	2018-11-26 16:28:51.000000000 +0200
+++ abc/include/vapp.h	2018-11-27 23:41:48.835629937 +0200
@@ -6,6 +6,7 @@
 #ifndef _WIN32
 #include <sys/time.h>
 #endif
+#include <stdio.h> // printf
 
 class VermilionApplication
 {
@@ -73,6 +74,7 @@
 
 #ifdef _DEBUG
 //*
+#if 0
 #define DEBUG_OUTPUT_CALLBACK                                                   \
 void APIENTRY VermilionApplication::DebugOutputCallback(GLenum source,          \
                                                          GLenum type,           \
@@ -85,7 +87,7 @@
     OutputDebugStringA(message);                                                \
     OutputDebugStringA("\n");                                                   \
 }
-/*/
+#endif
 #define DEBUG_OUTPUT_CALLBACK                                                   \
 void APIENTRY VermilionApplication::DebugOutputCallback(GLenum source,         \
                                                          GLenum type,           \
@@ -101,7 +103,6 @@
                           "SEVERITY(0x%04X), \"%s\"\n",\
            source, type, id, severity, message);\
 }
-*/
 #else
 #define DEBUG_OUTPUT_CALLBACK
 #endif
diff -ur opengl_pg_9ed/src/01-triangles/01-triangles.cpp abc/src/01-triangles/01-triangles.cpp
--- opengl_pg_9ed/src/01-triangles/01-triangles.cpp	2016-09-18 22:30:22.000000000 +0300
+++ abc/src/01-triangles/01-triangles.cpp	2018-11-27 23:51:22.077768711 +0200
@@ -38,8 +38,8 @@
 
     ShaderInfo  shaders[] =
     {
-        { GL_VERTEX_SHADER, "media/shaders/triangles/triangles.vert" },
-        { GL_FRAGMENT_SHADER, "media/shaders/triangles/triangles.frag" },
+        { GL_VERTEX_SHADER, "bin/media/shaders/triangles/triangles.vert" },
+        { GL_FRAGMENT_SHADER, "bin/media/shaders/triangles/triangles.frag" },
         { GL_NONE, NULL }
     };
 
@@ -86,6 +86,9 @@
 {
     glfwInit();
 
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
+	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
     GLFWwindow* window = glfwCreateWindow(800, 600, "Triangles", NULL, NULL);
 
     glfwMakeContextCurrent(window);

Находясь в директории проекта:

cd ../
patch -p0 < patch.patch
cd -

Надеюсь, ничего не напутал.

goto-vlad
()
Ответ на: комментарий от goto-vlad

Чтобы по-деревенски и по-быстрому проверить OpenGL программу на наличие runtime-ошибок, нужно запустить программу так:

MESA_DEBUG=context bin/01-triangles_d
Разумеется, нужен Меса-драйвер. А вообще лучше создавать отладочный контекст OpenGL.

goto-vlad
()

Новый Патч

diff -ur opengl_pg_9ed/CMakeLists.txt abc/CMakeLists.txt
--- opengl_pg_9ed/CMakeLists.txt	2018-11-27 20:06:06.000000000 +0200
+++ abc/CMakeLists.txt	2018-11-27 23:28:20.781854654 +0200
@@ -80,5 +80,6 @@
 include_directories( include )
 include_directories(lib/glfw/include)
 
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
 ADD_CUSTOM_TARGET(debug ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=Debug ${PROJECT_SOURCE_DIR})
 ADD_CUSTOM_TARGET(release ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=Release ${PROJECT_SOURCE_DIR})
diff -ur opengl_pg_9ed/include/vapp.h abc/include/vapp.h
--- opengl_pg_9ed/include/vapp.h	2018-11-26 16:28:51.000000000 +0200
+++ abc/include/vapp.h	2018-11-28 01:02:17.245959274 +0200
@@ -5,6 +5,7 @@
 
 #ifndef _WIN32
 #include <sys/time.h>
+#include <cstdio> // printf
 #endif
 
 class VermilionApplication
@@ -72,7 +73,7 @@
 };
 
 #ifdef _DEBUG
-//*
+#ifdef _WIN32
 #define DEBUG_OUTPUT_CALLBACK                                                   \
 void APIENTRY VermilionApplication::DebugOutputCallback(GLenum source,          \
                                                          GLenum type,           \
@@ -85,7 +86,7 @@
     OutputDebugStringA(message);                                                \
     OutputDebugStringA("\n");                                                   \
 }
-/*/
+#else
 #define DEBUG_OUTPUT_CALLBACK                                                   \
 void APIENTRY VermilionApplication::DebugOutputCallback(GLenum source,         \
                                                          GLenum type,           \
@@ -101,7 +102,7 @@
                           "SEVERITY(0x%04X), \"%s\"\n",\
            source, type, id, severity, message);\
 }
-*/
+#endif
 #else
 #define DEBUG_OUTPUT_CALLBACK
 #endif
diff -ur opengl_pg_9ed/src/01-triangles/01-triangles.cpp abc/src/01-triangles/01-triangles.cpp
--- opengl_pg_9ed/src/01-triangles/01-triangles.cpp	2016-09-18 22:30:22.000000000 +0300
+++ abc/src/01-triangles/01-triangles.cpp	2018-11-28 01:07:23.741858193 +0200
@@ -4,6 +4,7 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 
+#include <cstdio>
 #include "vgl.h"
 #include "LoadShaders.h"
 
@@ -21,6 +22,19 @@
 // init
 //
 
+#ifdef _DEBUG
+static void openglDebug(GLenum        source,
+                        GLenum        type,
+                        GLuint        id,
+                        GLenum        severity,
+                        GLsizei       length,
+                        const GLchar *message,
+                        const void   *userParam)
+{
+	fprintf(stderr, "OpenGL error: %s\n", message);
+}
+#endif
+
 void
 init( void )
 {
@@ -38,8 +52,8 @@
 
     ShaderInfo  shaders[] =
     {
-        { GL_VERTEX_SHADER, "media/shaders/triangles/triangles.vert" },
-        { GL_FRAGMENT_SHADER, "media/shaders/triangles/triangles.frag" },
+        { GL_VERTEX_SHADER, "bin/media/shaders/triangles/triangles.vert" },
+        { GL_FRAGMENT_SHADER, "bin/media/shaders/triangles/triangles.frag" },
         { GL_NONE, NULL }
     };
 
@@ -86,11 +100,21 @@
 {
     glfwInit();
 
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
+	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+#ifdef _DEBUG
+	glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
+#endif
     GLFWwindow* window = glfwCreateWindow(800, 600, "Triangles", NULL, NULL);
 
     glfwMakeContextCurrent(window);
     gl3wInit();
 
+#ifdef _DEBUG
+	glDebugMessageCallback(openglDebug, NULL);
+#endif
+
     init();
 
     while (!glfwWindowShouldClose(window))
goto-vlad
()
Ответ на: комментарий от the1

Low-level 3D API — это для framework/engine разрабов.

Согласен.
Иногда складывается такое чувство, что некоторые люди не понимают, что несколько графических API могут вполне себе сосуществовать, особенно если эти самые API преследуют в некоторой степени различные цели.

goto-vlad
()

Тоже кручу-верчу apple metal, нравится больше, чем opengl! Так что мой совет не терять время, и сразу учить godot, или unreal engine. Unreal можно юзать для всех консолей, godot, в основном, для десктопов и андроида, металл еще не прикрутили, и, видимо, не скоро прикрутят(

menangen ★★★★★
()
Ответ на: комментарий от menangen

Это они металл назвали? Использовать библиотеки через прокси, свитчи, свифты итд их же потом обвинят в краже фишки улучшения графики в играх с которых это начиналось. А, начиналось все с жта так что аппле (сосать) применить

anonymous
()
Ответ на: Новый Патч от goto-vlad

Спасибо добрый человек!

Только у меня не работает:

$ MESA_DEBUG=context bin/01-triangles_d
function is no-op
... ~20 such lines
function is no-op
Shader linking failed: ��S
function is no-op
... 5
function is no-op
Segmentation fault
Даже окно не показывает. Видюха AMD HD7750 старая что ли для GLv4.5?

the1 ★★
() автор топика

чёрное окно

Неполиткорректностью пахнет.

anonymous
()
Ответ на: комментарий от goto-vlad
OpenGL core profile version string: 4.3 (Core Profile) Mesa 13.0.6
OpenGL core profile shading language version string: 4.30

Посмотрел, на x.org написано что для этой видюхи (southern islands) поддержка 4.5, но со сноской (18): «LLVM 3.9 and Kernel 4.7 required». В репе Дебиана 9 есть llvm версии 3.8, 3.9 и 4.0. Kernel ок, 4.9. Это что получается, в Дебиане собирали месу со старой llvm? Есть попроще решение, кроме как обновить систему?

the1 ★★
() автор топика
Ответ на: комментарий от the1

Можно попробовать собрать Месу. Я использую, что-то вроде такого:

apt build-dep mesa
mkdir -p mesa/build/debug
cd mesa
git clone https://gitlab.freedesktop.org/mesa/mesa.git
cd mesa
git checkout 17.0
cd ../build/debug
../../mesa/autogen.sh --with-dri-drivers= --with-gallium-drivers=radeonsi --enable-debug

Переключил на ветку 17, так как последние версии требуют свежего libdrm, который тоже нужно было бы собирать отдельно.

Обычно у меня бывает несколько директорий в папке build: debug, profile, test и т. д. Небольшой скрипт glrun позволит нам переключаться между ними на лету, без необходимости предварительной установки их в систему.

#!/bin/bash

lib_dir="/home/user/path/to/mesa/build/$1/lib"

shift
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$lib_dir"
export LIBGL_DRIVERS_PATH="$lib_dir/gallium"
exec "$@"

С таким подходом пользователь может выбирать с какой именно версией OpenGL(предварительно им скомпилированной) запускать то или иное приложение:

glrun debug bin/01-triangles_d
или
glrun profile bin/01-triangles_d
Или создать алиас:
alias gldebug='MESA_DEBUG=context glrun debug'
gldebug bin/01-triangles_d

goto-vlad
()
Ответ на: комментарий от goto-vlad

Спасибо! Я это обязательно попробую, но попозже. +10 к скору (модераторы, можно попросить?), и +$100 к зарплате! :)

the1 ★★
() автор топика
Ответ на: комментарий от goto-vlad

Что-то не работает... Пробовал и 17 месу, и 18 (свеже-откомпилил libdrm). Однако:

MESA_DEBUG=context \
LD_LIBRARY_PATH="/mnt/win1/mesa/build/debug/lib" \
LIBGL_DRIVERS_PATH="/mnt/win1/mesa/build/debug/lib/gallium" \
glxinfo|less
...
OpenGL version string: 2.1 Mesa 18.0.5 (git-aba161e63a)
OpenGL shading language version string: 1.30
...
Конфигурил так (разное пробовал, ненужные ключи на всякий случай поставил как у Матта):
../../mesa/autogen.sh --with-dri-drivers= \
--with-gallium-drivers=radeonsi \
--enable-debug --enable-gallium-llvm \
--with-egl-platforms=x11,drm --enable-glx-tls  \
--prefix=/mnt/win1/local
Для 18-ой месы llvm поставил 4.0. Версия 2.1 конечно смущает, в ней дело? Эта 2.1 и для 17, и 18 месы. Как сделать (после этих попыток — уже вожделенную) 4.5? (дебианцы ведь сделали как-то 4.3 для моей видюхи).

Выхлоп triangles почти такой же как и раньше. Только вместо function — названия функций, типа glGetIntegerv, или glDebugMessageCallback (их там много таких).

the1 ★★
() автор топика
Ответ на: комментарий от goto-vlad

Думаю, может бросить это 9-е издание, с 4.5? Взять 8-е, там 4.3. И что даже важнее, стандарт должен быть проще для понимания (я нуб). Не знаю правда как пойдёт портирование примеров. Может помогут диффы-патчи для 9-го издания. Как думаете?

Если кому другим эта тема интересна, то через пол года, с новым Дебианом всё должно будет заработать само. Поскольку решение вы дали («Нужно явно указывать версию контекста OpenGL перед созданием. ... glfwWindowHint»)

the1 ★★
() автор топика
Ответ на: комментарий от ZenitharChampion

Да мне без разницы какого цвета книжка :) Мне примеры нужны. Линуксовые. Я ищу на гитхабе «opengl+programming+guide+9th», и вижу ерунду вобщем, аналогично для 8-го издания. Где эти примеры под линукс можно скачать? Лучше даже для 8-го издания.

the1 ★★
() автор топика
Ответ на: комментарий от the1

Найди базовый рабочий линуксовый вывод треугольника с core контекстом, а потом вызовы опенгл можно будить туда добавлять из вендовых туториалов, тк вся разница в создании контекста.

anonymous
()
Ответ на: комментарий от ZenitharChampion

Так, я извиняюсь, я сгоряча: там в поиске 8-е издание было оранжевым. А сейчас посмотрел повнимательнее, это совсем другая книжка, OpenGL Shading Language, и другие авторы. Спасибо за наводку. Посмотрю.

the1 ★★
() автор топика
Ответ на: комментарий от anonymous

Найди базовый рабочий ... тк вся разница в создании контекста

Спасибо! Жаль ты не помог этим советом челу, когда он долго выкорчёвывал винапи-шную GetTickCount (из 8-го издания). В других примерах (в конце той ветки) всё равно, и чёрные окна, и сегфолты. И видимо он это всё бросил. Где ты был 5 лет назад? :( Зато как с этим советом повезло сейчас мне!

the1 ★★
() автор топика
Ответ на: комментарий от the1

Если знаешь английский, то этот сайт очень и очень хорош https://learnopengl.com. Автор его, если я не ошибаюсь, из Guerilla Games. Начинается обучение там с OpenGL 3.3 core, и для начала этого достаточно с головой, постепенно переходя к более сложным алгоритмам, и к новым версиям OpenGL. Код по сравнению с примерами из этой темы более компактен и прост для понимания.

goto-vlad
()
Ответ на: комментарий от the1

Попробовал собрать 17.0 и при запуске glxinfo вывалилось предупреждение:

Mesa warning: couldn't open libtxc_dxtn.so, software DXTn compression/decompression unavailable
Раньше, я помню, эту библиотеку нужно было устанавливать вручную, чтобы сжатие текстур было доступно в OpenGL, но с недавних пор (с версии 17.3, возможно?) она была инкорпорирована в Месу.
Поэтому есть 2 варианта - либо попробовать установить эту библиотеку вручную (это самый простой вариант, если она есть в Дебиане, например, в Убунту 18 она уже не доступна), либо попробовать собрать 17.3.
Собрал 17.3, но и это не помогло - версия Opengl была по-прежнему 2.0. И тут я вспомнил, что нужно было указать еще один флаг --enable-texture-float. Для более новых версий этого делать уже не нужно, но когда я первый раз собирал Месу, то тоже недоумевал почему версия OpenGL такая маленькая. Извиняюсь, что не сразу не упомянул об этом флаге:
autogen.sh --with-dri-drivers= --with-gallium-drivers=radeonsi --enable-debug --enable-texture-float

Итого для Opengl 3.0+ кроме всего прочего нужна поддержка:

  • Сжатия текстур - libtxc_dxtn или Mesa 17.3+
  • float текстур - --enable-texture-float

Сейчас собрал Месу 17.3 с этими флагами и llvm4.0 и все заработало.

goto-vlad
()
Ответ на: комментарий от goto-vlad

--enable-texture-float

Да, так всё заработало, и версия 4.5 в glxinfo, и треугольники показаны! (я 18-ую месу взял) Спасибо!

Мне понравился (так, на первый взгляд) тот сайт, learnopengl.com . И то что есть скачиваемая книжка (потому что сайт из Москвы пришлось открыть через тор). Но главное — примеры, откомпилились без сучка и задоринки. Вот как-то сразу симпатичен мне этот автор, Joey de Vries! Я пожалуй тогда попробую именно его читать. Если понравится книжка — буду при случае его пиарить, вместо вендузятников этих.

the1 ★★
() автор топика
Ответ на: комментарий от the1

Только что проверил - начиная с версии 18.2 этот флаг уже не нужно указывать.

goto-vlad
()
Ответ на: комментарий от the1

Весь, целиком?

Да.

Пожалуйста ссылку на авторитетный источник.

Сайт khronos group смотри. Они Vulkan сделали для полной замены OpenGL. До этого он даже glNext назывался.

Quasar ★★★★★
()
Ответ на: комментарий от Quasar

OpenGL сейчас официально deprecated

Мусор, пурга, бред. 4.2

the1 ★★
() автор топика
Ответ на: комментарий от menangen

Оффтоп, извините.

Старая новость:

Apps built using OpenGL and OpenCL will continue to run in macOS 10.14, but these legacy technologies are deprecated in macOS 10.14.

Я вот не понимаю. Вот Майкрософт продолжает поддерживать (вроде? - не пользуюсь виндой) чуть ли не 30-летние досовские программы, хоть дос давно deprecated. Как в этом отношении ведёт себя Эппл? Пусть не развивать OpenGL ES (может своими проприетарными extensions, или ещё чем), но просто поддерживать его как системную либу - как долго будет? Как много лет пользователи смогут запускать мой OpenGL ES апп на новых устройствах и новых версиях (>=12) iOS?

(да, видел треды в толксах, и новости, но что-то не понял. резюмируй пожалуйста)

the1 ★★
() автор топика
Ответ на: комментарий от the1

Думаю, года 2-3. Без проблем. После 3 лет сможешь использовать и дальше, но, видимо, сам будешь париться с либами/дровами и прочим.

Возможно, они выкатят Metal в opensource, тогда всё будет по-интереснее. Альтернатива то какая - тока Vulkan.

Если поддерживать opengl лет 10 ещё, то никто и не будет чесаться, особенно, мелкие разрабы, которые экономят на разработке и привыкли юзать готовые либы, готовые туториалы, которые в 90% под старый opengl, и им пофиг на этот металл - вот таких и «вышибают с рынка», они также вышибают и x86(32-bit only) приложения - уже нельзя их запустить в новой Mojave, тока x64 приложухи.

menangen ★★★★★
()
Ответ на: комментарий от menangen

Почти ясно, спасибо.

Но неужели «вышибать с рынка мелких разрабов» - это политика Эппл? (пусть и неофициальная). Чем мелкие мешают? Наводняют Апстор своими аппами - хорошо. Только тем что пишут те 90% «legacy» тьюториалов, и этим весь фэн-шуй портят?

the1 ★★
() автор топика
Ответ на: комментарий от the1

У них же политика не тянуть легаси. Перекатились с процессоров power на x86, и старые программы там сейчас только через программный эмулятор работают, если вообще.

anonymous
()
Ответ на: комментарий от anonymous

Перекатились с процессоров power на x86...

Кстати очень любопытный пример поддержки Эппл. В октябре 2007 выпущена Intel-версия Mac OS X 10.5 Leopard. Т.е. PowerPC deprecated. 2 года спустя 10.6 Snow Leopard, с опциональным эмулятором Rosetta. Ещё через 2 года, июль 2011 - 10.7 Lion, где Rosetta убрана уже окончательно. И с тех пор совсем никак. Короче, меньше 4 лет, такой ключевой функционал! Я начинаю любить Майкрософт :)

the1 ★★
() автор топика
Ответ на: комментарий от the1

Из-за чего? Прогресс нужно мотивировать - вот они и мотивируют как могут. У них и так крупные проблемы с производительность и играми на платформе Mac.

menangen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.