Sending data to a shader using vertex attributes and vertex buffer object
上次我们说到着色器的编译和连接,后面的事情没有做过多的阐述,所以我们今天继续上次的。
今天所讲的也是OpenGL着色器编程中非常重要的一个环节,叫做:数据传递
它主要承担的任务呢就是把opengl主程序中的数据传递到着色器中,上一节,我们已经把着色器准备好了,本节,我们将把主程序中的数据传递到着色器中进行处理。
说到数据传递,它其实分两种:
上述两者均为非常重要的内容,我们今天先阐述第一种。
Getting Ready
为了方便,我们把上次的代码贴过来
顶点着色器 vertShader
#version 430 layout (location=0) in vec3 VertexPosition; layout (location=1) in vec3 VertexColor; out vec3 Color; void main() { Color = VertexColor; gl_Position = vec4(VertexPosition,1.0); }
片元着色器 fragShader
#version 430 in vec3 Color; out vec4 FragColor; void main() { FragColor = vec4(Color, 1.0); }
opengl 主程序(应用程序)
1 //配置代码 2 #if _MSC_VER>=1900 3 #include "stdio.h" 4 _ACRTIMP_ALT FILE* __cdecl __acrt_iob_func(unsigned); 5 #ifdef __cplusplus 6 extern "C" 7 #endif 8 FILE* __cdecl __iob_func(unsigned i) { 9 return __acrt_iob_func(i); 10 } 11 #endif /* _MSC_VER>=1900 */ 12 13 //code-list 14 //using namespace std; 15 #include <iostream> 16 #include <fstream> 17 using namespace std; 18 #include <vgl.h> 19 20 GLint vertShader, fragShader; 21 GLuint vaoHandle; 22 23 float positionDate[] = 24 { 25 -0.8f,-0.8f,0.0f, 26 0.8f,-0.8f,0.0f, 27 0.0f,0.8f,0.0f, 28 }; 29 float colorDate[] = 30 { 31 1.0f,0.0f,0.0f, 32 0.0f,1.0f,0.0f, 33 0.0f,0.0f,1.0f, 34 }; 35 36 void init(); 37 void Display(); 38 void _Compiling_Shader_(GLint& shaderHandle, GLint GL_Shader_type, GLchar* shaderName); //编译着色器 39 void _Link_Shader_(); //链接着色器 40 bool readFile(const char*, string&); //读取文件内容的函数 41 42 int main(int argc, char** argv) 43 { 44 glutInit(&argc, argv); 45 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); 46 glutInitWindowSize(1024, 768); 47 glutInitWindowPosition(20, 20); 48 glutCreateWindow("test"); 49 50 if (glewInit()) 51 { 52 cout << "Error!" << glGetString(glewInit()) << endl; 53 exit(EXIT_FAILURE); 54 } 55 56 cout << "GL version:" << glGetString(GL_VERSION) << endl; //查询本机OpenGL版本 57 58 init(); 59 60 61 _Compiling_Shader_(vertShader, GL_VERTEX_SHADER,"basic.vert"); 62 _Compiling_Shader_(fragShader, GL_FRAGMENT_SHADER, "basic.frag"); 63 64 _Link_Shader_(); 65 66 glutDisplayFunc(Display); 67 68 glutMainLoop(); 69 } 70 71 72 void init() 73 { 74 GLuint vboHandles[2]; 75 76 glGenBuffers(2, vboHandles); 77 78 GLuint postionBufferHandle = vboHandles[0]; 79 GLuint colorBufferHanle = vboHandles[1]; 80 81 glBindBuffer(GL_ARRAY_BUFFER, postionBufferHandle); 82 glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), positionDate, GL_STATIC_DRAW); 83 84 glBindBuffer(GL_ARRAY_BUFFER, colorBufferHanle); 85 glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), colorDate, GL_STATIC_DRAW); 86 87 glGenVertexArrays(1, &vaoHandle); 88 glBindVertexArray(vaoHandle); 89 90 glEnableVertexAttribArray(0); 91 glEnableVertexAttribArray(1); 92 93 glBindBuffer(GL_ARRAY_BUFFER, postionBufferHandle); 94 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); 95 96 glBindBuffer(GL_ARRAY_BUFFER, colorBufferHanle); 97 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr); 98 } 99 100 void Display() 101 { 102 glClear(GL_COLOR_BUFFER_BIT); 103 104 glBindVertexArray(vaoHandle); 105 glDrawArrays(GL_TRIANGLES, 0, 3); 106 glutSwapBuffers(); 107 } 108 109 bool readFile(const char* filename, string& content) 110 { 111 ifstream infile; 112 infile.open(filename); 113 if (!infile.is_open())return false; 114 115 char ch; 116 infile >> noskipws; 117 while (!infile.eof()) 118 { 119 infile >> ch; 120 content += ch; 121 } 122 infile.close(); 123 content += '\0'; 124 return true; 125 } 126 127 void _Compiling_Shader_(GLint& shaderHandle, GLint GL_Shader_type, GLchar* shaderName) 128 { 129 shaderHandle = glCreateShader(GL_Shader_type); 130 //检查编译情况 131 if (0 == shaderHandle) 132 { 133 fprintf(stderr, "Error creating shader.\n"); 134 exit(EXIT_FAILURE); 135 } 136 string ShaderCode; 137 if (!readFile(shaderName, ShaderCode)) 138 { 139 cout << "readFile Error!" << endl; 140 exit(EXIT_FAILURE); 141 } 142 const GLchar* shaderSource = ShaderCode.c_str(); 143 const GLchar* codeArray[] = { shaderSource }; 144 glShaderSource(shaderHandle, 1, codeArray, NULL); 145 146 glCompileShader(shaderHandle); 147 148 GLint result; 149 glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &result); 150 if (GL_FALSE == result) 151 { 152 fprintf(stderr, "shader compilation failed!\n"); 153 154 GLint logLen; 155 glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &logLen); 156 157 if (logLen > 0) 158 { 159 char* log = new char[logLen]; 160 161 GLsizei written; 162 glGetShaderInfoLog(shaderHandle, logLen, &written, log); 163 164 fprintf(stderr, "Shader log:\n%s", log); 165 delete[] log; 166 } 167 } 168 } 169 void _Link_Shader_() 170 { 171 GLuint programHandle = glCreateProgram(); 172 if (0 == programHandle) 173 { 174 fprintf(stderr, "Error creating program object.\n"); 175 exit(1); 176 } 177 178 glAttachShader(programHandle, vertShader); 179 glAttachShader(programHandle, fragShader); 180 181 glLinkProgram(programHandle); 182 183 GLint status; 184 glGetProgramiv(programHandle, GL_LINK_STATUS, &status); 185 if (GL_FALSE == status) 186 { 187 fprintf(stderr, "Failed to link shader program!\n"); 188 189 GLint logLen; 190 glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &logLen); 191 if (logLen > 0) 192 { 193 char* log = new char[logLen]; 194 195 GLsizei written; 196 glGetShaderInfoLog(programHandle, logLen, &written, log); 197 198 fprintf(stderr, "Program log:\n%s", log); 199 delete[] log; 200 } 201 } 202 else 203 glUseProgram(programHandle); 204 }