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 | |
15 | void CGLSLProgram::CreateProgram() |
16 | { |
17 | m_ProgramId = glCreateProgram(); |
18 | } |
19 | |
20 | void CGLSLProgram::DeleteProgram() |
21 | { |
22 | if(!m_IsLinked) |
23 | return; |
24 | m_IsLinked = false; |
25 | glDeleteProgram(m_ProgramId); |
26 | } |
27 | |
28 | bool 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 | |
38 | void CGLSLProgram::DetachShader(CGLSL *pShader) const |
39 | { |
40 | if(pShader->IsLoaded()) |
41 | { |
42 | DetachShaderById(ShaderId: pShader->GetShaderId()); |
43 | } |
44 | } |
45 | |
46 | void CGLSLProgram::DetachShaderById(TWGLuint ShaderId) const |
47 | { |
48 | glDetachShader(m_ProgramId, ShaderId); |
49 | } |
50 | |
51 | void 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 | |
71 | void 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 | |
92 | void CGLSLProgram::SetUniformVec4(int Loc, int Count, const float *pValues) |
93 | { |
94 | glUniform4fv(Loc, Count, pValues); |
95 | } |
96 | |
97 | void CGLSLProgram::SetUniformVec2(int Loc, int Count, const float *pValues) |
98 | { |
99 | glUniform2fv(Loc, Count, pValues); |
100 | } |
101 | |
102 | void CGLSLProgram::SetUniform(int Loc, int Count, const float *pValues) |
103 | { |
104 | glUniform1fv(Loc, Count, pValues); |
105 | } |
106 | |
107 | void CGLSLProgram::SetUniform(int Loc, const int Value) |
108 | { |
109 | glUniform1i(Loc, Value); |
110 | } |
111 | |
112 | void CGLSLProgram::SetUniform(int Loc, const float Value) |
113 | { |
114 | glUniform1f(Loc, Value); |
115 | } |
116 | |
117 | void CGLSLProgram::SetUniform(int Loc, const bool Value) |
118 | { |
119 | glUniform1i(Loc, (int)Value); |
120 | } |
121 | |
122 | int CGLSLProgram::GetUniformLoc(const char *pName) const |
123 | { |
124 | return glGetUniformLocation(m_ProgramId, pName); |
125 | } |
126 | |
127 | void CGLSLProgram::UseProgram() const |
128 | { |
129 | if(m_IsLinked) |
130 | glUseProgram(m_ProgramId); |
131 | } |
132 | |
133 | TWGLuint CGLSLProgram::GetProgramId() const |
134 | { |
135 | return m_ProgramId; |
136 | } |
137 | |
138 | CGLSLProgram::CGLSLProgram() |
139 | { |
140 | m_IsLinked = false; |
141 | } |
142 | |
143 | CGLSLProgram::~CGLSLProgram() |
144 | { |
145 | DeleteProgram(); |
146 | } |
147 | |
148 | #endif |
149 | |