////////////////////////////////////////////////////////////////////////////////////// //移动三角形,版本2:通过shader实现位置变化. //作者:青丝成霜 ////////////////////////////////////////////////////////////////////////////////////// #include <stdio.h> #include <stdlib.h> #include <GL/glew.h> #include "readtext.h" #ifdef _APPLE_ #include <glut/glut.h> #else #define FREEGLUT_STATIC #include <GL/glut.h> #endif GLuint vShader, fShader, programHandle; GLint vaoHandle, vboHandles[2], positionBufferHandle, colorBufferHandle; GLint elapseTimeUniformLocation, loopDurationLocation; GLint positionLocation, colorLocation; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// int infoLogLength =0; int charWritten =0; char *infoLog; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// float positionData[]={ 0.8f, 0.0f, 0.0f, -0.8f, 0.0f, 0.0f, 0.0f, 0.8f, 0.0f}; ////////////////////////////////////////// float colorData[]= { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetupShader() { char *renderer; char *vender; char *version; char *glslVersion; //////////////////////////////////// char *vs, *fs; char *vv, *ff; char *txt; ///////////////////////////////////////////////////////////// renderer =glGetString(GL_RENDERER); vender =glGetString(GL_VENDOR); version =glGetString(GL_VERSION); glslVersion =glGetString(GL_SHADING_LANGUAGE_VERSION); printf("graphic card:\t%s \n", renderer); printf("graphic company:\t%s \n", vender); printf("openGL version:\t%s \n", version); printf("GLSL version:\t %s \n", glslVersion); printf("*****************************************************\n"); ////////////////////////////////////////////////////////////// //txt =readText("2.txt"); //printf("%s\n",txt); //putchar(10); vShader =glCreateShader(GL_VERTEX_SHADER); vs =readText("shader/triangle.vert"); printf("%s\n",vs); vv =vs; if(vShader ==0) { printf("Error: fail to create shader!"); exit(1); } glShaderSource(vShader, 1, &vv, NULL); glCompileShader(vShader); free(vs); glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &infoLogLength); if(infoLogLength >0) { infoLog =(char *)malloc(infoLogLength); glGetShaderInfoLog(vShader, infoLogLength, &charWritten, infoLog); printf("%s\n", infoLog); printf("********************************************************\n"); free(infoLog); } ///////////////////////////////////////////////////////////////////////////////// fShader =glCreateShader(GL_FRAGMENT_SHADER); if(fShader ==0) { printf("can‘t create fragment shader! \n"); exit(1); } fs =readText("shader/triangle.frag"); printf("%s \n",fs); ff= fs; glShaderSource(fShader, 1, &ff, NULL); glCompileShader(fShader); free(fs); glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &infoLogLength); if(infoLogLength >0) { infoLog =(char *)malloc(infoLogLength); glGetShaderInfoLog(fShader, infoLogLength, &charWritten, infoLog); ////////charWritten is printf("%s \n",infoLog); printf("*********************************************************\n"); free(infoLog); } //////////////////////////////////// ////////////////////////////////////// programHandle =glCreateProgram(); glAttachShader(programHandle, vShader); glAttachShader(programHandle, fShader); glLinkProgram(programHandle); glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &infoLogLength); if(infoLogLength >0) { infoLog =(char *)malloc(infoLogLength); glGetProgramInfoLog(programHandle, infoLogLength, &charWritten, infoLog); printf("%s \n", infoLog); printf("*********************************************************\n"); free(infoLog); } glUseProgram(programHandle); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void InitVBO() { glGenBuffers(2, vboHandles); positionBufferHandle =vboHandles[0]; colorBufferHandle =vboHandles[1]; ////////////////////////////////////// glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle); glBufferData(GL_ARRAY_BUFFER, sizeof(positionData), positionData,GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle); glBufferData(GL_ARRAY_BUFFER, sizeof(colorData), colorData, GL_STATIC_DRAW); ////////////////////////////////////////// glGenVertexArrays(1, &vaoHandle); glBindVertexArray(vaoHandle);//必须绑定方可使用,通过glVertexAttribPointer将VAO与VBO联系起来 ///////////////////////////////////////////// glEnableVertexAttribArray(0); glEnableVertexAttribArray(1);//必须在glVertexAttribPointer之前 glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); //联系VAO VBO的关键. glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); } ///////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// void SetupRC() { glewInit(); SetupShader(); InitVBO(); glClearColor(1.0, 0.0, 0.0, 1.0); } ///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// void RenderScene() { glClear(GL_COLOR_BUFFER_BIT ); glBindVertexArray(vaoHandle); glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(0); elapseTimeUniformLocation =glGetUniformLocation(programHandle, "time"); loopDurationLocation =glGetUniformLocation(programHandle, "loopDuration"); //printf("%d\t%d\t",elapseTimeUniformLocation, loopDurationLocation); glUniform1f(loopDurationLocation, 5.0f); glUniform1f(elapseTimeUniformLocation, glutGet(GLUT_ELAPSED_TIME)/1000.0f ); glutSwapBuffers(); glutPostRedisplay(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(800, 600); glutInitWindowPosition(0,0); glutCreateWindow("second triangle:active!"); SetupRC(); glutDisplayFunc(RenderScene); glutMainLoop(); return 0; }
triangle.vert
#version 400 layout(location =0) in vec3 vertexPosition; layout(location =1) in vec3 vertexColor; out vec3 vColor; uniform float loopDuration; uniform float time; void main() { float timeScale = 3.14159f * 2.0f / loopDuration; float currTime = mod(time, loopDuration); vec4 totalOffset = vec4(cos(currTime * timeScale) * 0.5f, sin(currTime * timeScale) * 0.5f, 0.0f, 0.0f); gl_Position = vec4(vertexPosition,1.0) + totalOffset; vColor =vertexColor; }
triangle.frag
#version 400 in vec3 vColor; out vec4 fragColor; void main() { fragColor =vec4(vColor, 1.0); }