1#include "opengl_sl_program.h"
2#include "opengl_sl.h"
3#include <base/system.h>
4
5#include <base/detect.h>
6
7#if defined(BACKEND_AS_OPENGL_ES) || !defined(CONF_BACKEND_OPENGL_ES)
8
9#ifndef BACKEND_AS_OPENGL_ES
10#include <GL/glew.h>
11#else
12#include <GLES3/gl3.h>
13#endif
14
15void CGLSLProgram::CreateProgram()
16{
17 m_ProgramId = glCreateProgram();
18}
19
20void CGLSLProgram::DeleteProgram()
21{
22 if(!m_IsLinked)
23 return;
24 m_IsLinked = false;
25 glDeleteProgram(m_ProgramId);
26}
27
28bool CGLSLProgram::AddShader(CGLSL *pShader) const
29{
30 if(pShader->IsLoaded())
31 {
32 glAttachShader(m_ProgramId, pShader->GetShaderId());
33 return true;
34 }
35 return false;
36}
37
38void CGLSLProgram::DetachShader(CGLSL *pShader) const
39{
40 if(pShader->IsLoaded())
41 {
42 DetachShaderById(ShaderId: pShader->GetShaderId());
43 }
44}
45
46void CGLSLProgram::DetachShaderById(TWGLuint ShaderId) const
47{
48 glDetachShader(m_ProgramId, ShaderId);
49}
50
51void CGLSLProgram::LinkProgram()
52{
53 glLinkProgram(m_ProgramId);
54 int LinkStatus;
55 glGetProgramiv(m_ProgramId, GL_LINK_STATUS, &LinkStatus);
56 m_IsLinked = LinkStatus == GL_TRUE;
57 if(!m_IsLinked)
58 {
59 char aInfoLog[1024];
60 char aFinalMessage[1536];
61 int LogLength;
62 glGetProgramInfoLog(m_ProgramId, 1024, &LogLength, aInfoLog);
63 str_format(buffer: aFinalMessage, buffer_size: sizeof(aFinalMessage), format: "Error! Shader program wasn't linked! The linker returned:\n\n%s", aInfoLog);
64 dbg_msg(sys: "glslprogram", fmt: "%s", aFinalMessage);
65 }
66
67 //detach all shaders attached to this program
68 DetachAllShaders();
69}
70
71void CGLSLProgram::DetachAllShaders() const
72{
73 TWGLuint aShaders[100];
74 GLsizei ReturnedCount = 0;
75 while(true)
76 {
77 glGetAttachedShaders(m_ProgramId, 100, &ReturnedCount, aShaders);
78
79 if(ReturnedCount > 0)
80 {
81 for(GLsizei i = 0; i < ReturnedCount; ++i)
82 {
83 DetachShaderById(ShaderId: aShaders[i]);
84 }
85 }
86
87 if(ReturnedCount < 100)
88 break;
89 }
90}
91
92void CGLSLProgram::SetUniformVec4(int Loc, int Count, const float *pValues)
93{
94 glUniform4fv(Loc, Count, pValues);
95}
96
97void CGLSLProgram::SetUniformVec2(int Loc, int Count, const float *pValues)
98{
99 glUniform2fv(Loc, Count, pValues);
100}
101
102void CGLSLProgram::SetUniform(int Loc, int Count, const float *pValues)
103{
104 glUniform1fv(Loc, Count, pValues);
105}
106
107void CGLSLProgram::SetUniform(int Loc, const int Value)
108{
109 glUniform1i(Loc, Value);
110}
111
112void CGLSLProgram::SetUniform(int Loc, const float Value)
113{
114 glUniform1f(Loc, Value);
115}
116
117void CGLSLProgram::SetUniform(int Loc, const bool Value)
118{
119 glUniform1i(Loc, (int)Value);
120}
121
122int CGLSLProgram::GetUniformLoc(const char *pName) const
123{
124 return glGetUniformLocation(m_ProgramId, pName);
125}
126
127void CGLSLProgram::UseProgram() const
128{
129 if(m_IsLinked)
130 glUseProgram(m_ProgramId);
131}
132
133TWGLuint CGLSLProgram::GetProgramId() const
134{
135 return m_ProgramId;
136}
137
138CGLSLProgram::CGLSLProgram()
139{
140 m_IsLinked = false;
141}
142
143CGLSLProgram::~CGLSLProgram()
144{
145 DeleteProgram();
146}
147
148#endif
149