Opengl绘制STL模型

  • 实现效果
  • STL模型文件
  • 实现代码

实现效果

首先先看看使用可编程管线实现的STL模型的渲染效果,网格模型的数量大约在100来万,实现的效果还是挺鲁棒。

STL模型文件

关于STL的文件格式主要包括以下两种:

  • ASCII格式
  • 二进制格式

实现代码

filesystem.h文件

#ifndef FILESYSTEM_H
#define FILESYSTEM_H#include <string>
#include <cstdlib>
#include "root_directory.h" // This is a configuration file generated by CMake.class FileSystem
{private:typedef std::string (*Builder) (const std::string& path);public:static std::string getPath(const std::string& path){static std::string(*pathBuilder)(std::string const &) = getPathBuilder();return (*pathBuilder)(path);}private:static std::string const & getRoot(){static char const * envRoot = getenv("LOGL_ROOT_PATH");static char const * givenRoot = (envRoot != nullptr ? envRoot : logl_root);static std::string root = (givenRoot != nullptr ? givenRoot : "");return root;}//static std::string(*foo (std::string const &)) getPathBuilder()static Builder getPathBuilder(){if (getRoot() != "")return &FileSystem::getPathRelativeRoot;elsereturn &FileSystem::getPathRelativeBinary;}static std::string getPathRelativeRoot(const std::string& path){return getRoot() + std::string("/") + path;}static std::string getPathRelativeBinary(const std::string& path){return "../../../" + path;}};// FILESYSTEM_H
#endif

shader_m.h文件

#ifndef SHADER_H
#define SHADER_H#include <glad/glad.h>
#include <glm/glm.hpp>#include <string>
#include <fstream>
#include <sstream>
#include <iostream>class Shader
{public:unsigned int ID;// constructor generates the shader on the fly// ------------------------------------------------------------------------Shader(const char* vertexPath, const char* fragmentPath){// 1. retrieve the vertex/fragment source code from filePathstd::string vertexCode;std::string fragmentCode;std::ifstream vShaderFile;std::ifstream fShaderFile;// ensure ifstream objects can throw exceptions:vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);try {// open filesvShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);std::stringstream vShaderStream, fShaderStream;// read file's buffer contents into streamsvShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();        // close file handlersvShaderFile.close();fShaderFile.close();// convert stream into stringvertexCode = vShaderStream.str();fragmentCode = fShaderStream.str();           }catch (std::ifstream::failure& e){std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ: " << e.what() << std::endl;}const char* vShaderCode = vertexCode.c_str();const char * fShaderCode = fragmentCode.c_str();// 2. compile shadersunsigned int vertex, fragment;// vertex shadervertex = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex, 1, &vShaderCode, NULL);glCompileShader(vertex);checkCompileErrors(vertex, "VERTEX");// fragment Shaderfragment = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragment, 1, &fShaderCode, NULL);glCompileShader(fragment);checkCompileErrors(fragment, "FRAGMENT");// shader ProgramID = glCreateProgram();glAttachShader(ID, vertex);glAttachShader(ID, fragment);glLinkProgram(ID);checkCompileErrors(ID, "PROGRAM");// delete the shaders as they're linked into our program now and no longer necesseryglDeleteShader(vertex);glDeleteShader(fragment);}// activate the shader// ------------------------------------------------------------------------void use() const{ glUseProgram(ID); }// utility uniform functions// ------------------------------------------------------------------------void setBool(const std::string &name, bool value) const{         glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)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 setVec2(const std::string &name, const glm::vec2 &value) const{ glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); }void setVec2(const std::string &name, float x, float y) const{ glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y); }// ------------------------------------------------------------------------void setVec3(const std::string &name, const glm::vec3 &value) const{ glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); }void setVec3(const std::string &name, float x, float y, float z) const{ glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); }// ------------------------------------------------------------------------void setVec4(const std::string &name, const glm::vec4 &value) const{ glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); }void setVec4(const std::string &name, float x, float y, float z, float w) const{ glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w); }// ------------------------------------------------------------------------void setMat2(const std::string &name, const glm::mat2 &mat) const{glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);}// ------------------------------------------------------------------------void setMat3(const std::string &name, const glm::mat3 &mat) const{glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);}// ------------------------------------------------------------------------void setMat4(const std::string &name, const glm::mat4 &mat) const{glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);}private:// utility function for checking shader compilation/linking errors.// ------------------------------------------------------------------------void checkCompileErrors(GLuint shader, std::string type){GLint success;GLchar infoLog[1024];if (type != "PROGRAM"){glGetShaderiv(shader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(shader, 1024, NULL, infoLog);std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;}}else{glGetProgramiv(shader, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(shader, 1024, NULL, infoLog);std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;}}}
};
#endif

camera.文件

#ifndef CAMERA_H
#define CAMERA_H#include <glad/glad.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 Attributesglm::vec3 Position;glm::vec3 Front;glm::vec3 Up;glm::vec3 Right;glm::vec3 WorldUp;// euler Anglesfloat Yaw;float Pitch;// camera optionsfloat MovementSpeed;float MouseSensitivity;float Zoom;// constructor with vectorsCamera(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 valuesCamera(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 Matrixglm::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 flippedif (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 anglesupdateCameraVectors();}// processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axisvoid ProcessMouseScroll(float yoffset){Zoom -= (float)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 Anglesvoid updateCameraVectors(){// calculate the new Front vectorglm::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 vectorRight = 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
//头文件可以去learnopengl中获得,太多了这边不一一给出了
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>#include <learnopengl/filesystem.h>
#include <learnopengl/shader_m.h>
#include <learnopengl/camera.h>
#include <learnopengl/model.h>#include <iostream>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);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;// camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = SCR_WIDTH / 2.0f;
float lastY = SCR_HEIGHT / 2.0f;
bool firstMouse = true;// timing
float deltaTime = 0.0f;
float lastFrame = 0.0f;
// lighting
glm::vec3 lightPos(1.2f, 1.0f, 5.0f);
int main()
{// glfw: initialize and configure// ------------------------------glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif// glfw window creation// --------------------GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);glfwSetCursorPosCallback(window, mouse_callback);glfwSetScrollCallback(window, scroll_callback);// tell GLFW to capture our mouseglfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);// glad: load all OpenGL function pointers// ---------------------------------------if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}// tell stb_image.h to flip loaded texture's on the y-axis (before loading model).stbi_set_flip_vertically_on_load(true);// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// build and compile shaders// -------------------------Shader ourShader("1.model_loading.vs", "1.model_loading.fs");Shader lightCubeShader("4.2.light_cube.vs", "4.2.light_cube.fs");float vertices[] = {-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,-0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,-0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,-0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,-0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,-0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,-0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,-0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,-0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f};// first, configure the cube's VAO (and VBO)unsigned int VBO, cubeVAO;glGenVertexArrays(1, &cubeVAO);glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindVertexArray(cubeVAO);// position attributeglVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// normal attributeglVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);// second, configure the light's VAO (VBO stays the same; the vertices are the same for the light object which is also a 3D cube)unsigned int lightCubeVAO;glGenVertexArrays(1, &lightCubeVAO);glBindVertexArray(lightCubeVAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);// note that we update the lamp's position attribute's stride to reflect the updated buffer dataglVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// load models// -----------Model ourModel[3];ourModel[0]= Model(FileSystem::getPath("resources/objects/backpack/Pikachu_X_Thor.stl"));ourModel[1] = Model(FileSystem::getPath("resources/objects/backpack/Wedding pikachu with sofa.stl"));ourModel[2] = Model(FileSystem::getPath("resources/objects/backpack/kitten.stl"));//draw in wireframe//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);// render loop// -----------while (!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame = static_cast<float>(glfwGetTime());deltaTime = currentFrame - lastFrame;lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(1.0f, 1.0f, 1.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// don't forget to enable shader before setting uniformsourShader.use();ourShader.setVec3("objectColor", 248.0f/255.0f, 235.0f/255.0f, 214.0f/255.0f);ourShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);ourShader.setVec3("lightPos", lightPos);ourShader.setVec3("viewPos", camera.Position);int spvalue = 256;ourShader.setInt("spvalue", spvalue);// view/projection transformationsglm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);glm::mat4 view = camera.GetViewMatrix();ourShader.setMat4("projection", projection);ourShader.setMat4("view", view);// render the loaded modelglm::mat4 model = glm::mat4(1.0f);model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); // translate it down so it's at the center of the scenemodel = glm::rotate(model, glm::radians(-60.0f), glm::vec3(1.0f,0.0f,0.0f));model = glm::scale(model, glm::vec3(0.05f, 0.05f, 0.05f));  // it's a bit too big for our scene, so scale it downourShader.setMat4("model", model);ourModel[0].Draw(ourShader);ourShader.setVec3("objectColor", 181.0f/255.0f, 196.0f/255.0f, 177.0f/255.0f);ourShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);ourModel[1].Draw(ourShader);ourShader.setVec3("objectColor", 193.0f / 255.0f, 204.0f / 255.0f, 214.0f / 255.0f);ourShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);ourModel[2].Draw(ourShader);lightCubeShader.use();lightCubeShader.setMat4("projection", projection);lightCubeShader.setMat4("view", view);model = glm::mat4(1.0f);model = glm::translate(model, lightPos);model = glm::scale(model, glm::vec3(0.2f)); // a smaller cubelightCubeShader.setMat4("model", model);glBindVertexArray(lightCubeVAO);glDrawArrays(GL_TRIANGLES, 0, 36);// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// glfw: terminate, clearing all previously allocated GLFW resources.// ------------------------------------------------------------------glfwTerminate();return 0;
}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == 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);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}// glfw: whenever the mouse moves, this callback is called
// -------------------------------------------------------
void mouse_callback(GLFWwindow* window, double xposIn, double yposIn)
{float xpos = static_cast<float>(xposIn);float ypos = static_cast<float>(yposIn);if (firstMouse){lastX = xpos;lastY = ypos;firstMouse = false;}float xoffset = xpos - lastX;float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to toplastX = xpos;lastY = ypos;camera.ProcessMouseMovement(xoffset, yoffset);
}// glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ----------------------------------------------------------------------
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{camera.ProcessMouseScroll(static_cast<float>(yoffset));
}

加载模型顶点着色器

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;out vec3 FragPos;
out vec3 Normal;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{FragPos = vec3(model * vec4(aPos, 1.0));Normal = mat3(transpose(inverse(model))) * aNormal;  gl_Position = projection * view * vec4(FragPos, 1.0);
}

加载模型片段着色器

#version 330 core
out vec4 FragColor;in vec3 Normal;
in vec3 FragPos;  uniform vec3 lightPos;
uniform vec3 viewPos;
uniform vec3 lightColor;
uniform vec3 objectColor;
uniform int spvalue;
void main()
{// ambientfloat ambientStrength = 0.1;vec3 ambient = ambientStrength * lightColor;// diffuse vec3 norm = normalize(Normal);vec3 lightDir = normalize(lightPos - FragPos);float diff = max(dot(norm, lightDir), 0.0);vec3 diffuse = diff * lightColor;// specularfloat specularStrength = 0.5;vec3 viewDir = normalize(viewPos - FragPos);vec3 reflectDir = reflect(-lightDir, norm);  float spec = pow(max(dot(viewDir, reflectDir), 0.0), spvalue);vec3 specular = specularStrength * spec * lightColor;  vec3 result = (ambient + diffuse + specular) * objectColor;FragColor = vec4(result, 1.0);
}

光源顶点着色器

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

光源片段着色器

#version 330 core
out vec4 FragColor;void main()
{FragColor = vec4(1.0); // set alle 4 vector values to 1.0
}

线框模式下得到的结果如下:

网格放大如图所示:

OpenGL渲染STL三角网格模型相关推荐

  1. 三角网格模型及基于RBF隐曲面方程求解的曲面重建

    资料来源:径向基函数和神经网络技术在逆向工程中的应用研究(博士论文:王宏涛) RBF神经网络模型 RBF神经网络起源于数值分析中多变量插值的RBF方法,1988年Broomhead等人首先将该算法应用 ...

  2. 图形处理(十二)拉普拉斯网格优化、最小二乘网格模型光顺

    看这篇博文前,请先参考我的另外一篇博文<图形处理(三)简单拉普拉斯网格变形-Siggraph 2004>学习拉普拉斯坐标的相关理论知识.这里要分享的paper,是通过拉普拉斯的方法实现三角 ...

  3. VTK修炼之道46:图形基本操作进阶_三角网格体积、表面积、测地距离、包围盒

    1.基本图形操作意义 图形处理,比如图形平滑.多分辨率分析.特征提取等都离不开一些基本的图形操作.掌握这些基本的图形操作有助于理解和深入学习图形处理和分析方法. VTK中提供了多种图形的基本操作,其中 ...

  4. Siggraph三角网格变形之拉普拉斯变换

    三角网格变形一直是CAGD相关领域的重点,刚上研究生的时候,感觉有点神奇.而且一上来导师就给我发了一篇基于格林坐标的自由变形的相关paper,让我看,外文文献,看了n多天,第一次看外文文献,啥也没看懂 ...

  5. bullet物理引擎与OpenGL结合 导入3D模型进行碰撞检测 以及画三角网格的坑

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/11681069.html 一.初始化世界以及模型 /// 冲突配置包含内存的默认设置,冲突设置. ...

  6. android OpenGL渲染3D模型文件

    码字不易,转载请注明出处喔 https://blog.csdn.net/newchenxf/article/details/121402859 1 前言 大部分OpenGL示例代码,要么播放个视频,要 ...

  7. opengl加载显示3D模型STL类型文件

    opengl加载显示3D模型STL类型文件 前置条件 注意事项 项目展示 项目完整C++源代码 前置条件 opengl三方库freeglut,显示STL格式的三维模型文件 注意事项 源代码 model ...

  8. 几何实体图形保存成stl格式的ascII和二进制文。用matlab语言读入文件,给三角网格坐标值乘以2,并保存到另一stl文件。输出完成工作所用的执行时间

    1.题目: CAD/CAM软件生成几何实体图形,图形形状不限,但图形需包含曲面,分别保存成stl格式的ascII和二进制文.用matlab语言读入文件,给所有三角网格坐标值乘以2,并保存到另一stl文 ...

  9. OpenGL渲染模型 || 3. opengl 将模型成渲染图片

    前言 最近项目中需要使用到OpenGL对3D模型进行渲染. 已有数据为: 带纹理的3D模型 模型上的关键点.   需要实现的功能: 读取和保存 带纹理的3D模型.读取模型的关键点 对模型进行渲染,保存 ...

最新文章

  1. 动画原理与实现 浅析
  2. 动态网站的技术路线_3个好玩实用小网站!闲暇时间不妨打开看看
  3. 《读书报告 – Elasticsearch入门 》----Part II 深入搜索(2)
  4. java冒泡排序法对数组进行排序
  5. 《面向机器智能的TensorFlow实践》一 2.8 测试TensorFlow、Jupyter Notebook及matplotlib...
  6. php file取不到手机相册,webuploader移动端选择文件无法打开手机相册的解决办法...
  7. 【大数据】Azkaban学习笔记
  8. 两款扒站工具使用说明
  9. FFMPEG框架学习——(2)视频的提取和解码
  10. python 爬取歌曲程序_如何让程序像人一样的去批量下载歌曲?Python爬取付费歌曲...
  11. 华为设备配置MAC地址
  12. 容斥原理(二进制实现)
  13. vue 给iframe设置src_vue 中引入iframe,动态设置其src,遇到的一些小问题总结
  14. SCI论文怎么投,投稿流程和经验分享一文了解
  15. 【GEE笔记】有效像元(面积、数量)统计
  16. stc89c52c语言开发,STC89C52单片机开发板入门教程——简介(致雅科技)
  17. 真正爱一个人,是可以无私的付出
  18. 一文速读阿里云ET大脑 ——阿里云机器智能首席科学家闵万里详解数字驱动的智能之路...
  19. laravel5.8(二十一)laravel查询结果集转为数组的方法
  20. 联想yoga2触摸双指右击_评论:关于三台联想笔记本电脑的故事-X1 Carbon Touch,ThinkPad Yoga,IdeaPad Yoga 2 Pro

热门文章

  1. Springboot之@Async异步指定自定义线程池使用
  2. wps设置子标题编号继承上级标题
  3. HbuildX 用vue打包app调用微信支付
  4. php第三方扣扣登陆,thinkphp3.2 实现qq第三方登录
  5. java自定义校验注解
  6. C++中_findnext()函数触发断点问题
  7. linux clock头文件,Linux common clock framework(1)_概述
  8. html.action 访问分部视图,MVC+EF 随笔小计——分部视图(Partial View)及Html.Partial和Html.Action差异...
  9. Web前端第四季(jQuery):四:301-jQuery基本过滤器(奇数和偶数)+302-实现隔行换色+401-祖先选择器和子代选择器
  10. UVa 136 - Ugly Numbers