来源:《Computer Graphics Programming in OpenGL Using C++ 》by V Scott Gordon John L Clevenger 内容:程序4.3 Cube and Pyramid,书P83页,PDF102/403 效果:静止的立方体和锥体
程序4.3 Cube and Pyramid
文件1: 4.3 CubePyramid.cpp
# include <string>
# include <iostream>
# include <fstream>
# include <cmath>
# include "glm\glm.hpp"
# include "glm\gtc\type_ptr.hpp"
# include "glm\gtc\matrix_transform.hpp"
# include "Utils\4.1 Utils.h"
using namespace std;
# define numVAOs 1
# define numVBOs 2
float cameraX, cameraY, cameraZ;
float cubeLocX, cubeLocY, cubeLocZ;
float pyrLocX, pyrLocY, pyrLocZ;
GLuint renderingProgram;
GLuint vao[ numVAOs] ;
GLuint vbo[ numVBOs] ;
GLuint mvLoc, projLoc;
int width, height;
float aspect;
glm:: mat4 pMat, vMat, mMat, mvMat;
void setupVertices ( void ) {
float CubePositions[ 108 ] = {
- 1.0f , 1.0f , - 1.0f , - 1.0f , - 1.0f , - 1.0f , 1.0f , - 1.0f , - 1.0f ,
1.0f , - 1.0f , - 1.0f , 1.0f , 1.0f , - 1.0f , - 1.0f , 1.0f , - 1.0f ,
1.0f , - 1.0f , - 1.0f , 1.0f , - 1.0f , 1.0f , 1.0f , 1.0f , - 1.0f ,
1.0f , - 1.0f , 1.0f , 1.0f , 1.0f , 1.0f , 1.0f , 1.0f , - 1.0f ,
1.0f , - 1.0f , 1.0f , - 1.0f , - 1.0f , 1.0f , 1.0f , 1.0f , 1.0f ,
- 1.0f , - 1.0f , 1.0f , - 1.0f , 1.0f , 1.0f , 1.0f , 1.0f , 1.0f ,
- 1.0f , - 1.0f , 1.0f , - 1.0f , - 1.0f , - 1.0f , - 1.0f , 1.0f , 1.0f ,
- 1.0f , - 1.0f , - 1.0f , - 1.0f , 1.0f , - 1.0f , - 1.0f , 1.0f , 1.0f ,
- 1.0f , - 1.0f , 1.0f , 1.0f , - 1.0f , 1.0f , 1.0f , - 1.0f , - 1.0f ,
1.0f , - 1.0f , - 1.0f , - 1.0f , - 1.0f , - 1.0f , - 1.0f , - 1.0f , 1.0f ,
- 1.0f , 1.0f , - 1.0f , 1.0f , 1.0f , - 1.0f , 1.0f , 1.0f , 1.0f ,
1.0f , 1.0f , 1.0f , - 1.0f , 1.0f , 1.0f , - 1.0f , 1.0f , - 1.0f
} ;
float pyramidPositions[ 54 ] =
{ - 1.0f , - 1.0f , 1.0f , 1.0f , - 1.0f , 1.0f , 0.0f , 1.0f , 0.0f ,
1.0f , - 1.0f , 1.0f , 1.0f , - 1.0f , - 1.0f , 0.0f , 1.0f , 0.0f ,
1.0f , - 1.0f , - 1.0f , - 1.0f , - 1.0f , - 1.0f , 0.0f , 1.0f , 0.0f ,
- 1.0f , - 1.0f , - 1.0f , - 1.0f , - 1.0f , 1.0f , 0.0f , 1.0f , 0.0f ,
- 1.0f , - 1.0f , - 1.0f , 1.0f , - 1.0f , 1.0f , - 1.0f , - 1.0f , 1.0f ,
1.0f , - 1.0f , 1.0f , - 1.0f , - 1.0f , - 1.0f , 1.0f , - 1.0f , - 1.0f
} ;
glGenVertexArrays ( 1 , vao) ;
glBindVertexArray ( vao[ 0 ] ) ;
glGenBuffers ( numVBOs, vbo) ;
glBindBuffer ( GL_ARRAY_BUFFER, vbo[ 0 ] ) ;
glBufferData ( GL_ARRAY_BUFFER, sizeof ( CubePositions) , CubePositions, GL_STATIC_DRAW) ;
glBindBuffer ( GL_ARRAY_BUFFER, vbo[ 1 ] ) ;
glBufferData ( GL_ARRAY_BUFFER, sizeof ( pyramidPositions) , pyramidPositions, GL_STATIC_DRAW) ;
}
void init ( GLFWwindow* window) {
renderingProgram = createShaderProgram ( "add/4.12 vertShader.glsl" , "add/4.12 fragShader.glsl" ) ;
cameraX = 0.0f ; cameraY = 0.0f ; cameraZ = 8.0f ;
cubeLocX = 0.0f ; cubeLocY = - 2.0f ; cubeLocZ = 0.0f ;
pyrLocX = 0.0f ; pyrLocY = 2.0f ; pyrLocZ = 0.0f ;
setupVertices ( ) ;
}
void display ( GLFWwindow* window, double currentTime) {
glClear ( GL_DEPTH_BUFFER_BIT) ;
glUseProgram ( renderingProgram) ;
mvLoc = glGetUniformLocation ( renderingProgram, "mv_matrix" ) ;
projLoc = glGetUniformLocation ( renderingProgram, "proj_matrix" ) ;
glfwGetFramebufferSize ( window, & width, & height) ;
aspect = ( float ) width / ( float ) height;
pMat = glm:: perspective ( 1.0472f , aspect, 0.1f , 1000.0f ) ;
vMat = glm:: translate ( glm:: mat4 ( 1.0f ) , glm:: vec3 ( - cameraX, - cameraY, - cameraZ) ) ;
mMat = glm:: translate ( glm:: mat4 ( 1.0f ) , glm:: vec3 ( cubeLocX, cubeLocY, cubeLocZ) ) ;
mvMat = vMat * mMat;
glUniformMatrix4fv ( mvLoc, 1 , GL_FALSE, glm:: value_ptr ( mvMat) ) ;
glUniformMatrix4fv ( projLoc, 1 , GL_FALSE, glm:: value_ptr ( pMat) ) ;
glBindBuffer ( GL_ARRAY_BUFFER, vbo[ 0 ] ) ;
glVertexAttribPointer ( 0 , 3 , GL_FLOAT, GL_FALSE, 0 , 0 ) ;
glEnableVertexAttribArray ( 0 ) ;
glEnable ( GL_DEPTH_TEST) ;
glDepthFunc ( GL_LEQUAL) ;
glDrawArrays ( GL_TRIANGLES, 0 , 36 ) ;
mMat = glm:: translate ( glm:: mat4 ( 1.0f ) , glm:: vec3 ( pyrLocX, pyrLocY, pyrLocZ) ) ;
mvMat = vMat * mMat;
glUniformMatrix4fv ( mvLoc, 1 , GL_FALSE, glm:: value_ptr ( mvMat) ) ;
glUniformMatrix4fv ( projLoc, 1 , GL_FALSE, glm:: value_ptr ( pMat) ) ;
glBindBuffer ( GL_ARRAY_BUFFER, vbo[ 1 ] ) ;
glVertexAttribPointer ( 0 , 3 , GL_FLOAT, GL_FALSE, 0 , 0 ) ;
glEnableVertexAttribArray ( 0 ) ;
glEnable ( GL_DEPTH_TEST) ;
glDepthFunc ( GL_LEQUAL) ;
glDrawArrays ( GL_TRIANGLES, 0 , 18 ) ;
}
int main ( void ) {
if ( ! glfwInit ( ) ) { exit ( EXIT_FAILURE) ; }
glfwWindowHint ( GLFW_CONTEXT_VERSION_MAJOR, 4 ) ;
glfwWindowHint ( GLFW_CONTEXT_VERSION_MINOR, 3 ) ;
GLFWwindow* window = glfwCreateWindow ( 600 , 600 , "Chapter 4 - program 3" , NULL , NULL ) ;
glfwMakeContextCurrent ( window) ;
if ( glewInit ( ) != GLEW_OK) { exit ( EXIT_FAILURE) ; }
glfwSwapInterval ( 1 ) ;
init ( window) ;
while ( ! glfwWindowShouldClose ( window) ) {
display ( window, glfwGetTime ( ) ) ;
glfwSwapBuffers ( window) ;
glfwPollEvents ( ) ;
}
glfwDestroyWindow ( window) ;
glfwTerminate ( ) ;
exit ( EXIT_SUCCESS) ;
}
文件2: 4.12 vertShader.glsl
# version 430
layout ( location= 0 ) in vec3 position;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
out vec4 varyingColor;
void main ( void )
{ gl_Position = proj_matrix * mv_matrix * vec4 ( position, 1.0 ) ;
varyingColor = vec4 ( position, 1.0 ) * 0.5 + vec4 ( 0.5 , 0.5 , 0.5 , 0.5 ) ;
}
文件3: 4.12 fragShader.glsl
# version 430
in vec4 varyingColor;
out vec4 color;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
void main ( void )
{ color = varyingColor;
}