高级openg 混合,一个完整程序
1.当片段着色器处理完一个片段之后,模板测试(stencil test)会开始执行,和深度测试一样,它也可能会丢弃片段,接下来,被保留的片段会进入深度测试
2.每个窗口库都需要为你配置一个模板缓冲,但是GLFW这个窗口库会自动做这件事,所以不用告诉GLFW来创建一个模板缓冲
3.场景中的片段将只会在片段的模板值为1的时候被渲染,其他的都被丢弃了
启用模板缓冲的写入
渲染物体,更新模板缓冲的内容
禁用模板缓冲的写入
渲染其他物体,这次根据模板缓冲的内容丢弃特定的片段
用来配置模板缓冲的两个函数,glStencilFunc和glStencilOp
glStencilFunc(GLenum func, GLint ref, GLuint mash)一共包含三个参数:
func:设置模板测试函数(Stencil Test Function),这个测试函数将会应用到已存储的的模板值上和GLstenciFunc函数的ref值上,
可用的选项有:GL_NEVER/ GL_LESS/ GL_LEQUAL / GL_GREATER / GL_AEAUAL / GL_EQUAL / GL_NOTEQUAL和 GL_ALWAYS
ref:设置了模板测试的参考值(Reference Value), 模板缓冲的内容将会与这个值进行比较
mask:设置一个掩码,它将会与参考值和村初值在测试比较他们之前进行与(and)运算,初识情况下所有为都为1
但是glStencilFunc只描述了OpenGL应该对模板缓冲内容做什么,而不是我们应该如何更新缓冲,所以就需要glStencilOp这个函数了
glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)一共包含三个选项,我们能够设置每个选项应该采取的行为
sfail:模板测试失败是采取的行为
dpfail:模板测试通过,但深度测试失败采取的行为
dppass:模板测试和深度测试都通过时采取的行为
- 1 /**
- * glBlendFunc混合两种颜色的函数
- *glBlendFunc(GLenum sfactor, GLenum dfactor)函数接受两个参数,来设置源和目标因子
- *常数颜色向量Cconstan可以通过glBlendColor函数来另外设置*
- *glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- *也可以使用glBlendFuncSeparate为RGB和alpha通道分别设置不同的选项
- * glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_GL_ZERO);
- *glBlendEquation(GLenum mode)允许我们设置运算符
- *GL_FUNC_ADD:默认选项,将两个分量相加,Cr = S + D
- *GL_FUNC_SUBTRACT = S - D
- *GL_FUNC_REVERSE_SUBTRACT,将两个分量向减,但顺序相反*/
- /**
- *当绘制一个有不透明和透明物体的场景的时候,大体的原则如下:
- *1.先绘制所有不透明的物体。
- *2.对所有透明的物体排序。
- *3.按顺序绘制所有透明的物体。**/
- #include <iostream>
- #include <vector>
- #include <map>
- using namespace std;
- #define GLEW_STATIC
- #include <GL/glew.h>
- #include <GLFW/glfw3.h>
- #include "stb_image.h"
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtc/type_ptr.hpp>
- #include "Shader.h"
- #include "camera.h"
- //#include "Model.h"
- void framebuffer_size_callback(GLFWwindow* window, int width, int height);
- void mouse_callback(GLFWwindow* window, double xpos, double ypos);
- void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
- void processInput(GLFWwindow* window);
- unsigned int loadTexture(const char *path);
- //setting
- const unsigned int SCR_WIDTH = ;
- const unsigned int SCR_HEIGHT = ;
- //camera
- Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
- float lastX = (float)SCR_WIDTH / ;
- float lastY = (float)SCR_HEIGHT / ;
- bool firstMouse = true;
- //timing
- float deltaTime = 0.0f;
- float lastFrame = 0.0f;
- int main()
- {
- glfwInit();
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, );
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, );
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LEARNOPENGL", NULL, NULL);
- if (window == NULL)
- {
- std::cout << "Failed to create window!" << std::endl;
- glfwTerminate();
- return -;
- }
- glfwMakeContextCurrent(window);
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
- glfwSetCursorPosCallback(window, mouse_callback);
- glfwSetScrollCallback(window, scroll_callback);
- //tell GLFW to capture our mouse
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- glewExperimental = GL_TRUE;
- if (glewInit() != GLEW_OK)
- {
- std::cout << "Failed to initialize GLEW!" << std::endl;
- return -;
- }
- ////configure global opengl state
- //glEnable(GL_DEPTH_TEST); //启用深度测试,默认情况下是禁用的
- //glDepthFunc(GL_LESS); //always pass the depth test(same effect as glDisable(GL_DEPTH_TEST)//禁用深度测试,永远都通过深度测试
- ////glDepthMask(GL_FALSE); //深度掩码,可以禁用深度缓冲的写入
- //glEnable(GL_STENCIL_TEST);
- ////glStencilMask(0x00); //位掩码, 每个模板值都为0, 每一位在写入模板缓冲时都会变成0(禁用写入)
- //glStencilMask(0xff); //每个模板值都为1,每一位写入模板缓冲时都保持原样
- //glStencilFunc(GL_EQUAL, 1, 0xFF); //只要一个片段的模板值等于参考值1,片段将会通过测试并被绘制,否则会被被丢弃
- //glStencilOp(GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);//默认情况下,glStencilOp是设置为这样的,所以不论任何测试的结果是如何,模板缓冲都会保留它的值
- ////默认的行为不会更新模板缓冲,所以如果你想写入模板缓冲的话,至少对其中一个选项设置不同的值
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- glEnable(GL_BLEND); //启用混合
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- //build and compile shaders
- Shader shader("E:\\C++\\HigherOpenGL\\1.2.1ver1.txt", "E:\\C++\\HigherOpenGL\\1.3.2Frag1.txt");
- float cubeVertices[] = {
- //position //texture Coords
- -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
- 0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
- 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
- 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
- -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
- -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
- -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
- 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
- -0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
- -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
- -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
- -0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
- -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
- -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
- -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
- -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
- 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
- 0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
- 0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
- 0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
- -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
- 0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
- 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
- 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
- -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
- -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
- -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
- 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
- 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
- -0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
- -0.5f, 0.5f, -0.5f, 0.0f, 1.0f
- };
- float floorVertices[] = {
- 5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
- -5.0f, -0.5f, 5.0f, 0.0f, 0.0f,
- -5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
- 5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
- -5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
- 5.0f, -0.5f, -5.0f, 2.0f, 2.0f
- };
- float grassVertices[] = {
- 1.0f, -0.5f, 0.0f, 1.0f, 0.0f,
- 0.0f, -0.5f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
- 1.0f, -0.5f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
- 1.0f, 0.5f, 0.0f, 1.0f, 1.0f
- };
- vector<glm::vec3> vegetation;
- vegetation.push_back(glm::vec3(-1.5f, 0.0f, -0.48f));
- vegetation.push_back(glm::vec3(1.5f, 0.0f, 0.51f));
- vegetation.push_back(glm::vec3(0.0f, 0.0f, 0.7f));
- vegetation.push_back(glm::vec3(-0.3f, 0.0f, -2.3f));
- vegetation.push_back(glm::vec3(0.5f, 0.0f, -0.6f));
- //cube VAO
- unsigned int cubeVAO, cubeVBO;
- glGenVertexArrays(, &cubeVAO);
- glGenBuffers(, &cubeVBO);
- glBindVertexArray(cubeVAO);
- glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
- glEnableVertexAttribArray();
- glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
- glEnableVertexAttribArray();
- glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*)( * sizeof(float)));
- glBindVertexArray();
- //floor VAO
- unsigned int floorVAO, floorVBO;
- glGenVertexArrays(, &floorVAO);
- glGenBuffers(, &floorVBO);
- glBindVertexArray(floorVAO);
- glBindBuffer(GL_ARRAY_BUFFER, floorVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(floorVertices), floorVertices, GL_STATIC_DRAW);
- glEnableVertexAttribArray();
- glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
- glEnableVertexAttribArray();
- glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*)( * sizeof(float)));
- glBindVertexArray();
- unsigned grassVAO, grassVBO;
- glGenVertexArrays(, &grassVAO);
- glGenBuffers(, &grassVBO);
- glBindVertexArray(grassVAO);
- glBindBuffer(GL_ARRAY_BUFFER, grassVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(grassVertices), grassVertices, GL_STATIC_DRAW);
- glEnableVertexAttribArray();
- glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
- glEnableVertexAttribArray();
- glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*)( * sizeof(float)));
- //load textures
- stbi_set_flip_vertically_on_load(true);
- unsigned int cubeTexture = loadTexture("greenWall.jpg");
- unsigned int floorTexture = loadTexture("floor.jpg");
- unsigned int grassTexture = loadTexture("glass.png");
- shader.use();
- glUniform1i(glGetUniformLocation(shader.ID, "texture1"), );
- //render loop
- while (!glfwWindowShouldClose(window))
- {
- //per-frame time logic
- float currentFrame = glfwGetTime();
- deltaTime = currentFrame - lastFrame;
- lastFrame = currentFrame;
- //input
- processInput(window);
- //render
- glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- shader.use();
- glm::mat4 model;
- glm::mat4 view = camera.GetViewMatrix();
- glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
- shader.setMat4("view", view);
- glUniformMatrix4fv(glGetUniformLocation(shader.ID, "projection"), , GL_FALSE, glm::value_ptr(projection));
- //floor
- glBindVertexArray(floorVAO);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, floorTexture);
- shader.setMat4("model", glm::mat4());
- glDrawArrays(GL_TRIANGLES, , );
- //glBindVertexArray(0);
- //cube
- glBindVertexArray(cubeVAO);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, cubeTexture);
- model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
- glUniformMatrix4fv(glGetUniformLocation(shader.ID, "model"), , GL_FALSE, glm::value_ptr(model));
- glDrawArrays(GL_TRIANGLES, , );
- model = glm::mat4();
- model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f)); //the second cube
- shader.setMat4("model", model);
- glDrawArrays(GL_TRIANGLES, , );
- //我们把距离和它对应的位置向量存储到一个STL库的map数据结构中,map会自动根据健值(key)对它的值进行排序,
- //所以只要我们添加了所有的位置,并以他的距离作为键,它们就会自动根据距离值排序了
- std::map<float, glm::vec3> sorted;
- for (unsigned int i = ; i < vegetation.size(); i++)
- {
- float distance = glm::length(camera.Position - vegetation[i]);
- sorted[distance] = vegetation[i]; //一个距离对应一个位置
- }
- //结果就是一个排序后的容器对象,它根据distance健值从低到高存储了每个窗户的位置
- //之后,这次在渲染的时候,我们将以逆序(从远到近)从map中获取值,之后以正确的顺序绘制对应的窗户
- /*glBindVertexArray(grassVAO);
- glBindTexture(GL_TEXTURE_2D, grassTexture);
- for (std::map<float, glm::vec3>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++)
- {
- model = glm::mat4();
- model = glm::translate(model, it->second);
- shader.setMat4("model", model);
- glDrawArrays(GL_TRIANGLES, 0, 6);
- }*/
- glBindVertexArray(grassVAO);
- glBindTexture(GL_TEXTURE_2D, grassTexture);
- for (unsigned int i = ; i < vegetation.size(); i++)
- {
- model = glm::mat4();
- model = glm::translate(model, vegetation[i]);
- shader.setMat4("model", model);
- glDrawArrays(GL_TRIANGLES, , );
- }
- //glfw: swap buffers and poll IO events (keys pressed / released, mouse moved etc.)
- glfwSwapBuffers(window);
- glfwPollEvents();
- }
- //optional: de - allocate all resources once they've outlived their purpose;
- glDeleteVertexArrays(, &cubeVAO);
- glDeleteVertexArrays(, &floorVAO);
- glDeleteBuffers(, &cubeVBO);
- glDeleteBuffers(, &floorVBO);
- glfwTerminate();
- return ;
- }
- void processInput(GLFWwindow *window)
- {
- if (glfwGetKey(window, GLFW_KEY_ENTER) == GLFW_PRESS)
- glfwSetWindowShouldClose(window, true);
- if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
- camera.ProcessKeyboard(FORWARD, deltaTime);
- if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
- camera.ProcessKeyboard(BACKWARD, deltaTime);
- if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
- camera.ProcessKeyboard(LEFT, deltaTime);
- if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
- camera.ProcessKeyboard(RIGHT, deltaTime);
- }
- void framebuffer_size_callback(GLFWwindow* window, int width, int height)
- {
- glViewport(, , width, height);
- }
- void mouse_callback(GLFWwindow *window, double xpos, double ypos)
- {
- if (firstMouse)
- {
- lastX = xpos;
- lastY = ypos;
- firstMouse = false;
- }
- float xoffset = xpos - lastX;
- float yoffset = lastY - ypos;
- lastX = xpos;
- lastY = ypos;
- camera.ProcessMouseMovement(xoffset, yoffset);
- }
- void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
- {
- camera.ProcessMouseScroll(yoffset);
- }
- unsigned int loadTexture(char const *path)
- {
- unsigned int textureID;
- glGenTextures(, &textureID);
- int width, height, nrChannels;
- unsigned char *data = stbi_load(path, &width, &height, &nrChannels, );
- if (data)
- {
- GLenum format;
- if (nrChannels == )
- format = GL_RED;
- else if (nrChannels == )
- format = GL_RGB;
- else if (nrChannels == )
- format = GL_RGBA;
- glBindTexture(GL_TEXTURE_2D, textureID);
- //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- glTexImage2D(GL_TEXTURE_2D, , format, width, height, , format, GL_UNSIGNED_BYTE, data); //create a texture
- glGenerateMipmap(GL_TEXTURE_2D);
- /*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- stbi_image_free(data);
- }
- else
- {
- std::cout << "Texture failed to load at path: " << path << std::endl;
- stbi_image_free(data);
- }
- return textureID;
- }
Shader.h
- #ifndef SHADER_H_INCLUDE
- #define SHADER_H_INCLUDE
- #include <iostream>
- #include <string>
- #include <sstream>
- #include <fstream>
- #include <GL/glew.h>
- #include <GLFW/glfw3.h>
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtc/type_ptr.hpp>
- class Shader {
- public:
- unsigned int ID;
- Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
- {
- std::string vertexCode;
- std::string fragmentCode;
- std::ifstream vShaderFile;
- std::ifstream fShaderFile;
- vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
- fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
- try {
- //open files
- vShaderFile.open(vertexPath);
- fShaderFile.open(fragmentPath);
- std::stringstream vShaderStream, fShaderStream;
- //read file's buffer contents into streams
- vShaderStream << vShaderFile.rdbuf();
- fShaderStream << fShaderFile.rdbuf();
- //close file handlers
- vShaderFile.close();
- fShaderFile.close();
- //convert stream into string
- vertexCode = vShaderStream.str();
- fragmentCode = fShaderStream.str();
- }
- catch (std::ifstream::failure e)
- {
- std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;
- }
- const char* vShaderCode = vertexCode.c_str();
- const char* fShaderCode = fragmentCode.c_str();
- //2.compile shaders
- unsigned int vertex, fragment;
- int success;
- char infoLog[];
- //vertex shader
- vertex = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vertex, , &vShaderCode, NULL);
- glCompileShader(vertex);
- glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
- if (!success)
- {
- glGetShaderInfoLog(vertex, , NULL, infoLog);
- std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED!" << std::endl;
- }
- fragment = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fragment, , &fShaderCode, NULL);
- glCompileShader(fragment);
- glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
- if (!success)
- {
- glGetShaderInfoLog(fragment, , NULL, infoLog);
- std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED!" << std::endl;
- }
- ID = glCreateProgram();
- glAttachShader(ID, vertex);
- glAttachShader(ID, fragment);
- glLinkProgram(ID);
- glGetProgramiv(ID, GL_LINK_STATUS, &success);
- if (!success)
- {
- glGetProgramInfoLog(ID, , NULL, infoLog);
- std::cout << "ERROR::SHADER::PROGRAM::LINKTING_FAILED!" << std::endl;
- }
- //delete the shaders sa they are linked into our program now and no long necessary
- glDeleteShader(vertex);
- glDeleteShader(fragment);
- }
- //activate the shader
- void use()
- {
- glUseProgram(ID);
- }
- //utility uniform functions
- void setBool(const std::string &name, bool value) const
- {
- glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
- }
- void setInt(const std::string &name, int value) const
- {
- glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
- }
- void setFloat(const std::string &name, float value) const
- {
- glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
- }
- void setVec3(const std::string &name, const glm::vec3 &value) const
- {
- glUniform3fv(glGetUniformLocation(ID, name.c_str()), , &value[]);
- }
- void setVec3(const std::string &name, float x, float y, float z) const
- {
- glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
- }
- void setMat4(const std::string &name, glm::mat4 &trans) const
- {
- glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), , GL_FALSE, &trans[][]);
- }
- /*void setMat4(const std::string &name, glm::mat4 trans) const
- {
- //'trans': formal parameter with requested alignment of 16 won't be aligned,请求对齐的16的形式参数不会对齐
- glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, glm::value_ptr(trans));
- }*/
- };
- #endif
camera.h
- #ifndef CAMERA_H
- #define CAMERA_H
- #include <GL/glew.h>
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <vector>
- // Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
- enum Camera_Movement {
- FORWARD,
- BACKWARD,
- LEFT,
- RIGHT
- };
- // Default camera values
- const float YAW = -90.0f;
- const float PITCH = 0.0f;
- const float SPEED = 2.5f;
- const float SENSITIVITY = 0.1f;
- const float ZOOM = 45.0f;
- // An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL
- class Camera
- {
- public:
- // Camera Attributes
- glm::vec3 Position;
- glm::vec3 Front;
- glm::vec3 Up;
- glm::vec3 Right;
- glm::vec3 WorldUp;
- // Euler Angles
- float Yaw;
- float Pitch;
- // Camera options
- float MovementSpeed;
- float MouseSensitivity;
- float Zoom;
- // Constructor with vectors
- Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
- {
- Position = position;
- WorldUp = up;
- Yaw = yaw;
- Pitch = pitch;
- updateCameraVectors();
- }
- // Constructor with scalar values
- Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
- {
- Position = glm::vec3(posX, posY, posZ);
- WorldUp = glm::vec3(upX, upY, upZ);
- Yaw = yaw;
- Pitch = pitch;
- updateCameraVectors();
- }
- // Returns the view matrix calculated using Euler Angles and the LookAt Matrix
- glm::mat4 GetViewMatrix()
- {
- return glm::lookAt(Position, Position + Front, Up);
- }
- // Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
- void ProcessKeyboard(Camera_Movement direction, float deltaTime)
- {
- float velocity = MovementSpeed * deltaTime;
- if (direction == FORWARD)
- Position += Front * velocity;
- if (direction == BACKWARD)
- Position -= Front * velocity;
- if (direction == LEFT)
- Position -= Right * velocity;
- if (direction == RIGHT)
- Position += Right * velocity;
- }
- // Processes input received from a mouse input system. Expects the offset value in both the x and y direction.
- void ProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true)
- {
- xoffset *= MouseSensitivity;
- yoffset *= MouseSensitivity;
- Yaw += xoffset;
- Pitch += yoffset;
- // Make sure that when pitch is out of bounds, screen doesn't get flipped
- if (constrainPitch)
- {
- if (Pitch > 89.0f)
- Pitch = 89.0f;
- if (Pitch < -89.0f)
- Pitch = -89.0f;
- }
- // Update Front, Right and Up Vectors using the updated Euler angles
- updateCameraVectors();
- }
- // Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
- void ProcessMouseScroll(float yoffset)
- {
- if (Zoom >= 1.0f && Zoom <= 45.0f) //zoom缩放,就是视野
- Zoom -= yoffset;
- if (Zoom <= 1.0f)
- Zoom = 1.0f;
- if (Zoom >= 45.0f)
- Zoom = 45.0f;
- }
- private:
- // Calculates the front vector from the Camera's (updated) Euler Angles
- void updateCameraVectors()
- {
- // Calculate the new Front vector
- glm::vec3 front;
- front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
- front.y = sin(glm::radians(Pitch));
- front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
- Front = glm::normalize(front);
- // Also re-calculate the Right and Up vector
- Right = glm::normalize(glm::cross(Front, WorldUp)); // Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
- Up = glm::normalize(glm::cross(Right, Front));
- }
- };
- #endif
图片:
高级openg 混合,一个完整程序的更多相关文章
- yii2高级模板使用一个域名管理前后台
yii2的高级模板分为backend和frontend,最开始用yii的时候并没怎么在意,就使用了两个域名分别解析前后台.今天无意间看见 可以使用一个域名指向前后台. 1.修改 advanced/ba ...
- python高级编程 编写一个包1
#目的是:编写,发行python包可重复过程"""1:是缩短开始真正工作之前所需要的设置时间,也就是提供模板2:提供编写包的标准化方法3:简化测试驱动开发方法的使用4:为 ...
- Java高级特性--自定义一个StringBuilder的类
案例讲解--自定义一个StringBuilder的类 一:案例设计介绍 自义一个M定yStringBuilder来实现StringBuilder的功能 二:案例设计 实现append()方法追加字符串 ...
- constraintLayout的一些高级用法 布局一个16:9的图片 以及GuideLine的使用
<!-- "W,9:16" 同样的效果 --> <ImageView android:layout_width="0dp" android:l ...
- Java高级应用(一个)-文件夹监控服务
最近.在研究一些比较成熟的框架.他们还发现,他们中的一些相当不错的文章.现在,对于一些在你们中间一个简单的翻译(版的英文文章,非常有帮助). 译:原文链接 你有没有发现,当你编辑一个文件.同一时候使用 ...
- Yii2 高级版新建一个 Api 应用
原文地址:http://www.getyii.com/topic/28 先在项目的根目录下复制一份 backend 为 api: cp backend/ api -r 拷贝 api 环境 cp -a ...
- UNIX环境高级编程——初始化一个守护进程
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h&g ...
- yii2 高级版新建一个应用(api应用为例子)
先在项目的根目录下复制一份 backend 为 api: cp backend/ api -r 拷贝 api 环境 cp -a environments/dev/frontend environmen ...
- webdriver高级应用- 改变一个页面对象的属性值
适用于一些无法操作的元素,可以直接改他的属性从而操作,代码如下: #encoding=utf-8 from selenium import webdriver import unittest impo ...
随机推荐
- Oracle hint手动优化
例子 select/*+FULL(fortest)*/ * from fortest where id = 2000000 //使用0.70s时间 select* from fortest where ...
- 从Oracle数据库中的本地命名文件tnsnames.ora来看服务别名、服务名和实例名的区别。
tnsnames.ora的作用这里就不多述了,各位应该都知道. 首先先看两个例子: test1 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCO ...
- git中工作区,缓存区,本地库,远程库的简要区别
git中工作区,缓存区,本地库,远程库的简要区别 实际上前三个名词对应到实体,都是你从远程仓库克隆下来的那个项目目录!只不过工作区就是你实际看到的目录和目录里的内容,当你修改/添加/删除了从远程仓库c ...
- [转]JavaScript与元素间的抛物线轨迹运动
在张鑫旭的博客看到这个抛物线的小动画,觉得很感兴趣,转载一下方便研究~ 原文地址:http://www.zhangxinxu.com/wordpress/?p=3855 在页面上添加元素的位移动画,除 ...
- react native 之 获取键盘高度
多说不如多撸: /** * Created by shaotingzhou on 2017/2/23. *//** * Sample React Native App * https://github ...
- js--call( )/apply()/bind()--应用
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call funct ...
- MongDB篇,第四章:数据库知识4
MongDB 数据库知识4 GridFS 大文件存储 文件的数据库存储 1,在数据库中以 字符串的方式 存储文件在本地的路径: 优点: 节省数据库空间 缺点: 当数据库或者文件位置发生变化时则无 ...
- SpringBoot 配置文件详解
springboot采纳了建立生产就绪spring应用程序的观点. Spring Boot优先于配置的惯例,旨在让您尽快启动和运行.在一般情况下,我们不需要做太多的配置就能够让spring boot正 ...
- base标签对svg的影响
页面地址:http://127.0.0.1:8080/fullLink_node.html?project_id=2 base:<base href="http://127.0.0.1 ...
- 利用selenium模拟登录webqq
from selenium import webdriver import selenium.webdriver.support.ui as ui import time opt = webdrive ...