1 #include "vertexLayout.h"
2 #include "text.h"
3 #include <sys/types.h>
4
5 std::map<GLint, GLuint> VertexLayout::s_enabledAttribs = std::map<GLint, GLuint>();
6
VertexLayout(std::vector<VertexAttrib> _attribs)7 VertexLayout::VertexLayout(std::vector<VertexAttrib> _attribs) : m_attribs(_attribs), m_stride(0), m_positionAttribIndex(-1), m_colorAttribIndex(-1), m_normalAttribIndex(-1), m_texCoordAttribIndex(-1) {
8
9 m_stride = 0;
10 for (unsigned int i = 0; i < m_attribs.size(); i++) {
11
12 // Set the offset of this vertex attribute: The stride at this point denotes the number
13 // of bytes into the vertex by which this attribute is offset, but we must cast the number
14 // as a void* to use with glVertexAttribPointer; We use reinterpret_cast to avoid warnings
15 m_attribs[i].offset = reinterpret_cast<void*>(m_stride);
16
17 GLint byteSize = m_attribs[i].size;
18
19 switch (m_attribs[i].type) {
20 case GL_FLOAT:
21 case GL_INT:
22 case GL_UNSIGNED_INT:
23 byteSize *= 4; // 4 bytes for floats, ints, and uints
24 break;
25 case GL_SHORT:
26 case GL_UNSIGNED_SHORT:
27 byteSize *= 2; // 2 bytes for shorts and ushorts
28 break;
29 }
30
31 if ( m_attribs[i].attrType == POSITION_ATTRIBUTE ){
32 m_positionAttribIndex = i;
33 }
34 else if ( m_attribs[i].attrType == COLOR_ATTRIBUTE ){
35 m_colorAttribIndex = i;
36 }
37 else if ( m_attribs[i].attrType == NORMAL_ATTRIBUTE ){
38 m_normalAttribIndex = i;
39 }
40 else if ( m_attribs[i].attrType == TEXCOORD_ATTRIBUTE ){
41 m_texCoordAttribIndex = i;
42 }
43
44 m_stride += byteSize;
45
46 // TODO: Automatically add padding or warn if attributes are not byte-aligned
47 }
48 }
49
~VertexLayout()50 VertexLayout::~VertexLayout() {
51 m_attribs.clear();
52 }
53
enable(const Shader * _program)54 void VertexLayout::enable(const Shader* _program) {
55 GLuint glProgram = _program->getProgram();
56
57 // Enable all attributes for this layout
58 for (unsigned int i = 0; i < m_attribs.size(); i++) {
59 const GLint location = _program->getAttribLocation("a_"+m_attribs[i].name);
60 if (location != -1) {
61 glEnableVertexAttribArray(location);
62 glVertexAttribPointer(location, m_attribs[i].size, m_attribs[i].type, m_attribs[i].normalized, m_stride, m_attribs[i].offset);
63 s_enabledAttribs[location] = glProgram; // Track currently enabled attribs by the program to which they are bound
64 }
65 }
66
67 // Disable previously bound and now-unneeded attributes
68 for (std::map<GLint, GLuint>::iterator it=s_enabledAttribs.begin(); it!=s_enabledAttribs.end(); ++it){
69 const GLint& location = it->first;
70 GLuint& boundProgram = it->second;
71
72 if (boundProgram != glProgram && boundProgram != 0) {
73 glDisableVertexAttribArray(location);
74 boundProgram = 0;
75 }
76 }
77 }
78
getDefaultVertShader()79 std::string VertexLayout::getDefaultVertShader() {
80 std::string rta =
81 "#ifdef GL_ES\n"
82 "precision mediump float;\n"
83 "#endif\n"
84 "\n"
85 "uniform mat4 u_modelViewProjectionMatrix;\n"
86 "uniform mat4 u_modelMatrix;\n"
87 "uniform mat4 u_viewMatrix;\n"
88 "uniform mat4 u_projectionMatrix;\n"
89 "uniform mat4 u_normalMatrix;\n"
90 "\n"
91 "uniform float u_time;\n"
92 "uniform vec2 u_mouse;\n"
93 "uniform vec2 u_resolution;\n"
94 "\n";
95
96 for (unsigned int i = 0; i < m_attribs.size(); i++) {
97 int size = m_attribs[i].size;
98 if (m_positionAttribIndex == int(i)) {
99 size = 4;
100 }
101 rta += "in vec" + toString(size) + " a_" + m_attribs[i].name + ";\n";
102 rta += "out vec" + toString(size) + " v_" + m_attribs[i].name + ";\n";
103 }
104
105 rta += "\n"
106 "void main(void) {\n"
107 "\n";
108
109 for (unsigned int i = 0; i < m_attribs.size(); i++) {
110 rta += " v_" + m_attribs[i].name + " = a_" + m_attribs[i].name + ";\n";
111 }
112
113 if (m_positionAttribIndex != -1 && m_positionAttribIndex < int(m_attribs.size())) {
114 rta += " gl_Position = u_modelViewProjectionMatrix * v_" + m_attribs[m_positionAttribIndex].name + ";\n";
115 }
116
117 rta += "}\n";
118
119 return rta;
120 }
121
getDefaultFragShader()122 std::string VertexLayout::getDefaultFragShader() {
123 std::string rta =
124 "#ifdef GL_ES\n"
125 "precision mediump float;\n"
126 "#endif\n"
127 "\n"
128 "uniform mat4 u_modelViewProjectionMatrix;\n"
129 "uniform mat4 u_modelMatrix;\n"
130 "uniform mat4 u_viewMatrix;\n"
131 "uniform mat4 u_projectionMatrix;\n"
132 "uniform mat4 u_normalMatrix;\n"
133 "\n"
134 "uniform float u_time;\n"
135 "uniform vec2 u_mouse;\n"
136 "uniform vec2 u_resolution;\n"
137 "\n";
138
139 for (unsigned int i = 0; i < m_attribs.size(); i++) {
140 int size = m_attribs[i].size;
141 if (m_positionAttribIndex == int(i)) {
142 size = 4;
143 }
144 rta += "out vec" + toString(size) + " v_" + m_attribs[i].name + ";\n";
145 }
146
147 rta += "\n"
148 "void main(void) {\n"
149 "\n";
150
151 if (m_colorAttribIndex != -1) {
152 rta += " gl_FragColor = v_" + m_attribs[m_colorAttribIndex].name + ";\n";
153 }
154 else if ( m_texCoordAttribIndex != -1 ){
155 rta += " gl_FragColor = vec4(vec3(v_" + m_attribs[m_texCoordAttribIndex].name + ",1.0),1.0);\n";
156 }
157 else if ( m_normalAttribIndex != -1 ){
158 rta += " gl_FragColor = vec4(0.5+v_" + m_attribs[m_normalAttribIndex].name + "*0.5,1.0);\n";
159 }
160 else {
161 rta += " gl_FragColor = vec4(1.0);\n";
162 }
163
164 rta += "}\n";
165
166 return rta;
167 }
168