最近版本的OpenGL更新以后,所有的固定流水线的功能全部加入到shader里面计算。
兼容模式:最早版本的opengl绘制模式,支持glBegin/glEnd/glVertexPointer/glColorPointer等函数,也支持可编程管线,无显卡要求。
核心模式:现代3D编程模式,较新,不支持glBegin/glEnd/glVertexPointer/glColorPointer等函数,仅支持可编程管线。
兼容模式Shader 和核心模式的Shader不兼容
1.Shader:
//VertexShader:
1#version 330 core
2
3// Input vertex data, different for all executions of this shader.
4layout(location = 0) in vec3 vertexPosition_modelspace;
5
6void main(){
7 gl_Position.xyz = vertexPosition_modelspace;
8}
9
10
//FragmentShader:
1#version 330 core
2
3// Ouput data
4out vec3 color;
5
6void main(){
7 // Output color = red
8 color = vec3(1,0,0);
9} 2.Shader:
Data can be passed from a vertex shader to a fragment shader, using output variables in the vertex shader and corresponding input variables in the fragment shader//VertexShader:
1#version 330
2
3layout (location = 0) in vec4 position;
4layout (location = 1) in vec4 color;
5
6smooth out vec4 theColor;
7
8void main(){
9 gl_Position=position;
10 theColor=color;
11} //FragmentShader:
1#version 330
2
3smooth in vec4 theColor;
4out vec4 outputColor;
5
6void main(){
7 outputColor=theColor;
8}
9
10 渲染:
1void myDispaly(){
2 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
3 glClear(GL_COLOR_BUFFER_BIT);
4
5 GLuint programID = LoadShaders( "vertpositionColor.vert", "fragmentpc.frag" );
6
7 GLuint vertexbuffer;
8 glGenBuffers(1, &vertexbuffer);
9 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
10 glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
11
12 glUseProgram(programID);
13 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
14
15 glEnableVertexAttribArray(0);
16 glEnableVertexAttribArray(1);
17
18 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void*)0 );
19 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)48 );
20
21 glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
22
23 glDisableVertexAttribArray(0);
24 glDisableVertexAttribArray(1);
25
26 glutSwapBuffers();
27 glUseProgram(0);
28 glDeleteBuffers(1, &vertexbuffer);
29}
30 3.Shader:移动
如果不用内置函数来操作,那么可以用shader来实现,首先要计算出物体移动的x y z坐标,然后通过vertex shader来传递:
//vertex shader
1#version 330 core
2
3layout (location = 0) in vec4 position;
4
5uniform vec2 offset;
6
7void main(){
8 vec4 totaloffset=vec4(offset.x,offset.y,0,0);
9 gl_Position=position+totaloffset;
10} uniform变量操作:
1offsetLocation=glGetUniformLocation(programID,"offset"); 1 glUniform2f(offsetLocation,fXOffset,fYOffset); 4.Shader:透视投影
//vertex shader
1#version 330 core
2
3layout (location = 0) in vec4 position;
4layout (location = 1) in vec4 Color;
5
6smooth out vec4 theColor;
7
8uniform vec2 offset;
9uniform float zNear;
10uniform float zFar;
11uniform float frustumScale;
12
13void main(){
14 vec4 cameraPos=position+vec4(offset.x, offset.y, 0, 0);
15 vec4 clipPos;
16
17 clipPos.xy=cameraPos.xy*frustumScale;
18
19 clipPos.z=cameraPos.z*(zNear + zFar)/(zNear - zFar);
20 clipPos.z+=2*zNear*zFar/(zNear - zFar);
21
22 clipPos.w = -cameraPos.z;
23
24 gl_Position=clipPos;
25 theColor=Color;
26
27} 5.Shader 透视投影版本1
//vertex shader
1#version 330
2
3layout(location = 0) in vec4 position;
4layout(location = 1) in vec4 color;
5
6smooth out vec4 theColor;
7
8uniform vec2 offset;
9uniform mat4 perspectiveMatrix;
10
11void main()
12{
13 vec4 cameraPos = position + vec4(offset.x, offset.y, 0.0, 0.0);
14
15 gl_Position = perspectiveMatrix * cameraPos;
16 theColor = color;
17} 变量传值:
1offsetUniform = glGetUniformLocation(theProgram, "offset");
2
3perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix");
4
5float fFrustumScale = 1.0f; float fzNear = 0.5f; float fzFar = 3.0f;
6
7float theMatrix[16];
8memset(theMatrix, 0, sizeof(float) * 16);
9
10theMatrix[0] = fFrustumScale;
11theMatrix[5] = fFrustumScale;
12theMatrix[10] = (fzFar + fzNear) / (fzNear - fzFar);
13theMatrix[14] = (2 * fzFar * fzNear) / (fzNear - fzFar);
14theMatrix[11] = -1.0f;
15
16glUseProgram(theProgram);
17glUniformMatrix4fv(perspectiveMatrixUnif, 1, GL_FALSE, theMatrix);
18glUseProgram(0);