С тех пор, как я начал изучать OpenGL, я подумал, что я бы также написал небольшую платформу C ++ (для себя), чтобы избежать тошноты, которую явно вызывает чрезмерное использование кода C-ish.:)
Так как я собираюсь придерживаться Qt, фреймворк использует некоторые классы Qt.
Первое, что мне действительно нужно, это простой способ использовать шейдеры и программы.Вот мое представление о классе шейдеров.
class Shader
{
public:
//create a shader with no source code
explicit Shader(GLenum shaderType);
//create a shader with source code and compile it
Shader(GLenum shaderType, const QString& sourceCode);
//create a shader from source file and compile it
Shader(GLenum shaderType, QFile& sourceFile);
~Shader();
//change the source code and recompile
void Source(QFile& sourceFile);
void Source(const QString& sourceCode);
GLuint get() const; //get the handle
private:
//common part for creation in different constructors
void createShader(GLenum shaderType);
//compile
void compile();
private:
GLuint handle;
};
Должно быть совершенно очевидно, что делают разные функции.Каждый вызывает соответствующие подпрограммы OpenGL, проверяет ошибки и выдает исключения в случае любого сбоя.Конструктор вызывает glCreateShader
.Теперь сложная часть.Деструктору нужно вызвать glDeleteShader(handle);
, но в этом случае у меня возникает дилемма:
Опция 1: Отключить назначение и копирование.Это имеет преимущество, заключающееся в том, что необходимо избегать подсчета ссылок и недостатка в том, чтобы принудительно использовать shared_pointers для помещения их в векторы и общего обхода.
Опция 2: Включить подсчет ссылок.Это имеет очевидный положительный момент: оно позволяет копировать и, следовательно, хранить в контейнерах (что мне понадобится позже для передачи ряда шейдеров в программу).Недостатком является следующее:
Shader s1(GL_VERTEX_SHADER, QFile("MyVertexShader.vp"));
Shader s2(s1);
s2.Source(QFile("MyOtherVertexShader.vp"));
Как видите, я изменил источник s1 через s2, потому что они используют один и тот же внутренний дескриптор шейдера.Если честно, я не вижу здесь большой проблемы.Я написал класс, так что я знаю, что его семантика копирования такова, и я в порядке.Проблема в том, что я не уверен, что такой дизайн когда-либо приемлем.Все это может быть достигнуто с помощью общих указателей Option1 +, с той лишь разницей, что я не хочу иметь общий указатель каждый раз, когда создаю шейдер (не из соображений производительности - просто для удобства синтаксиса).
Q1: Пожалуйста, прокомментируйте варианты и, если необходимо, всю идею. 1
Q2: Если бы я выбрал вариант 2, я должен реализовать это сам или есть готовый класс в boost или Qt, от которого я мог бы получить или иметь член, и я бы получил бесплатный подсчет ссылок?
Q3: Согласны ли вычто сделать Shader
абстрактным классом и иметь три производных класса VertexShader
, FragmentShader
и GeometryShader
было бы излишним?
1 Если вы хотите отослать меня к существующей платформе C ++ OpenGL, это очень хорошо (так как я на самом деле ее не нашел)но это действительно должно быть побочным примечанием, чем ответом на мои вопросы.Также обратите внимание, что я видел класс QGLShader где-то в документации, но он, по-видимому, отсутствует в моей версии Qt, и у меня есть причины не обновляться прямо сейчас.
UPDATE
Спасибо за ответы.В конце концов я решил сделать свой класс шейдеров неизменным, удалив исходные функции.Шейдер компилируется при создании и не имеет неконстантных функций-членов.Таким образом, простой подсчет ссылок решает все мои проблемы одновременно.