1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > opengl鼠标键盘控制相机漫游

opengl鼠标键盘控制相机漫游

时间:2018-11-06 04:00:52

相关推荐

opengl鼠标键盘控制相机漫游

键盘wsad控制相机位移,鼠标左键按下控制相机旋转 效果如下代码如下

#include <stdio.h>#include <string.h> #include <iostream>#include <fstream> #include <sstream>#include <GL/glew.h> #include <GL/freeglut.h> #include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp> using namespace std;using namespace glm;const char* vsShaderName = "shader.vs";//顶点着色器const char* fsShaderName = "shader.fs";//片元着色器GLuint VBO;//顶点缓冲对象GLuint IBO;//索引缓冲对象 static GLfloat *vertices;//顶点数组static unsigned int *indices; //索引数组GLuint ShaderProgram;GLuint MatrixID;int windowWidth = 800;int windowHeight = 800;//相机参数glm::mat4 ViewMatrix;//视图矩阵glm::mat4 ProjectionMatrix; //投影矩阵glm::mat4 MVP;//模型视图矩阵glm::mat4 ModelMatrix;//模型矩阵glm::vec3 position = glm::vec3(5, 5, 5); //相机位置float horizontalAngle = 3.14f;float verticalAngle = 0.0f;float initialFoV = 45.0f; //相机视场角float speed = 0.05f; //平移速度float mouseSpeed = 0.005f;int mouseX, mouseY;//鼠标位置 窗口坐标bool mouseLeftDown=false;//鼠标左键按下 // 传递键盘事件static void SpecialKeyboardCB(unsigned char Key, int x, int y){ glm::vec3 direction(cos(verticalAngle) * sin(horizontalAngle),sin(verticalAngle),cos(verticalAngle) * cos(horizontalAngle));glm::vec3 right = glm::vec3(sin(horizontalAngle - 3.14f / 2.0f),0,cos(horizontalAngle - 3.14f / 2.0f));glm::vec3 up = glm::cross(right, direction);switch (Key) { case 'w':position += direction * speed;//fprintf(stderr, "up \n");break; case 'd':position += right * speed;//fprintf(stderr, "right \n");break; case 's':position -= direction * speed;//fprintf(stderr, "down \n");break; case 'a':position -= right * speed;//fprintf(stderr, "left \n");break;case 27:exit(1);break;default:break;//fprintf(stderr, "Unimplemented GLUT key\n");//exit(1); }float FoV = initialFoV;ProjectionMatrix = glm::perspective(glm::radians(FoV), (float)windowWidth /(float) windowHeight, 0.1f, 100.0f);ViewMatrix = glm::lookAt(position,position + direction,up);ModelMatrix = glm::mat4(1.0);MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;glutPostRedisplay();//设置窗口重绘}//传递鼠标事件void mouseCB(int button, int state, int x, int y){ if (button == GLUT_LEFT_BUTTON){if (state == GLUT_DOWN){mouseLeftDown = true;mouseX = x;mouseY = y; } else if (state == GLUT_UP){mouseLeftDown = false;}} }//传递鼠标位置static void mouseMotionCB(int x, int y){if (mouseLeftDown == true){horizontalAngle += mouseSpeed * float(x - mouseX);verticalAngle += mouseSpeed * float(y - mouseY);mouseX = x;mouseY = y;SpecialKeyboardCB(0, 0, 0);}}//渲染回调函数 void RenderScenceCB() {// 清空颜色缓存 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, VBO);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_LINES, 0, 40*4);glDisableVertexAttribArray(0);//交换前后缓存glutSwapBuffers();}//创建顶点static void CreateVertexBuffer(){ vertices = new GLfloat[40*3];for (size_t i = 0; i < 10; i++){ vertices[i * 12] = 0;vertices[i * 12 + 1] = 0;vertices[i * 12 + 2] = i;vertices[i * 12 + 3] = 9;vertices[i * 12 + 4] = 0;vertices[i * 12 + 5] = i;vertices[i * 12 + 6] = i;vertices[i * 12 + 7] = 0;vertices[i * 12 + 8] = 0;vertices[i * 12 + 9] = i;vertices[i * 12 + 10] = 0;vertices[i * 12 + 11] = 9;}glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, 40*3* sizeof(GLfloat), vertices, GL_STATIC_DRAW); } static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType){// 根据shader类型参数定义两个shader对象GLuint ShaderObj = glCreateShader(ShaderType);// 检查是否定义成功if (ShaderObj == 0) {fprintf(stderr, "Error creating shader type %d\n", ShaderType);exit(0);}// 定义shader的代码源const GLchar* p[1];p[0] = pShaderText;GLint Lengths[1];Lengths[0] = strlen(pShaderText);glShaderSource(ShaderObj, 1, p, Lengths);glCompileShader(ShaderObj);// 编译shader对象 // 检查和shader相关的错误GLint success;glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success);if (!success) {GLchar InfoLog[1024];glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog);fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog);exit(1);}// 将编译好的shader对象绑定到program object程序对象上glAttachShader(ShaderProgram, ShaderObj);}// 编译着色器函数static void CompileShaders(){// 创建着色器程序ShaderProgram = glCreateProgram();// 检查是否创建成功if (ShaderProgram == 0) {fprintf(stderr, "Error creating shader program\n");exit(1);}// 存储着色器文本的字符串string vs, fs;// 分别读取着色器文件中的文本到字符串std::ifstream VertexShaderStream(vsShaderName, std::ios::in);if (VertexShaderStream.is_open()) {std::stringstream sstr;sstr << VertexShaderStream.rdbuf();vs = sstr.str();VertexShaderStream.close();}else {printf("Error to open %s\n", vsShaderName);getchar();exit(0);}std::ifstream FragmentShaderStream(fsShaderName, std::ios::in);if (FragmentShaderStream.is_open()) {std::stringstream sstr;sstr << FragmentShaderStream.rdbuf();fs = sstr.str();FragmentShaderStream.close();}// 添加顶点着色器和片段着色器AddShader(ShaderProgram, vs.c_str(), GL_VERTEX_SHADER);AddShader(ShaderProgram, fs.c_str(), GL_FRAGMENT_SHADER);// 链接shader着色器程序,并检查程序相关错误GLint Success = 0;GLchar ErrorLog[1024] = { 0 };glLinkProgram(ShaderProgram);glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);if (Success == 0) {glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);exit(1);}// 检查验证在当前的管线状态程序是否可以被执行glValidateProgram(ShaderProgram);glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success);if (!Success) {glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);exit(1);}// 设置到管线声明中来使用上面成功建立的shader程序glUseProgram(ShaderProgram);MatrixID = glGetUniformLocation(ShaderProgram, "gWVP");}int main(int argc, char ** argv) {// 初始化GLUTglutInit(&argc, argv);// 显示模式:双缓冲、RGBAglutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);glutInitWindowSize(windowWidth, windowHeight);glutInitWindowPosition(100, 100);glutCreateWindow("CameraTest");GLenum res = glewInit();if (res != GLEW_OK) {fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));return 1;}// 开始渲染glutDisplayFunc(RenderScenceCB);// 注册键盘事件 glutKeyboardFunc(SpecialKeyboardCB);//注册鼠标事件glutMouseFunc(mouseCB);glutMotionFunc(mouseMotionCB);mouseX = windowWidth / 2;mouseY = windowHeight / 2;// 缓存清空后的颜色值glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//创建顶点CreateVertexBuffer(); // 编译着色器CompileShaders();//开启深度测试glEnable(GL_DEPTH_TEST);// 通知开始GLUT的内部循环glutMainLoop();delete vertices;return 0;}

#version 330 layout (location = 0) in vec3 Position; uniform mat4 gWVP; out vec3 Color; void main(){gl_Position = gWVP * vec4(Position, 1.0); Color = Position/10;}

#version 330 out vec3 FragColor; in vec3 Color; void main(){FragColor = Color;}

本文链接/gucheng/p/10139299.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。