Dlaczego zmienna "shaderProgram" wynosi 3 skoro mam tylko jeden shaderProgram?

0

Witam! Mam 2 klasy Shader i GLShader.
Wyglądają one następująco

class Shader
	{
	public:

		enum class Type
		{
			VERTEX,
			FRAGMENT
		};

		Shader() = default;
		~Shader() = default;

		virtual void Create() {}

		virtual const void* ShaderFromSource(const char* shader, Type type) const { return nullptr; }

		virtual void Link(const void* ids[], int count) const {}

		virtual void UseProgram() const {}
		virtual void UnuseProgram() const {}

		virtual void Free() {}

		template<typename T>
		T getShaderProgram() const { return (T)getProgram(); }

	private:
		inline virtual const void* getProgram() const { return nullptr; } 
	};
	class GLShader : public Shader
 	{
	public:
		GLShader() = default;
		~GLShader();

		void Create() override;
		
		const void* ShaderFromFile(const std::string& shader, Type type) const override;
		const void* ShaderFromSource(const char* shader, Type type) const override;

		void Link(const void* ids[], int count) const override;

		void UseProgram() const override;
		void UnuseProgram() const override;

		void Free() override;

	private:
		GLuint shaderProgram = 0;

		uint ConvertTypeToOpenGL(Type type) const;

		inline const void* getProgram() const override { return (const void*)shaderProgram; }
	};
 	void GLShader::Create() 	
	{
		shaderProgram = glCreateProgram();
	}

	const void* GLShader::ShaderFromSource(const char* shader, Type type) const
	{
		uint shaderID = glCreateShader(ConvertTypeToOpenGL(type));

		glCall(glShaderSource(shaderID, 1, &shader, NULL));
		glCall(glCompileShader(shaderID));

		ShaderCompiledError(shaderID);

		glCall(glAttachShader(shaderProgram, shaderID));

		return (const void*)shaderID;
	}

	void GLShader::Link(const void* ids[], int count) const
	{
		glCall(glLinkProgram(shaderProgram));

		for (int i = 0; i < count; ++i) {
			ShaderLinkedError((uint)ids[i]);
			glCall(glDetachShader(shaderProgram, (uint)ids[i]));
			glCall(glDeleteShader((uint)ids[i]));
		}
	}

        uint GLShader::ConvertTypeToOpenGL(Type type) const
	{
		switch (type) {
			case Type::VERTEX: return GL_VERTEX_SHADER; break;
			case Type::FRAGMENT: return GL_FRAGMENT_SHADER; break;
			case Type::GEOMETRY: return GL_GEOMETRY_SHADER; break;
		}
		return NULL;
	}

sposób użycia

// w jakies klasie
std::unique_ptr<Shader> shader;

//w jakies metodzie
	shader = std::make_unique<GLShader>();
		shader->Create();
		const void* shaders[2] = {
			shader->ShaderFromSource(VertexGLShader, Type::VERTEX),
			shader->ShaderFromSource(FragmentGLShader, ype::FRAGMENT)
		};
		shader->End(shaders, 2);

Kiedyś działało jak natura chciała (zwracało 1) więc myślałem, że wszystko jest fajno, ale dzisiaj jak dodawałem obsługę subroutins sprawdziłem sobie jaka wartość kryje się pod shaderProgram i wyszło, że jest to 3

Dlaczego jest zwracana wartość 3 skoro używany jest tylko jeden shader?

3

Gdzie w dokumentacji masz napisane, że wartość glCreateProgram() jest / powinna być deterministyczna, bądź że reprezentuje aktualnie utworzoną liczbę shaderów?

Tutaj wspominają jedynie, że:

glCreateProgram creates an empty program object and returns a non-zero value by which it can be referenced.

... czyli równie dobrze mogło by zwrócić 100, 666 czy 9182736465 ;-)

1

Po co w ogóle robisz to rzutowanie uint na (const void*)shaderID ?

1

Czy to dziedziczenie ma jakieś uzasadnienie czy jest tylko pustą formą?
Bo w tej chwili zastąpiłeś kilka wywołań GL wielokrotnie większą liczbą linii kodu.

0

private + virtual jest bezsensu
virtual oznacza: do nadpisania w klasie pochodnej
private oznacza: nikt nie ma do tego dostępu, w tym klasa pochodna.

ten szablon na getShaderProgram to chyba jakaś próba strzelenia sobie w kolano. Po co?

0

Żeby móc sobie wybrać z jakiego API chce korzystać. Jak później będzie DirectX albo vulkan, no to one chyba nie działają na uintach, więc w zależności od tego sobie wybiorę jaką wartość chcę zwrócić. Jeśli getShaderProgram<uint>() to znaczy, że opengl, jeśli getShaderProgram<JakaśTamzDX>() to znaczy, że DirectX, itd. Nie wiem czy to będzie działać, ale na razie o tym nie myślę za bardzo. Po prostu jest i mi nie przeszkadza. W przyszłości zobaczę, a najwyżej zmienię.

private + virtual jest bezsensu
virtual oznacza: do nadpisa w klasie pochodnej
private oznacza: nikt nie ma do tego dostępu, w tym klasa pochodna.

A tego nie zauważyłem, już zmienione.

1 użytkowników online, w tym zalogowanych: 0, gości: 1