opengl 键盘和鼠标
还是针对之前的那个立方体,只是键盘和鼠标输入时,实时修改它的透视矩阵和视图矩阵。
#include "glew.h"
#include <glfw3.h>
#include "common/loadShader.h"
#include "common/controls.h"
#include "glm.hpp"
#include "ext.hpp"
GLFWwindow* window;
int main(void)
{
//GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(480, 320, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
// Needed in core profile
if( glewInit() != GLEW_OK)
{
glfwTerminate();
return -1;
}
// Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
// A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.f, 1.f, 1.f,
-1.f,-1.f, 1.f,
1.f,-1.f, 1.f,
1.f,-1.f, 1.f,
1.f, 1.f, 1.f,
-1.f, 1.f, 1.f,
1.f, 1.f, 1.f,
1.f,-1.f, 1.f,
1.f,-1.f,-1.f,
1.f,-1.f,-1.f,
1.f, 1.f,-1.f,
1.f, 1.f, 1.f,
-1.f, 1.f,-1.f,
-1.f, 1.f, 1.f,
1.f, 1.f, 1.f,
1.f, 1.f, 1.f,
1.f, 1.f,-1.f,
-1.f, 1.f,-1.f,
-1.f,-1.f,-1.f,
-1.f,-1.f, 1.f,
1.f,-1.f, 1.f,
1.f,-1.f, 1.f,
1.f,-1.f,-1.f,
-1.f,-1.f,-1.f,
-1.f, 1.f,-1.f,
-1.f,-1.f,-1.f,
1.f,-1.f,-1.f,
1.f,-1.f,-1.f,
1.f, 1.f,-1.f,
-1.f, 1.f,-1.f,
-1.f, 1.f, 1.f,
-1.f, 1.f,-1.f,
-1.f,-1.f,-1.f,
-1.f,-1.f,-1.f,
-1.f,-1.f, 1.f,
-1.f, 1.f, 1.f,
};
//This will identify our vertex buffer
GLuint vertexbuffer;
//Generate 1 buffer,put the resulting identifier in vertexbuffer
glGenBuffers(1,&vertexbuffer);
//The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
//Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER,sizeof(g_vertex_buffer_data),g_vertex_buffer_data,GL_STATIC_DRAW);
GLuint Texture = loadBMP_custom("./resource/uvtemplate.bmp");
// One color for each vertex. They were generated randomly.
static const GLfloat g_uv_buffer_data[] = {
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f
};
GLuint uvbuffer;
glGenBuffers(1,&uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER,uvbuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(g_uv_buffer_data),g_uv_buffer_data,GL_STATIC_DRAW);
GLuint programID = LoadShaders("./shader/vertex.shader","./shader/fragment.shader");
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
/* Loop until the user closes the window */
// Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit 100 units
//glm::mat4 Projection = glm::ortho(-4.0f/3.0f, 4.0f/3.0f, -1.0f, 1.0f, 0.1f, 100.0f);
// Get a handle for our "MVP" uniform.
// Only at initialisation time.
GLuint MatrixID = glGetUniformLocation(programID,"MVP");
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
// For each model you render, since the MVP will be different (at least the M part)
GLuint TextureID = glGetUniformLocation(programID,"myTextureSampler");
int width,height;
glfwGetWindowSize(window,&width,&height);
float centerX = width;
float centerY = height;
centerX /= 2;
centerY /= 2;
glfwSetCursorPos(window,centerX,centerY);
while (glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && !glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
computeMatricesFromInputs();
glm::mat4 Projection = getProjectionMatrix();
glm::mat4 View = getViewMatrix();
//Model matrix : an identity matrix (model will be at the origin)
glm::mat4 Model = glm::mat4(1.0f);
// Our ModelViewProjection : multiplication of our 3 matrices
glm::mat4 MVP = Projection * View * Model;// Remember, matrix multiplication is the other way around
glUniformMatrix4fv(MatrixID,1,GL_FALSE,&MVP[0][0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,Texture);
glUniform1i(TextureID, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER,uvbuffer);
glVertexAttribPointer(
1, // attribute 0. No particular reason for 0, but must match the layout in the shader.
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDrawArrays(GL_TRIANGLES,0,12*3);// Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
来看键盘和鼠标检测
#include "controls.h"
#include <glfw3.h>
#include "glm.hpp"
#include "ext.hpp"
glm::mat4 ProjectionMatrix ;
glm::mat4 ViewMatrix;
extern GLFWwindow* window;
float speed = 3.0f; // 3 units / second
float mouseSpeed = 0.005f;
// position
glm::vec3 position = glm::vec3(0,0,5);
// horizontal angle : toward -Z
float horizontalAngle = 3.14f;
//vertical angle : 0, look at the horizon
float verticalAngle = 0.0f;
//Initial Field of View
float initialFov = 45.0f;
double lastXpos = 240;
double lastYpos = 160;
void computeMatricesFromInputs()
{
//FoV is the level of zoom. 80° = very wide angle, huge deformations. 60° – 45° : standard. 20° : big zoom.
double xpos,ypos;
glfwGetCursorPos(window,&xpos,&ypos);
static double lastTime = glfwGetTime();
double currentTime = glfwGetTime();
float deltaTime = float(currentTime - lastTime);
lastTime = float(currentTime);
// Compute new orientation
horizontalAngle += mouseSpeed * float(xpos - lastXpos);
verticalAngle += mouseSpeed * float(ypos - lastYpos);
lastXpos = xpos;
lastYpos = ypos;
// Direction : Spherical coordinates to Cartesian coordinates conversion
glm::vec3 direction(
cos(verticalAngle) * sin(horizontalAngle),
sin(verticalAngle),
cos(verticalAngle) * cos(horizontalAngle)
);
// Right vector
glm::vec3 right = glm::vec3(
sin(horizontalAngle - 3.14f/2.0f),
0,
cos(horizontalAngle - 3.14f/2.0f)
);
// Up vector : perpendicular to both direction and right
glm::vec3 up = glm::cross( right, direction );
// Move forward
if (glfwGetKey(window, GLFW_KEY_UP ) == GLFW_PRESS){
position += direction * deltaTime * speed;
}
// Move backward
if (glfwGetKey(window, GLFW_KEY_DOWN ) == GLFW_PRESS){
position -= direction * deltaTime * speed;
}
// Strafe right
if (glfwGetKey(window, GLFW_KEY_RIGHT ) == GLFW_PRESS){
position += right * deltaTime * speed;
}
// Strafe left
if (glfwGetKey(window, GLFW_KEY_LEFT ) == GLFW_PRESS){
position -= right * deltaTime * speed;
}
float FoV = 45.0f;//initialFoV - 5 * glfwGetMouseButton();
ProjectionMatrix = glm::perspective(FoV, 4.0f / 3.0f, 0.1f, 100.0f);
ViewMatrix = glm::lookAt(
position, // Camera is here
position+direction, // and looks here : at the same position, plus "direction"
up
);
// For the next frame, the "last time" will be "now"
lastTime = currentTime;
}
glm::mat4 getProjectionMatrix()
{
return ProjectionMatrix;
}
glm::mat4 getViewMatrix()
{
return ViewMatrix;
}