Здравствуйте, как давно меня здесь не было... Наверное не было ещё такой темы ради которой стоило бы Вас, дорогие читатели моих опусов, беспокоить.
Решил я познакомится поближе с OpenGL. Единственный доступный инструмент для написания программ и их компиляции, оказался NetBeans IDE 8.2, установочный файл netbeans-8.2-windows.exe размером 225 472 кб. и jdk-8u144-windows-x64 установочный файл jdk-8u144-windows-x64.exe размером 202 523 кб.
Размеры файлов и названия пишу точно, поскольку их размер зависит от их комплектации, а комплектация, насколько могу быть точным от конечной функциональности. После установки получаем вот такой инструмент разработки:
Использую компилятор CLang. Все инструменты скачаны при помощи утилиты MSYS которую можно скачать по ссылке https://www.msys2.org. Упор был сделан на инструменты UCRT64. MinGW не пользуюсь совсем.
Об инструментах поговорили и перейдём к OpenGL.
Проблема состояла в том, как тот код, который из интернета, запихать в конструкцию из GLFW + GLAD и получить OpenGL графику с шейдерами.
Первая проблема была с тем, как инициализировать GLAD? С glad.h проблем не было, а вот с glad.c возникли. Поиски решения оказались успешными и её реализацию вы увидите в коде, который я приведу ниже.
Вторая проблема в том, что часто можно увидеть конструкцию GLFW+GLEW, но я от неё отказался поскольку хотел реализовать конструкцию GLFW+GLAD.
Третья проблема, что везде в "туториалах" даётся множество примеров, которые отвязаны от цельного кода, куда писать, как встраивать код в программу, где искать дополнительные файлы, не понятно.
Я новичок в программировании, поэтому пишу с позиции именно новичка, так что не нападайте :)
main.cpp
//#define GLAD_GL_IMPLEMENTATION
#include <GLAD/glad Core v.3.3/include/glad/glad.h>
#include <GLAD/glad Core v.3.3/src/glad.c>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
//GLFWwindow *window;
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GLFW_TRUE);
switch (key)
{
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(window, GLFW_TRUE);
break;
/* case GLFW_KEY_SPACE:
cur_icon_color = (cur_icon_color + 1) % 5;
set_icon(window, cur_icon_color);
break;
case GLFW_KEY_X:
glfwSetWindowIcon(window, 0, NULL);
break;*/
}
}
void triang()
{
GLuint vbo = 0;
GLuint vao = 0;
float points[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
const char* vertex_shader =
"#version 400\n"
"in vec3 vp;"
"void main() {"
" gl_Position = vec4(vp, 1.0);"
"}";
const char* fragment_shader =
"#version 400\n"
"out vec4 frag_colour;"
"void main() {"
" frag_colour = vec4(0.2, 0.0, 0.5, 1.0);"
"}";
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
GLuint shader_programme = glCreateProgram();
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
glUseProgram(shader_programme);
glBindVertexArray(vao);
// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays(GL_TRIANGLES, 0, 3);
// update other events like input handling
}
// Когда пользователь меняет размер окна, окно просмотра также должно быть скорректировано, требуя функцию обратного вызова
void framebuffer_size_callback(GLFWwindow* window,int width,int height){
// Первые два параметра функции glViewport управляют положением нижнего левого угла окна, а третий и четвертый параметры контролируют ширину и высоту окна рендеринга
glfwSetKeyCallback(window, key_callback);
glfwGetFramebufferSize(window, &width, &height);
glViewport(0,0,width,height);
}
// Объявляем функцию, чтобы определить, нажата ли конкретная клавиша
void processInput(GLFWwindow * window){
// Проверка, нажимает ли пользователь клавишу возврата (Esc) (если не нажата, glfwGetKey вернет GLFW_RELEASE, если нажата, GLFW_PRESS)
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
int main(int argc, char** argv)
{ // Инициализация GLFW
glfwInit();
// Установить номер основной версии OpenGL (Major) и номер вспомогательной версии (Minor) в 3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// Использование режима ядра (Core-profile)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Если это система MacOS, вам понадобится следующая строка кода для работы конфигурации
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Создать объект окна
GLFWwindow * window = glfwCreateWindow(800, 600, "GLFW + GLAD", NULL, NULL);
if (window == NULL){
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
// Уведомить GLFW, чтобы установить контекст нашего окна в качестве основного контекста текущего потока
glfwMakeContextCurrent(window);
// GLAD используется для управления указателем функции OpenGL, нам нужно инициализировать GLAD перед вызовом любой функции OpenGL
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
cout << "Failed to initialize GLAD" << endl;
return -1;
}
// Зарегистрируем определенную функцию обратного вызова и сообщаем GLFW вызывать эту функцию при каждом изменении размера окна
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// Визуализация цикла
while (!glfwWindowShouldClose(window)) {
// Проверить, нажата ли конкретная клавиша, и обрабатывать ее каждый кадр
processInput(window);
// функция glClearColor - это функция установки состояния, используемая для установки цвета, используемого для очистки экрана
glClearColor(0.2f,0.3f,0.3f,1.0f);
// Функция glClear - это функция использования состояния, которая использует текущее состояние для очистки экрана с указанным цветом
glClear(GL_COLOR_BUFFER_BIT);
//triang(); - запускаем отрисовку треугольника. Работает именно в этом месте!
triang();
// Функция glfwSwapBuffers будет обмениваться цветовыми буферами
glfwSwapBuffers(window);
// Функция glfwPollEvents проверяет, запущены ли какие-либо события
glfwPollEvents();
}
// Освободить все ресурсы, выделенные ранее
glfwTerminate();
return 0;
}
результат работы программы:
В этом коде я собрал много разных идей, здесь нет ни чего моего, кроме компоновки кода.
Да. Программа не ахти какая, но как видно из примера, работать в этой конструкции можно и вполне себе успешно. Можно выдернуть код, удалив всего одну функцию не разрушив целость структуры и так же вставить другой код. Какие перспективы у данной реализации? Наверно ограничиваются только фантазией.
Всем творческих успехов.
Комментарии (39)
lea
09.07.2023 16:31+4М-м-м, а шейдеры точно нужно компилить каждый фрейм?
VladimirIM12 Автор
09.07.2023 16:31-3Каждый кадр перерисовывается и текстуры обновляются.
lymes
09.07.2023 16:31+2Комментатор выше прав, компилировать шейдеры для каждого фрейма не нужно. Статья ни о чем, да еще и с орфографическими ошибками.
VladimirIM12 Автор
09.07.2023 16:31-6это когда хочется отметится, а сказать нечего, делают замечания об орфографических ошибках.
Компилировать шейдеры для каждого фрейма действительно не нужно. Программа целиком компилируется всего один раз, а при исполнении картинка перерисовывается каждую смену кадра.
Сам код действительно ценности не представляет. Как ранее в тексте было замечено ценность имеет только подход к компоновке кода при использовании определённого набора инструментов.bodyawm
09.07.2023 16:31+5Зря спорите, комментатор прав.
triang() вызывается каждый кадр, соотвественно каждый кадр аллокейтятся новые хендлы как для программы, так и для вершинного/фрагментного шейдера. Кроме того, каждый кадр происходит аллокейт вершинного буфера, что несет за собой утечку памяти и в целом это плохо для статической геометрии. Правильнее будет так:
void PreloadResources() { GLuint vs = glCreateShader(GL_VERTEX_SHADER); GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); GLuint shader_programme = glCreateProgram(); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glShaderSource(vs, 1, &vertex_shader, NULL); glCompileShader(vs); glShaderSource(fs, 1, &fragment_shader, NULL); glCompileShader(fs); glAttachShader(shader_programme, fs); glAttachShader(shader_programme, vs); glLinkProgram(shader_programme); } ... void DrawFrame() { glUseProgram(shader_programme); // Биндим юниформы, аттачим текстуры и.т.п glDrawArrays(...); }
VladimirIM12 Автор
09.07.2023 16:31-1Я как бы упомянул, что новичок в этом деле, кода моего как такового здесь нет, только сборка, цель которой была запустить конструкцию GLFW + GLAD = OpenGL графика с шейдерами, чего ранее ни где в инете не встречал.
Каким образом далее такая конструкция будет работать и жизнеспособна ли покажет время.
За замечание спасибо, но желательно было бы вписать ваши поправки в представленный ранее код, что бы любой читатель мог его целиком взять и у себя запустить.
Тема ведь для начинающих.bodyawm
09.07.2023 16:31+2Все норм) я просто подсказку дал.
VladimirIM12 Автор
09.07.2023 16:31Можно положить фрагменты в разные функции и вынимать их только когда необходимо, но это уже разные зоны видимости. К фрагментам нужно уже будет обращаться через обращение к функции где оно лежит, а у меня по моему уровню знаний с этим пока проблемы. Так что пока всё в куче. Главное, что я на первом этапе реализовал задуманное.
lea
09.07.2023 16:31+1Ну почему же ни о чем) Треугольник выводится, это уже успех.
Может кто-нибудь опытный подкинет список хорошей литературы по opengl в комментах?
lymes
09.07.2023 16:31ага. а еще «ценность компоновки» ????
VladimirIM12 Автор
09.07.2023 16:31а Вы покопайтесь в инете и найдите подобное, прежде чем ёрничать.
lymes
09.07.2023 16:31+3Послушайте, я бы не ёрничал, если бы в свое время не изучал OpenGL. В инете есть очень много обучающего материала, вот, погуглил https://ogldev.org например. Но вы даже не удосужились понять как это работает и при этом позволяете себе спорить с комментаторами, которые указывают вам на самые вопиющие ошибки. Это вместо того, чтобы сказать спасибо.
Ну и как тут не поёрничать над тем, что вы кое-как слепленный код из интернета называете годной компоновкой? Извините если что.
VladimirIM12 Автор
09.07.2023 16:31-3Подобное - это именно совместное использование GLFW+GLAD
Спасибо за ёрничество?
Вот сейчас да спасибо за ссылку поизучаю.
В таком виде, на самом деле, информации пруд пруди - именно в таком виде.
Я же написал в само начале, что мой уровень НАЧИНАЮЩИЙ Вы даже не удосужились прочитать хотя текста минимумЯ эту информацию уже месяц изучаю только с той стороны - куда и что втыкать.
Там приведены чисто функции и что они делают. Вот вам набор функций для создания окна, делают они то-то и то-то. Всё! и так везде.
Если есть код файла целиком, то в нём обязательно будет ссылка на фал, которого у тебя нет и у тебя этот код работать не будет.
Весь процесс обучения - собираешь мозаику из миллиона фрагментов, у которых есть ещё и версии.
Ну, за месяц, можно сказать, я не плохо управился.
VladimirIM12 Автор
09.07.2023 16:31-3И да, если изучали OpenGL и такой знаток, то привели бы в пример свой вариант кода как правильный. Зачем забивать пространство пустыми репликами, просто обозначить своё присутствие?
bodyawm
09.07.2023 16:31+1Лучшая литература именно по принципу работы GAPI, это спека OGL 1.0 и MSDN доки о DX11. Первая спека благодаря стейтовой направленности поможет понять, как под капотом работают такие вещи, как освещение, трансформации, материалы, комбайнеры и другие атрибуты ффп, а благодаря DX10/DX11 относительно легко понять, как происходит менеджмент ресурсов под капотом и как работает современный пайплайн (у огл функционал дх10+ реализован криво, но это мое имхо).
VladimirIM12 Автор
09.07.2023 16:31Если бы кто дал наводку на код, который показывает как создаются прототипы объектов, а затем на основе прототипа можно создать несколько других объектов, допустим другого цвета, размеров и так далее, что лучше, чем каждый раз создавать каждый объект заново.
Хотя бы как Вы показали на примере, что одну функцию можно разбить на фрагменты и тем самым улучшить программу.bodyawm
09.07.2023 16:31+1Это уже ближе к системе сущностей, нежели к рендереру. См. исходники Half-Life, особенно первой, там концепция Entity подаётся хорошо. Или см. исходники моей игры, которую я реализовав в цикле из двух статей про разработку игр на Windows Mobile
monobogdan/spaceshooterwm (github.com)VladimirIM12 Автор
09.07.2023 16:31код на скриптах. Я вообще не понимаю как это может работать. Для меня информации ноль :)
отрендерить можно объект реализованный из прототипа.
Прототип это манекен, на который можно одеть любую одежду и сфотографировать(отрендерить). Таким образом мы получаем толпу.bodyawm
09.07.2023 16:31+1Вы видимо про меши (модели) говорите. См. Assimp, ну и в коде выше есть примитивный загрузчик md2.
VladimirIM12 Автор
09.07.2023 16:31Есть вариант загрузки готового 3D объекта как прототипа. Есть вариант его непосредственное создание кодом, только без текстур. Вероятно это и есть Меши, я не очень в этом пока разбираюсь. Как например создать модель Солнечной системы. Тут либо создавать 10 сфер отдельно, либо создать прототип одной сферы и затем для каждой планеты задать параметры и текстуры и это будет уже самостоятельный объект. Из той информации, которой на данное время владею владею, мне кажется что эту тему мне стоило бы изучить. На верном я пути или нет время покажет.
Deosis
09.07.2023 16:31+2Для совсем начинающих подойдет https://learnopengl.com/
На хабре даже перевод есть.
VladimirIM12 Автор
09.07.2023 16:31-2https://translate.yandex.ru
Вставляешь блок текста и получаешь качественный перевод. Аналог Гугл переводчика.
В прочем нужен код реализации, общая теория как бы понятна.
VladimirIM12 Автор
09.07.2023 16:31Спасибо за ссылку. Займусь освоением раздела https://learnopengl.com/Model-Loading/Mesh
Только сначала нужно будет освоить использование инструмента GLM
Всего скорее придётся компилировать DLL библиотеку. Вроде как есть такая рекомендация из официального источника.
Не знаю точно, но если у кого есть опыт использования GLM не помешали бы рекомендации.bodyawm
09.07.2023 16:31+2Зачем? GLM это header-библиотека, её можно и нужно встраивать в основной бинарник.
a-tk
09.07.2023 16:31+1Казалось бы, причём здесь скриншоты IDE?
VladimirIM12 Автор
09.07.2023 16:31-2Для начала показал инструмент на котором всё это делается. Какие компиляторы используются, их версии.
Затем код, который этими инструментами собирается в программу, какой версии и это всё работает.
Ну, написал бы я код, а чем собирал, в какой среде, утаил. Вы перенесли к себе и у вас он не работает. И Вы начинаете нервничать, задавать вопросы.
Тут же всё ясно.
COKPOWEHEU
09.07.2023 16:31+2запихать в конструкцию из GLFW + GLAD
Было бы неплохо в двух словах описать что такое GLFW, что такое GLAD и почему выбраны именно они.
#include <GLAD/glad Core v.3.3/src/glad.c>
Что это делает в исходном коде?
using namespace std;
Плохая идея
void triang() glCreateShader(GL_VERTEX_SHADER); glCreateShader(GL_FRAGMENT_SHADER); glGenBuffers(1, &vbo); glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW); glGenVertexArrays(1, &vao);
Совсем плохая идея. Вы на каждом кадре гоняете между CPU и GPU кучу данных, которые вообще не меняются. Вы каждый раз выделяете буферы, но не освобождаете их. Про проверку успешности выделения и говорить нечего.
В общем, недостаточно вы разобрались в теме чтобы кого-то учить.
VladimirIM12 Автор
09.07.2023 16:31-2// GLAD используется для управления указателем функции OpenGL, нам нужно инициализировать GLAD перед вызовом любой функции OpenGL gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
Если вы внимательно смотрели код программы там этот комментарий есть.
GLFW - инструмент для создания окна и управления ходом выполнения программы.
Каждого комментатора приходится отсылать к исходному тексту, в котором чёрным по белому написано и то. что - "Я новичёк! поэтому не нападайте"
Какой новичок будет кого-то учить? - это же глупо...
Вы не первый сообщаете, что прога впустую тратит ресурсы, но ни кто так и не удосужился поправить код.
На словах все умные, а как дела касается ни кого нету...
Ну так покажите правильный код если видите ошибку.
Не я один эту прогу прогонять буду, закладок уже набралось достаточно, все кого эта тема заинтересовала будут вам признательны.
А если предложить нечего, зачем в пустоту кричать и возмущаться?Покажи правильный, по своему разумению код, а мы все посмотрим кто это такой умный так сильно возмущается.
ColdPhoenix
09.07.2023 16:31+3Вы не первый сообщаете, что прога впустую тратит ресурсы, но ни кто так и не удосужился поправить код.
Серьезно? люди за вас должны поправить вашу статью?
Покажи правильный, по своему разумению код, а мы все посмотрим кто это такой умный так сильно возмущается.
Да пожалуйста.
На всякий случай, оконная библиотека в данном случае не имеет значений к самому коду прорисовки.
VladimirIM12 Автор
09.07.2023 16:31-2За пример конечно спасибо. Ну очень понравилось решение.
С другой стороны, для себя решил больше не писать на Habr(e) ни чего.
Получается, что не ты делишься чем-то с другими, а забредших случайно на публикацию обязываешь напрягаться.... Сидишь и обтекаешь читая недовольства в свой адрес. А оно мне надо?
Публикацию не прячу только на том основании, что читатели сделали закладки, а значит кому тема интересна и у них есть надежда на конструктивный диалог и естественно на материал, который возможно получит своё развитие и продолжение. Допустим работа с GLM mesh в этой же среде GLFW+GLAD.
Но этого не будет. Только потому, что ни кто ни за кого ни чего писать и править не собирается.Зачем за кого-то? А совместными усилиями достичь определённого результата проще или сложнее? что бы потом всем пользоваться результатом совместного труда?
Ну да ладно.
Я больше сюда ни ногой. Решено. Аппетита нет.
COKPOWEHEU
09.07.2023 16:31+2Если вы внимательно смотрели код программы там этот комментарий есть.
Еще не хватало в вашем говнокоде копаться.
GLAD используется для управления указателем функции OpenGL, нам нужно инициализировать GLAD перед вызовом любой функции OpenGL
Ни в одном примере по OpenGL я glad не видел. Для OGL1 вообще ничего не нужно кроме создания окна, OCL2 у меня тоже без извращений запускался, но вообще часто подключают glew. Чем примечателен glad?
GLFW — инструмент для создания окна и управления ходом выполнения программы.
Это стоило разместить где-нибудь в начале статьи по принципу справочной информации. Помимо GLFW есть еще GLUT, SDL, SFML — стоило также написать почему вы остановились именно на этом. Пусть даже мотивацией будет "захотелось потыкать палочкой".
Каждого комментатора приходится отсылать к исходному тексту
И какие вы из этого сделали выводы?
Какой новичок будет кого-то учить? — это же глупо...
Вы меня спрашиваете зачем вы написали сюда статью?! Обычно если человек публикует техническую статью, он хочет что-то рассказать окружающим, чему-то научить, поделиться информацией.
Вы не первый сообщаете, что прога впустую тратит ресурсы, но ни кто так и не удосужился поправить код.
А что, вам самому это не очевидно? Ну как минимум вынести инициализацию в функцию инициализации и вызвать ее единственный раз при старте программы.
Покажи правильный, по своему разумению код, а мы все посмотрим кто это такой умный так сильно возмущается.
Список моих публикаций доступен для просмотра и комментирования всем желающим. О тех вещах, в которых я считаю себя достаточно компетентным, я рассказываю.
Не я один эту прогу прогонять буду, закладок уже набралось достаточно, все кого эта тема заинтересовала будут вам признательны.
Нет, в области шейдерного OpenGL моих знаний недостаточно. Недавно пришлось спрашивать на форуме как же проводить на шейдерах вычисления. И даже по готовому коду не все стало понятно. Поэтому кого-то этому учить я не возьмусь.
А если предложить нечего, зачем в пустоту кричать и возмущаться?
Отчего же. Я бы предложил вам спрятать статью в черновики и основательно над ней посидеть. Исправить грубые ошибки в коде, поэкспериментировать, ознакомиться с чужим кодом. Учесть советы из комментариев (вот просто отключить эмоциональную реакцию и оценить каждый пост на то, какую полезную информацию из него можно извлечь). Хорошо бы придумать что-то, чем ваша статья будет выделяться из десятков других хелло-ворлдов. Сформулировать основную мысль статьи.
Потом дать ей отлежаться день-два, перечитать и, если сочтете достойной, уже выкладывать.
VladimirIM12 Автор
09.07.2023 16:31-4Я так понял - нечего сказать, кроме как оценить статью как говно и код как говнокод, Полагаю, что в этом и есть твоя компетентность.
Отчего же. Я бы предложил вам спрятать статью в черновики и основательно над ней посидеть. Исправить грубые ошибки в коде, поэкспериментировать, ознакомиться с чужим кодом. Учесть советы из комментариев (вот просто отключить эмоциональную реакцию и оценить каждый пост на то, какую полезную информацию из него можно извлечь). Хорошо бы придумать что-то, чем ваша статья будет выделяться из десятков других хелло-ворлдов. Сформулировать основную мысль статьи.
Ты знаешь сколько я в инете копался, что бы хоть что-то в GL понять? Сколько перечитал статей, сколько текстов перевёл. Ни где не встречал такой конструкции, до которой кстати докопался своими мозгами без подсказок. А когда у меня получилось, решил поделится с начинающими свой путь в OpenGL.
Советовать и я горазд, но не срать в комментариях.
Как, скажи мне дружище получить полезную инфу о том, чего достиг и перспективу куда двигаться? - Конечно от того кто знакомится с твоим достижением, которого ты достиг. Да криво. Но уж как умею на своём уровне.
Код = Говнокод, подскажи, если дока. Нет? Промолчи за умного сойдёшьЯ новичок в программировании, поэтому пишу с позиции именно новичка, так что не нападайте :)
Вот эту строку текста перед кодом читал?
Вы меня спрашиваете зачем вы написали сюда статью?! Обычно если человек публикует техническую статью, он хочет что-то рассказать окружающим, чему-то научить, поделиться информацией.
Всё верно, именно поделится, а не учить.
Может вы этого не знали и вдруг спохватились.Зацепило что ли?
Струны Эго задело?
COKPOWEHEU
09.07.2023 16:31+2Я так понял — нечего сказать, кроме как оценить статью как говно и код как говнокод, Полагаю, что в этом и есть твоя компетентность.
Не угадали. Попробуйте не угадывать, а подумать.
Ты знаешь сколько я в инете копался, что бы хоть что-то в GL понять?
Судя по результату, не более нескольких часов. Слишком мало чтобы кого-то чему-то учить.
Ни где не встречал такой конструкции, до которой кстати докопался своими мозгами без подсказок.
"такой" это какой? Комбинации glwf с какой-то экзотикой? Ну так если опыта нет, стоило начать с чего-то более распространенного. Тот же sdl+glew например.
А когда у меня получилось, решил поделится с начинающими свой путь в OpenGL.
На что получили конструктивную критику. Но вместо того чтобы ее воспринять и сделать выводы, вы начали срач.
Как, скажи мне дружище получить полезную инфу о том, чего достиг и перспективу куда двигаться?
Сначала ознакомиться с чужими достижениями и сравнить можете ли вы к ним что-то добавить. Тот же курс learnopengl, который тут на Хабре переведен. Думаете, вы хоть немного приблизились к его качеству?
Код = Говнокод, подскажи, если дока. Нет? Промолчи за умного сойдёшь
А вы комментарии прочитать не пробовали? Там вам кучу подсказок дали, и я в том числе.
Я новичок в программировании, поэтому пишу с позиции именно новичка, так что не нападайте :)
Вот эту строку текста перед кодом читал?Вы написали учебную статью, в которой допустили грубейшие ошибки. В том виде, который сейчас, она просто вредна для окружающих. Вам на это указали. И оправдания "это мой первый код" никого не волнуют. Если не можете показать "как надо", лучше вообще не показывайте. Для "первого кода" есть форумы, где вам именно что подскажут что читать и как исправлять.
Но раз вы позиционируете свой материал как обучающий — получаете соответствующее отношение.
Всё верно, именно поделится, а не учить. Может вы этого не знали и вдруг спохватились.
Чего не знал? Еще раз: вы написали статью и выложили код как законченный продукт. "смотрите как это можно сделать". Если бы вы сперва задали вопрос на форуме вроде "я тут изучаю связку glad + glfw, пока получается вот так, что можно улучшить?", отношение было бы именно как к новичку. Но вы полезли с детским подходом на взрослый ресурс.
Зацепило что ли?
Пытаюсь вам помочь. Но это, похоже, бесполезно. Вместо того чтобы воспринимать конструктивную критику и развиваться, вы пытаетесь тут изобразить непризнанного гения.
Зачем за кого-то? А совместными усилиями достичь определённого результата проще или сложнее? что бы потом всем пользоваться результатом совместного труда?
В таком случае вы ресурсом ошиблись. Формат публикации подразумевает законченный продукт. Даже если кого-то эта тема заинтересует, ему что, в комментариях куски кода размещать?! Не говоря уж о том, что если кого-то заинтересует эта тема, воспользоваться вашей статьей он все равно не сможет из-за наличия грубейших ошибок. Да и написать подобный хелло-ворлд с нуля будет не сложнее.
Публикацию не прячу только на том основании, что читатели сделали закладки, а значит кому тема интересна
Не волнуйтесь, те 9 человек не слишком огорчатся если вы все-таки уберете статью на доработку и доведете ее до достойного состояния.
VladimirIM12 Автор
09.07.2023 16:31-3да и нас рать на ваше посредственное мнение. Вместо конструктивного диалога сплошные нравоучения. А то, что предоставили код, так это вам пришлось переступить через своё эго. Сначала закидали говном потом конфетку чтоб не плакал:) мне что после этого реверансы перед вами растанцовывать? то же мне, одолжение сделали :))
Не волнуйтесь, те 9 человек не слишком огорчатся если вы все-таки уберете статью на доработку и доведете ее до достойного состояния.
Это уже высшая степень эгоцентризма решать за других как им быть. ни как вы возомнили себя вершителем судеб?
Правка статьи возможна только по мере развития темы. Пока тема развития не получила дополнять, либо изменять содержимое публикации, не имеет смысла.COKPOWEHEU
09.07.2023 16:31+3Сначала закидали говном потом конфетку чтоб не плакал:)
Так вот какого уровня у вас ценности. Если конструктивно и подробно расписали как улучшить код, это называется "закидали говном". А чтобы вы не плакали, достаточно дать конфетку.
мне что после этого реверансы перед вами растанцовывать?
Какое мне дело до ваших ужимок? Статью свою лучше исправьте, чтобы она хоть немного пользы принести могла.
Правка статьи возможна только по мере развития темы.
Развитие темы у вас началось сразу с момента публикации: вам указали ошибки, указали литературу, осталось только изучить материал и переделать по-нормальному.
Это уже высшая степень эгоцентризма решать за других как им быть. ни как вы возомнили себя вершителем судеб?
Слишком примитивная манипуляция, пытайтесь тоньше.
bodyawm
Ну шо пацаны, OGL vs DX9? Какое API более убогое? :)