opengl 学习 之 06 lesson
opengl 学习 之 06 lesson
简介
随着键盘和鼠标来控制显示效果。
link
http://www.opengl-tutorial.org/uncategorized/2017/06/07/website-update/
Q&A
已知球坐标系的三个两个角度和长度如果求其方向向量
// 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
![]()
知道了水平的方向向量如何求逆时针旋转\(\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\n" );
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.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
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;
}
opengl 学习 之 06 lesson的更多相关文章
- OpenGL学习之windows下安装opengl的glut库
OpenGL学习之windows下安装opengl的glut库 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装. Windows环境下的GLUT下载地址:(大小约为15 ...
- OpenGL学习进程(7)第五课:点、边和图形(二)边
本节是OpenGL学习的第五个课时,下面介绍OpenGL边的相关知识: (1)边的概念: 数学上的直线没有宽度,但OpenGL的直线则是有宽度的.同时,OpenGL的直线必须是有限长度,而不是像数学概 ...
- OpenGL学习笔记3——缓冲区对象
在GL中特别提出了缓冲区对象这一概念,是针对提高绘图效率的一个手段.由于GL的架构是基于客户——服务器模型建立的,因此默认所有的绘图数据均是存储在本地客户端,通过GL内核渲染处理以后再将数据发往GPU ...
- OpenGL学习进程(12)第九课:矩阵乘法实现3D变换
本节是OpenGL学习的第九个课时,下面将详细介绍OpenGL的多种3D变换和如何操作矩阵堆栈. (1)3D变换: OpenGL中绘制3D世界的空间变换包括:模型变换.视图变换.投影变换和视口 ...
- OpenGL学习进程(11)第八课:颜色绘制的详解
本节是OpenGL学习的第八个课时,下面将详细介绍OpenGL的颜色模式,颜色混合以及抗锯齿. (1)颜色模式: OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. R ...
- OpenGL学习笔记:拾取与选择
转自:OpenGL学习笔记:拾取与选择 在开发OpenGL程序时,一个重要的问题就是互动,假设一个场景里面有很多元素,当用鼠标点击不同元素时,期待作出不同的反应,那么在OpenGL里面,是怎么知道我当 ...
- OpenGL学习之路(一)
1 引子 虽然是计算机科班出身,但从小对几何方面的东西就不太感冒,空间想象能力也较差,所以从本科到研究生,基本没接触过<计算机图形学>.为什么说基本没学过呢?因为好奇(尤其是惊叹于三维游戏 ...
- OpenGL学习之路(三)
1 引子 这些天公司一次次的软件发布节点忙的博主不可开交,另外还有其它的一些事也占用了很多时间.现在坐在电脑前,在很安静的环境下,与大家分享自己的OpenGL学习笔记和理解心得,感到格外舒服.这让我回 ...
- OpenGL学习之路(四)
1 引子 上次读书笔记主要是学习了应用三维坐标变换矩阵对二维的图形进行变换,并附带介绍了GLSL语言的编译.链接相关的知识,之后介绍了GLSL中变量的修饰符,着重介绍了uniform修饰符,来向着色器 ...
- OpenGL学习之路(五)
1 引子 不知不觉我们已经进入到读书笔记(五)了,我们先对前四次读书笔记做一个总结.前四次读书笔记主要是学习了如何使用OpenGL来绘制几何图形(包括二维几何体和三维几何体),并学习了平移.旋转.缩放 ...
随机推荐
- python满足任意一个条件均认为假设有效(执行if内脚本)if any的用法
下方代码,判断sta内是否包含s数组内的数字,只要包含任意一个输入ok,否则输出no s=['3','8','9'] sta='59' if s[0] in sta or s[1] in sta or ...
- 常用的 JVM 配置参数有哪些?
常用的 JVM 配置参数 JVM 配置参数可以用来控制 Java 程序的内存分配.垃圾回收.性能优化等.以下是一些常用的 JVM 配置参数: 1. 堆内存相关参数 -Xms:设置 JVM 初始堆内存大 ...
- 编译执行与解释执行的区别是什么?JVM 使用哪种方式?
编译执行与解释执行的区别 1. 编译执行(Compiled Execution) 定义: 将源代码一次性翻译为机器码(目标代码),生成可直接运行的二进制文件. 特点: 翻译只发生一次,生成的目标代码可 ...
- 【工具】没有人能拒绝这三种PDF阅读方式!打造良好的夜间PDF阅读环境,解放你的双眼!White is too harsh!
方式一和二都适用于常规的浏览器, 方式三是最最好用的PDF阅读器推荐. 方式一:f12改css 步骤一:打开开发者工具(f12). 步骤二:点击选择PDF所在元素,在style里面加一行filter: ...
- 鸿蒙NEXT开发实战教程—文字识别
今天跟大家分享一个ocr文字识别的小项目: 鸿蒙系统提供了文字识别的能力,支持简体中文.英文.日文.韩文.繁体中文五种语言.实现步骤为初始化文字识别服务.将图片转换为PixelMap.文字识别.释放O ...
- Lynx-字节跳动跨平台框架多端兼容Android, iOS, Web 原生渲染
介绍 字节跳动近期开源的跨平台框架Lynx被视为一项重要的技术创新.相较于市场上已有的解决方案如React Native (RN) 和Flutter,Lynx具有独特的特性. 首先,Lynx采用轻量级 ...
- WebAssembly:开启新时代的跨平台
@charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...
- Unity+MediaPipe虚拟试衣间技术实现全攻略
引言:数字时尚革命的序章 在元宇宙概念席卷全球的今天,虚拟试衣技术正成为连接物理世界与数字孪生的关键桥梁.本文将深入解析基于Unity引擎结合MediaPipe姿态估计框架的虚拟试衣系统实现,涵盖从环 ...
- 交易信号---MACD、RSI、Boll、分型等技术信号
技术指标 在交易决策过程中的简图: 什么是技术指标? 基于行情数据,通过特定数学公式或模型计算得出的.用于辅助交易决策的数值序列 技术指标的分类 三种关系: 趋势线: 股市走势震荡起伏,供需关系被打破 ...
- PyPI 使用的国内源
通过几次 pip 的使用,对于默认的 pip 源的速度实在无法忍受,于是便搜集了一些国内的pip源,如下:阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技大 ...
