zoukankan      html  css  js  c++  java
  • opengl 学习 之 06 lesson

    opengl 学习 之 06 lesson

    简介

    随着键盘和鼠标来控制显示效果。

    link

    http://www.opengl-tutorial.org/uncategorized/2017/06/07/website-update/

    Q&A

    1. 已知球坐标系的三个两个角度和长度如果求其方向向量

      // Direction : Spherical coordinates to Cartesian coordinates conversion
      glm::vec3 direction(
       cos(verticalAngle) * sin(horizontalAngle),
       sin(verticalAngle),
       cos(verticalAngle) * cos(horizontalAngle)
      );
      

      参考链接 https://jingyan.baidu.com/article/948f5924f37340d80ff5f93d.html

    2. 知道了水平的方向向量如何求逆时针旋转(pi /2)的向量。

      参考链接 https://linux.die.net/man/3/glmatrixmode

      其实想象一个单位圆,然后一个向量旋转了一定的角度。

      // Right vector
      glm::vec3 right = glm::vec3(
       sin(horizontalAngle - 3.14f/2.0f),
       0,
       cos(horizontalAngle - 3.14f/2.0f)
      );
      

    TIPS

    可以做到将三角面片的法向量如果不是朝向摄像机的话删去

    *// Cull triangles which normal is not towards the camera

    glEnable(GL_CULL_FACE);

    这个实例在linux上执行不成功一直在闪烁就是动的很快,不知道。

    其中按键移动上下左右改变摄像机的坐标。

    鼠标改变摄像机的朝向

    code

    // Include GLFW
    #include <GLFW/glfw3.h>
    extern GLFWwindow* window; // The "extern" keyword here is to access the variable "window" declared in tutorialXXX.cpp. This is a hack to keep the tutorials simple. Please avoid this.
    
    // Include GLM
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    using namespace glm;
    
    #include "controls.hpp"
    
    glm::mat4 ViewMatrix;
    glm::mat4 ProjectionMatrix;
    
    glm::mat4 getViewMatrix(){
    	return ViewMatrix;
    }
    glm::mat4 getProjectionMatrix(){
    	return ProjectionMatrix;
    }
    
    
    // Initial position : on +Z
    glm::vec3 position = glm::vec3( 0, 0, 5 ); 
    // Initial horizontal angle : toward -Z
    float horizontalAngle = 3.14f;
    // Initial vertical angle : none
    float verticalAngle = 0.0f;
    // Initial Field of View
    float initialFoV = 45.0f;
    
    float speed = 3.0f; // 3 units / second
    float mouseSpeed = 0.005f;
    
    
    
    void computeMatricesFromInputs(){
    
    	// glfwGetTime is called only once, the first time this function is called
    	static double lastTime = glfwGetTime();
    
    	// Compute time difference between current and last frame
    	double currentTime = glfwGetTime();
    	float deltaTime = float(currentTime - lastTime);
    
    	// Get mouse position
    	double xpos, ypos;
    	glfwGetCursorPos(window, &xpos, &ypos);
    
    	// Reset mouse position for next frame
    	glfwSetCursorPos(window, 1024/2, 768/2);
    
    	// Compute new orientation
    	horizontalAngle += mouseSpeed * float(1024/2 - xpos );
    	verticalAngle   += mouseSpeed * float( 768/2 - 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
    	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 = initialFoV;// - 5 * glfwGetMouseWheel(); // Now GLFW 3 requires setting up a callback for this. It's a bit too complicated for this beginner's tutorial, so it's disabled instead.
    
    	// Projection matrix : 45� Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
    	ProjectionMatrix = glm::perspective(glm::radians(FoV), 4.0f / 3.0f, 0.1f, 100.0f);
    	// Camera matrix
    	ViewMatrix       = glm::lookAt(
    								position,           // Camera is here
    								position+direction, // and looks here : at the same position, plus "direction"
    								up                  // Head is up (set to 0,-1,0 to look upside-down)
    						   );
    
    	// For the next frame, the "last time" will be "now"
    	lastTime = currentTime;
    }
    
    #ifndef CONTROLS_HPP
    #define CONTROLS_HPP
    
    void computeMatricesFromInputs();
    glm::mat4 getViewMatrix();
    glm::mat4 getProjectionMatrix();
    
    #endif
    
    // Include standard headers
    #include <stdio.h>
    #include <stdlib.h>
    
    // Include GLEW
    #include <GL/glew.h>
    
    // Include GLFW
    #include <GLFW/glfw3.h>
    GLFWwindow* window;
    
    // Include GLM
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    using namespace glm;
    
    #include <common/shader.hpp>
    #include <common/texture.hpp>
    #include <common/controls.hpp>
    
    int main( void )
    {
    	// Initialise GLFW
    	if( !glfwInit() )
    	{
    		fprintf( stderr, "Failed to initialize GLFW
    " );
    		getchar();
    		return -1;
    	}
    
    	glfwWindowHint(GLFW_SAMPLES, 4);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
    	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    	// Open a window and create its OpenGL context
    	window = glfwCreateWindow( 1024, 768, "Tutorial 0 - Keyboard and Mouse", NULL, NULL);
    	if( window == NULL ){
    		fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.
    " );
    		getchar();
    		glfwTerminate();
    		return -1;
    	}
        glfwMakeContextCurrent(window);
    
    	// Initialize GLEW
    	glewExperimental = true; // Needed for core profile
    	if (glewInit() != GLEW_OK) {
    		fprintf(stderr, "Failed to initialize GLEW
    ");
    		getchar();
    		glfwTerminate();
    		return -1;
    	}
    
    	// Ensure we can capture the escape key being pressed below
    	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
        // Hide the mouse and enable unlimited mouvement
        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
        
        // Set the mouse at the center of the screen
        glfwPollEvents();
        glfwSetCursorPos(window, 1024/2, 768/2);
    
    	// Dark blue background
    	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
    
    	// Enable depth test
    	glEnable(GL_DEPTH_TEST);
    	// Accept fragment if it closer to the camera than the former one
    	glDepthFunc(GL_LESS); 
    
    	// Cull triangles which normal is not towards the camera
    	glEnable(GL_CULL_FACE);
    
    	GLuint VertexArrayID;
    	glGenVertexArrays(1, &VertexArrayID);
    	glBindVertexArray(VertexArrayID);
    
    	// Create and compile our GLSL program from the shaders
    	GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "TextureFragmentShader.fragmentshader" );
    
    	// Get a handle for our "MVP" uniform
    	GLuint MatrixID = glGetUniformLocation(programID, "MVP");
    
    	// Load the texture
    	GLuint Texture = loadDDS("uvtemplate.DDS");
    	
    	// Get a handle for our "myTextureSampler" uniform
    	GLuint TextureID  = glGetUniformLocation(programID, "myTextureSampler");
    
    	// 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.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
    	};
    
    	// Two UV coordinatesfor each vertex. They were created with Blender.
    	static const GLfloat g_uv_buffer_data[] = { 
    		0.000059f, 0.000004f, 
    		0.000103f, 0.336048f, 
    		0.335973f, 0.335903f, 
    		1.000023f, 0.000013f, 
    		0.667979f, 0.335851f, 
    		0.999958f, 0.336064f, 
    		0.667979f, 0.335851f, 
    		0.336024f, 0.671877f, 
    		0.667969f, 0.671889f, 
    		1.000023f, 0.000013f, 
    		0.668104f, 0.000013f, 
    		0.667979f, 0.335851f, 
    		0.000059f, 0.000004f, 
    		0.335973f, 0.335903f, 
    		0.336098f, 0.000071f, 
    		0.667979f, 0.335851f, 
    		0.335973f, 0.335903f, 
    		0.336024f, 0.671877f, 
    		1.000004f, 0.671847f, 
    		0.999958f, 0.336064f, 
    		0.667979f, 0.335851f, 
    		0.668104f, 0.000013f, 
    		0.335973f, 0.335903f, 
    		0.667979f, 0.335851f, 
    		0.335973f, 0.335903f, 
    		0.668104f, 0.000013f, 
    		0.336098f, 0.000071f, 
    		0.000103f, 0.336048f, 
    		0.000004f, 0.671870f, 
    		0.336024f, 0.671877f, 
    		0.000103f, 0.336048f, 
    		0.336024f, 0.671877f, 
    		0.335973f, 0.335903f, 
    		0.667969f, 0.671889f, 
    		1.000004f, 0.671847f, 
    		0.667979f, 0.335851f
    	};
    
    	GLuint vertexbuffer;
    	glGenBuffers(1, &vertexbuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
    
    	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);
    
    	do{
    
    		// Clear the screen
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    		// Use our shader
    		glUseProgram(programID);
    
    		// Compute the MVP matrix from keyboard and mouse input
    		computeMatricesFromInputs();
    		glm::mat4 ProjectionMatrix = getProjectionMatrix();
    		glm::mat4 ViewMatrix = getViewMatrix();
    		glm::mat4 ModelMatrix = glm::mat4(1.0);
    		glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
    
    		// Send our transformation to the currently bound shader, 
    		// in the "MVP" uniform
    		glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
    
    		// Bind our texture in Texture Unit 0
    		glActiveTexture(GL_TEXTURE0);
    		glBindTexture(GL_TEXTURE_2D, Texture);
    		// Set our "myTextureSampler" sampler to use Texture Unit 0
    		glUniform1i(TextureID, 0);
    
    		// 1rst attribute buffer : vertices
    		glEnableVertexAttribArray(0);
    		glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    		glVertexAttribPointer(
    			0,                  // attribute. 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
    		);
    
    		// 2nd attribute buffer : UVs
    		glEnableVertexAttribArray(1);
    		glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    		glVertexAttribPointer(
    			1,                                // attribute. No particular reason for 1, but must match the layout in the shader.
    			2,                                // size : U+V => 2
    			GL_FLOAT,                         // type
    			GL_FALSE,                         // normalized?
    			0,                                // stride
    			(void*)0                          // array buffer offset
    		);
    
    		// Draw the triangle !
    		glDrawArrays(GL_TRIANGLES, 0, 12*3); // 12*3 indices starting at 0 -> 12 triangles
    
    		glDisableVertexAttribArray(0);
    		glDisableVertexAttribArray(1);
    
    		// Swap buffers
    		glfwSwapBuffers(window);
    		glfwPollEvents();
    
    	} // Check if the ESC key was pressed or the window was closed
    	while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
    		   glfwWindowShouldClose(window) == 0 );
    
    	// Cleanup VBO and shader
    	glDeleteBuffers(1, &vertexbuffer);
    	glDeleteBuffers(1, &uvbuffer);
    	glDeleteProgram(programID);
    	glDeleteTextures(1, &TextureID);
    	glDeleteVertexArrays(1, &VertexArrayID);
    
    	// Close OpenGL window and terminate GLFW
    	glfwTerminate();
    
    	return 0;
    }
    
    
    #version 330 core
    
    // Input vertex data, different for all executions of this shader.
    layout(location = 0) in vec3 vertexPosition_modelspace;
    layout(location = 1) in vec2 vertexUV;
    
    // Output data ; will be interpolated for each fragment.
    out vec2 UV;
    
    // Values that stay constant for the whole mesh.
    uniform mat4 MVP;
    
    void main(){
    
    	// Output position of the vertex, in clip space : MVP * position
    	gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
    	
    	// UV of the vertex. No special space for this one.
    	UV = vertexUV;
    }
    
    
    
    #version 330 core
    
    // Interpolated values from the vertex shaders
    in vec2 UV;
    
    // Ouput data
    out vec3 color;
    
    // Values that stay constant for the whole mesh.
    uniform sampler2D myTextureSampler;
    
    void main(){
    
    	// Output color = color of the texture at the specified UV
    	color = texture( myTextureSampler, UV ).rgb;
    }
    
    Hope is a good thing,maybe the best of things,and no good thing ever dies.----------- Andy Dufresne
  • 相关阅读:
    ToDesk 远程连接软件 连接远程电脑后黑屏
    Kentico updateall
    Stylesheet not loaded because of MIME-type
    Linux tail 命令作用及其常用用法
    浅析Linux中stty命令的作用、常用用法及案例使用
    【MySQL】修改表的存储引擎
    【MySQL】查看MySQL的默认存储引擎(Win环境)
    【Swing/STS】在Spring Tool Suite中制作可执行jar
    [Swing]我的作品 图片幻灯式浏览软件PicturesShow 献给广大美图爱好者的福音
    【Java Swing】如何给Jframe添加键盘和鼠标事件处理
  • 原文地址:https://www.cnblogs.com/eat-too-much/p/14068214.html
Copyright © 2011-2022 走看看