Desde que comencé a aprender OpenGL, pensé que sería mejor escribir un pequeño framework C++ (para mí) para evitar las náuseas que el excesivo uso del código C-ish aparentemente está causando. :)
Como tengo la intención de seguir con Qt, el framework usa algunas clases de Qt.Diseñando una clase shader
Lo primero que realmente necesitaba era una forma fácil de usar sombreadores y programas. Aquí está mi idea de la clase shader.
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;
};
Debe ser bastante obvio lo que están haciendo las diferentes funciones. Cada uno llama a las rutinas relevantes de OpenGL, comprueba si hay errores y arroja excepciones en caso de falla. El constructor llama al glCreateShader
. Ahora la parte difícil. El destructor necesita llamar al glDeleteShader(handle);
pero en este caso tengo un dilema:
Opción 1: Desactivar asignación y copia. Esto tiene el lado positivo de evitar el recuento de referencias y el inconveniente de verse obligado a usar shared_pointers para ponerlos en vectores y circular en general.
Opción 2: Habilita el recuento de referencias. Esto tiene el lado obvio de habilitar la copia y, por lo tanto, almacenarla en contenedores (que necesitaré para luego pasar una gama de sombreadores a un programa). La desventaja es la siguiente:
Shader s1(GL_VERTEX_SHADER, QFile("MyVertexShader.vp"));
Shader s2(s1);
s2.Source(QFile("MyOtherVertexShader.vp"));
Como se puede ver, he cambiado la fuente de s1 a través s2, ya que comparten el mismo identificador de sombreado interno. Para ser honesto, no veo un gran problema aquí. Escribí la clase, así que sé que su semántica de copia es así y estoy de acuerdo. El problema es que no estoy seguro de que este tipo de diseño sea aceptable. Todo esto se puede lograr con los punteros compartidos Opción1 +, con la única diferencia de que no quiero tener un puntero compartido cada vez que creo un sombreador (no por razones de rendimiento, solo por conveniencia sintáctica).
Q1: Comente las opciones y, opcionalmente, toda la idea.
P2: Si tuviera que elegir la opción 2, tengo que aplicar a mí mismo o hay una clase de lista en aumento o Qt que podría derivar de o tener un miembro y me gustaría obtener una conteo de referencia gratis?
P3: ¿Está de acuerdo que hacer Shader
una clase abstracta y tener tres clases derivadas VertexShader
FragmentShader
, y GeometryShader
sería una exageración?
Si me debe hacer referencia a un marco de OpenGL existentes C++, eso es muy bueno (ya que no he encontrado realmente uno), pero que realmente debería haber una nota al margen de una respuesta a mis preguntas . También tenga en cuenta que he visto una clase QGLShader en algún lugar de los documentos, pero aparentemente no está presente en mi versión de Qt y tengo mis razones para evitar la actualización en este momento.
ACTUALIZACIÓN
Gracias por las respuestas. Finalmente decidí hacer inmutable mi clase de sombreado eliminando las funciones de origen. El sombreador se compila en la creación y no tiene funciones miembro no const. Por lo tanto, un simple conteo de referencias resuelve todos mis problemas a la vez.
Para obtener un marco C++ OpenGL, puede consultar (¿la?) Biblioteca de visualización. Ofrece un montón de cosas, desde los conceptos básicos hasta un algoritmo de geometría de cubos de marcha. Gran biblioteca, algo compleja pero muy completa. http://www.visualizationlibrary.org – ssube
@peachykeen: Estoy mirando a través de los documentos: ¡se ve impresionante! ¡Muchas gracias! –
El autor también es extremadamente receptivo y útil. Hay algunas rarezas, en particular con ventanas, pero si encuentra un error y lo informa, generalmente se soluciona dentro de la semana (en mi experiencia). – ssube