OpenGL — GLFW — 颜色

来源:互联网 发布:伦敦金投资软件 编辑:程序博客网 时间:2024/06/07 08:10

OpenGL — GLFW — 颜色

参考教程:https://learnopengl-cn.readthedocs.io/zh/latest/02%20Lighting/01%20Colors/

既然,网络上已经有现成的教程了,我为什么还有在写一遍教程呢?
这个教程不是给大家写的,而是给我自己写的,算是我的学习笔记吧。我将编程序的重点提起出来,并将我的经验和遇到的问题记下来,为日后的我做参考用的。知识会随着时间的流过,而慢慢的被遗忘,当日后有一个项目要用到OpenGL的知识时,那个时候的我可能已经将当初学到的OpenGL忘记的擦不多了,这个时候,我就需要过去的我来帮助我,可以这样理解,跨越时空的两个我在完成一个项目!不错,这就是记笔记的作用。

给模型上颜色,两个步骤:

  1. 编写片段着色器
  2. 在主程序中给片段着色器赋值
  3. 在主主函数中,使用片段着色器

你可能会问,颜色有什么好讲的?我想说:你问对了,真的没有什么好讲的。就是定义一个变量:

glm::vec3 color(1.0f, 0.5f, 0.31f);   // 珊瑚红(Coral)

编写程序步骤

第1步:

程序

先顶点着色器程序,就用个精简版的程序:(顶点着色器(Vertex Shader)文件名为:color.vs

#version 330 corelayout (location = 0) in vec3 position;uniform mat4 model;uniform mat4 view;uniform mat4 projection;void main(){    gl_Position = projection * view * model * vec4(position, 1.0f);}

解释

layout (location = 0) in vec3 position;

得到CPP程序中是ID是0的数据,将ID为0的数据的物理意义定义为顶点位置

uniform mat4 model;uniform mat4 view;uniform mat4 projection;

这些变量是需要在CPP程序中等待赋值的。
归根结底,这三个变量都是4*4的矩阵,都是作用于模型的每一个顶点的。
但是他们代表着不同的物理意义:

model 模型自身的姿态矩阵。姿态旋转平移组成。 view 摄像机姿态矩阵。 projection 透视矩阵。
void main(){    gl_Position = projection * view * model * vec4(position, 1.0f);}

gl_PositionGLSL(OpenGL Shading Language)着色语言中的一个内置变量,即输出的顶点位置。

总结:这个顶点着色器的作用就是:更新顶点的位置

第2步:

程序

编写片段着色器:(片段着色器(Fragment shader)文件命名为:color.frag

#version 330 coreout vec4 color;uniform vec3 objectColor;uniform vec3 lightColor;void main(){    color = vec4(lightColor * objectColor, 1.0f);}

讲解

out vec4 color;

输出的color变量。

uniform vec3 objectColor;uniform vec3 lightColor;

这两个值在CPP程序中被赋值,分别表示物体色光源颜色

void main(){    color = vec4(lightColor * objectColor, 1.0f);}

将光源颜色与物体颜色相乘,即两个向量相乘,得到最终的颜色。因为定义的color4维向量,objectColorlightColor3维向量。所以这里给color赋值的时候要这样做color = vec4(vec3, 1.0f);

总结: 这个片段着色器做的事情:更新物体颜色。

第3步

编写CPP程序模板

#include <iostream>#include <cmath>// GLEW#define GLEW_STATIC#include <GL/glew.h>// GLFW#include <GLFW/glfw3.h>// Other Libs#include <SOIL.h>// GLM Mathematics#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>// Other includes#include <learnopengl\shader.h>#include <learnopengl\camera.h>#include <learnopengl\model.h>// Function prototypesvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);void mouse_callback(GLFWwindow* window, double xpos, double ypos);void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);void do_movement();// Window dimensionsconst GLuint WIDTH = 800, HEIGHT = 800;// CameraCamera  camera(glm::vec3(0.0f, 0.0f, 3.0f));GLfloat lastX  =  WIDTH  / 2.0;GLfloat lastY  =  HEIGHT / 2.0;bool    keys[1024];// DeltatimeGLfloat deltaTime = 0.0f;   // Time between current frame and last frameGLfloat lastFrame = 0.0f;   // Time of last frame// The MAIN function, from here we start the application and run the game loopint main(){    // Init GLFW    glfwInit();    // Set all the required options for GLFW    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);    // Create a GLFWwindow object that we can use for GLFW's functions    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "AoboSir OpenGL", nullptr, nullptr);    glfwMakeContextCurrent(window);    // Set the required callback functions    glfwSetKeyCallback(window, key_callback);    glfwSetCursorPosCallback(window, mouse_callback);    glfwSetScrollCallback(window, scroll_callback);    // GLFW Options    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);    // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions    glewExperimental = GL_TRUE;    // Initialize GLEW to setup the OpenGL Function pointers    glewInit();    // Define the viewport dimensions    glViewport(0, 0, WIDTH, HEIGHT);    // OpenGL options    glEnable(GL_DEPTH_TEST);    //定义着色器类对象    //定义模型类对象    // Game loop    while (!glfwWindowShouldClose(window))    {        // Calculate deltatime of current frame        GLfloat currentFrame = glfwGetTime();        deltaTime = currentFrame - lastFrame;        lastFrame = currentFrame;        // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions        glfwPollEvents();        do_movement();        // Clear the colorbuffer        //glClearColor(0.1f, 0.1f, 0.1f, 1.0f);        glClearColor(0.41f, 0.41f, 0.41f, 1.0f);        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        //给着色器进行赋值        //让模型使用这个着色器对象,显示模型        // Swap the screen buffers        glfwSwapBuffers(window);    }    // Terminate GLFW, clearing any resources allocated by GLFW.    glfwTerminate();    return 0;}// Is called whenever a key is pressed/released via GLFWvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode){    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)        glfwSetWindowShouldClose(window, GL_TRUE);    if (key >= 0 && key < 1024)    {        if (action == GLFW_PRESS)            keys[key] = true;        else if (action == GLFW_RELEASE)            keys[key] = false;    }}void do_movement(){    // Camera controls    if (keys[GLFW_KEY_W])        camera.ProcessKeyboard(FORWARD, deltaTime);    if (keys[GLFW_KEY_S])        camera.ProcessKeyboard(BACKWARD, deltaTime);    if (keys[GLFW_KEY_A])        camera.ProcessKeyboard(LEFT, deltaTime);    if (keys[GLFW_KEY_D])        camera.ProcessKeyboard(RIGHT, deltaTime);}bool firstMouse = true;void mouse_callback(GLFWwindow* window, double xpos, double ypos){    if(glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT )){        if (firstMouse)        {            lastX = xpos;            lastY = ypos;            firstMouse = false;        }        GLfloat xoffset = xpos - lastX;        GLfloat yoffset = ypos - lastY;  // Reversed since y-coordinates go from bottom to left        lastX = xpos;        lastY = ypos;        camera.ProcessMouseMovement(glm::radians(xoffset), glm::radians(yoffset));    } else {        firstMouse = true;    }}void scroll_callback(GLFWwindow* window, double xoffset, double yoffset){    camera.ProcessMouseScroll(glm::radians(yoffset) );}

注意:
1. glm::radians(angle)这个函数是将输入的角度转换为弧度。
2. glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT ) 函数,如果鼠标左键按下,函数会返回非零数据;如果鼠标左键没有被按下,函数会返回0.

第4步

定义着色器对象和模型对象,给着色器对象赋值,并让模型对象使用着色器对象,显示模型。

定义着色器对象和模型对象

    //定义着色器类对象    // Build and compile our shader program    Shader lightingShader("shader/color.vs", "shader/color.frag");    Shader lampShader("shader/lamp.vs", "shader/lamp.frag");    //定义模型类对象    Model ourModel("meshes/TexMesh.obj");    Model lampModel("meshes/Light_Bulb.obj");

给着色器进行赋值

        //给着色器进行赋值        // Use cooresponding shader when setting uniforms/drawing objects        lightingShader.Use();        GLint objectColorLoc = glGetUniformLocation(lightingShader.Program, "objectColor");        GLint lightColorLoc  = glGetUniformLocation(lightingShader.Program, "lightColor");        glUniform3f(objectColorLoc, 1.0f, 0.5f, 0.31f);        glUniform3f(lightColorLoc,  1.0f, 1.0f, 1.0f);        // Create camera transformations        glm::mat4 view;        view = camera.GetViewMatrix();        glm::mat4 projection = glm::perspective(camera.Zoom, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);        // Get the uniform locations        GLint modelLoc = glGetUniformLocation(lightingShader.Program, "model");        GLint viewLoc  = glGetUniformLocation(lightingShader.Program,  "view");        GLint projLoc  = glGetUniformLocation(lightingShader.Program,  "projection");        // Pass the matrices to the shader        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));        // Draw the loaded model        glm::mat4 model;        model = glm::scale(model, glm::vec3(0.2f, 0.2f, 0.2f)); // It's a bit too big for our scene, so scale it down        glUniformMatrix4fv(glGetUniformLocation(lightingShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));

让模型使用这个着色器对象,显示模型

        //让模型使用这个着色器对象,显示模型        ourModel.Draw(lightingShader);

大功告成,第6步,运行程序

Alt text
(这其实是以一张倒人脸的背面,你现在看到的是一片珊瑚红色,是因为在我们的这个着色器是最简单的着色器,并且我们没有使用模型的点的法线向量,所以没有阴影的效果。)

我们继续学习下一课。


参考网站:
http://www.cnblogs.com/zhanglitong/p/3209282.html
http://www.glfw.org/docs/latest/group__input.html#gac1473feacb5996c01a7a5a33b5066704
http://learnopengl.com/code_viewer.php?code=model_loading/model_diffuse
下载一个灯泡模型:http://tf3dm.com/3d-model/light-bulb-simple-studio-9032.html

0 0
原创粉丝点击