Skip to content
  • 首页
  • 留言
  • 关于

Share the joys of programming and technology

OpenGL雾化效果实现-每像素雾化

OpenGL雾化效果实现-每像素雾化

2022年1月21日 liyanliang Comments 0 Comment
阅读次数: 508

Contents

  • 1 雾化实现原理
  • 2 shader代码实现:
  • 3 完整项目代码:
  • 4 相关文章

雾化实现原理

雾背后的基本思想是,物体离相机越远,它应该被雾覆盖得越多,因此就越不可见。 因为我们现在拥有现代 GPU,所以我们可以检查场景的每个片段有多远并计算雾。 我们需要得到一个叫做雾因子的东西,它是一个从 0.0 到 1.0 的数字,简单地说,应该对那个片段应用多少雾。 如果为零,则没有雾,如果为 1.0,则对象完全被雾覆盖。 介于两者之间的任何东西都会使物体出现/迷失在迷雾中。

雾需要三个控制变量:

  struct Fog {
      vec4  color;  // 颜色
      float range;  // 范围
      float density; // 强度
  };

雾强度因子的计算:

      vec3    viewPos =   vec3(view * vec4(outPosition,1));
      float   eyeDist =   length(viewPos);
      float   fogIntensity   =   (fog.range - eyeDist) * fog.density;
      fogIntensity   =   clamp(fogIntensity, 0.0, 1.0);

关于clamp函数:

  genType clamp (genType x, float minVal, float maxVal)

clamp翻译为夹具,就叫夹具函数吧,这个函数是什么意思呢?看看解释的意思是:获取x和minVal之间较大的那个值,然后再拿较大的那个值和最后那个最大的值进行比较然后获取较小的那个,意思就明白了,clamp实际上是获得三个参数中大小处在中间的那个值。函数有个说明:如果minVal > minMax的话,函数返回的结果是未定的。也就是说x的值大小没有限制,但是minval的值必须比maxVal小。

像素颜色计算:

  FragColor = mix(objectColor, fog.color, 1-fogIntensity);

关于mix()函数:

mix(x,y,a) a控制混合结果 return x(1-a) +y*a 返回 线性混合的值。

shader代码实现:

shaderFog_fragment.vs

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

shaderFog_fragment.fs

#version 330 core
out vec4 FragColor;

struct Material {
    sampler2D diffuse;
    sampler2D specular;    
    float shininess;
}; 

struct Light {
    //vec3 position;
    vec3 direction;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

struct Fog {
    vec4  color;
    float range;
    float density;
};

in vec3 FragPos;  
in vec3 Normal;  
in vec2 TexCoords;

in vec3 outPosition;
uniform mat4 view; 

uniform vec3 viewPos;
uniform Material material;
uniform Light light;
uniform Fog fog;

void main()
{
    // fog
	vec3    viewPos =   vec3(view * vec4(outPosition,1));
    float   eyeDist =   length(viewPos);
    float   fogIntensity   =   (fog.range - eyeDist) * fog.density;
    fogIntensity   =   clamp(fogIntensity, 0.0, 1.0);
										
    // ambient
    vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb;
  	
    // diffuse 
    vec3 norm = normalize(Normal);
    // vec3 lightDir = normalize(light.position - FragPos);
    vec3 lightDir = normalize(-light.direction);  
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb;  
    
    // specular
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);  
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb;  
        
    vec3 result = ambient + diffuse + specular;
    //FragColor = vec4(result, 1.0);
	vec4 OutColor = vec4(result, 1.0);
	FragColor = mix(OutColor, fog.color, 1-fogIntensity);
} 

main.cpp

  #include <glad/glad.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 <learnopengl/shader_m.h>
  #include <learnopengl/camera.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);
  unsigned int loadTexture(const char *path);
  ​
  // settings
  const unsigned int SCR_WIDTH = 800;
  const unsigned int SCR_HEIGHT = 600;
  ​
  // camera
  Camera camera(glm::vec3(0.0f, 1.0f, 10.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;
  ​
  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, "ShaderFog", 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 mouse
      //glfwSetInputMode(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;
      }
  ​
      // configure global opengl state
      // -----------------------------
      glEnable(GL_DEPTH_TEST);
  ​
      // build and compile shaders
      // -------------------------
      Shader lightingShader("shaderFog_fragment.vs", "shaderFog_fragment.fs");
  ​
      // set up vertex data (and buffer(s)) and configure vertex attributes
      // ------------------------------------------------------------------
      float vertices[] = {
          // positions          // normals           // texture coords
          -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,
          0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  0.0f,
          0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,
          0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,
          -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  1.0f,
          -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,
  ​
          -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,
          0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  0.0f,
          0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f,
          0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f,
          -0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  1.0f,
          -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,
  ​
          -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
          -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  1.0f,
          -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
          -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
          -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  0.0f,
          -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
  ​
          0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
          0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f,
          0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
          0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
          0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  0.0f,
          0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
  ​
          -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  1.0f,
          0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  1.0f,
          0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  0.0f,
          0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  0.0f,
          -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  0.0f,
          -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  1.0f,
  ​
          -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  1.0f,
          0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  1.0f,
          0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,
          0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,
          -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  0.0f,
          -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  1.0f
      };
  ​
      float planeSize = 50.0f; // 5.0f
      float textureSize = 20.0f; // 2.0f
      float planeVertices[] = {
          // positions                    // normals           // texture Coords 
           planeSize, -0.5f,  planeSize,   0.0f,  0.0f,  1.0f, textureSize, 0.0f,
          -planeSize, -0.5f,  planeSize,   0.0f,  0.0f,  1.0f, 0.0f, 0.0f,
          -planeSize, -0.5f, -planeSize,   0.0f,  0.0f,  1.0f, 0.0f, textureSize,
  ​
           planeSize, -0.5f,  planeSize,  0.0f,  0.0f,  1.0f,  textureSize, 0.0f,
          -planeSize, -0.5f, -planeSize,  0.0f,  0.0f,  1.0f,  0.0f, textureSize,
           planeSize, -0.5f, -planeSize,  0.0f,  0.0f,  1.0f,  textureSize, textureSize
      };
  ​
      // positions all containers
      glm::vec3 cubePositions[] = {
          glm::vec3( 0.0f,  0.0f,  0.0f),
          glm::vec3( 2.0f,  0.0f, -15.0f),
          glm::vec3(-1.5f,  0.0f, -2.5f),
          glm::vec3(-3.8f,  0.0f, -12.3f),
          glm::vec3( 2.4f,  0.0f, -3.5f),
          glm::vec3(-1.7f,  0.0f, -7.5f),
          glm::vec3( 1.3f,  0.0f, -2.5f),
          glm::vec3( 1.5f,  0.0f, -2.5f),
          glm::vec3( 1.5f,  0.0f, -1.5f),
          glm::vec3(-1.3f,  0.0f, -1.5f)
      };
  ​
      // 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);
      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
      glEnableVertexAttribArray(0);
      glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
      glEnableVertexAttribArray(1);
      glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
      glEnableVertexAttribArray(2);
  ​
      // plane VAO
      unsigned int planeVAO, planeVBO;
      glGenVertexArrays(1, &planeVAO);
      glGenBuffers(1, &planeVBO);
      glBindVertexArray(planeVAO);
      glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
      glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW);
      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
      glEnableVertexAttribArray(0);
      glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
      glEnableVertexAttribArray(1);
      glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
      glEnableVertexAttribArray(2);
  ​
      // load textures (we now use a utility function to keep the code more organized)
      // -----------------------------------------------------------------------------
      unsigned int diffuseMap = loadTexture("resources/textures/container2.png");
      unsigned int specularMap = loadTexture("resources/textures/container2_specular.png");
      unsigned int floorTexture = loadTexture("resources/textures/metal.png");
  ​
      // shader configuration
      // --------------------
      lightingShader.use();
      lightingShader.setInt("material.diffuse", 0);
      lightingShader.setInt("material.specular", 1);
  ​
      // 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(0.1f, 0.1f, 0.1f, 1.0f);
          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  ​
          // be sure to activate shader when setting uniforms/drawing objects
          lightingShader.use();
          lightingShader.setVec3("light.direction", -0.2f, -1.0f, -0.3f);
          lightingShader.setVec3("viewPos", camera.Position);
  ​
          // light properties
          lightingShader.setVec3("light.ambient", 1.0f, 1.0f, 1.0f);
          lightingShader.setVec3("light.diffuse", 1.0f, 1.0f, 1.0f);
          lightingShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f);
  ​
          // material properties
          lightingShader.setFloat("material.shininess", 32.0f);
  ​
          // fog
          lightingShader.setVec4("fog.color", 1.0f, 1.0f, 1.0f, 1.0f);
          lightingShader.setFloat("fog.density", 0.1f); // 0.01
          lightingShader.setFloat("fog.range", 15.0f);
  ​
          // view/projection transformations
          glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
          glm::mat4 view = camera.GetViewMatrix();
          lightingShader.setMat4("projection", projection);
          lightingShader.setMat4("view", view);
  ​
          // world transformation
          glm::mat4 model = glm::mat4(1.0f);
          lightingShader.setMat4("model", model);
  ​
          // floor
          glActiveTexture(GL_TEXTURE0);
          glBindVertexArray(planeVAO);
          glBindTexture(GL_TEXTURE_2D, floorTexture);
          model = glm::mat4(1.0f);
          lightingShader.setMat4("model", model);
          glDrawArrays(GL_TRIANGLES, 0, 6);
  ​
          // cube
          // bind diffuse map
          glActiveTexture(GL_TEXTURE0);
          glBindTexture(GL_TEXTURE_2D, diffuseMap);
          // bind specular map
          glActiveTexture(GL_TEXTURE1);
          glBindTexture(GL_TEXTURE_2D, specularMap);
  ​
          // render containers
          glBindVertexArray(cubeVAO);
          for (unsigned int i = 0; i < 10; i++)
          {
              // calculate the model matrix for each object and pass it to shader before drawing
              glm::mat4 model = glm::mat4(1.0f);
              model = glm::translate(model, cubePositions[i]);
              //float angle = 20.0f * i;
              //model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
              lightingShader.setMat4("model", model);
  ​
              glDrawArrays(GL_TRIANGLES, 0, 36);
          }
  ​
          // 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(1, &cubeVAO);
      glDeleteVertexArrays(1, &planeVAO);
      glDeleteBuffers(1, &VBO);
  ​
      // 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 top
  ​
      lastX = 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));
  }
  ​
  // utility function for loading a 2D texture from file
  // ---------------------------------------------------
  unsigned int loadTexture(char const * path)
  {
      unsigned int textureID;
      glGenTextures(1, &textureID);
  ​
      int width, height, nrComponents;
      unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
      if (data)
      {
          GLenum format;
          if (nrComponents == 1)
              format = GL_RED;
          else if (nrComponents == 3)
              format = GL_RGB;
          else if (nrComponents == 4)
              format = GL_RGBA;
  ​
          glBindTexture(GL_TEXTURE_2D, textureID);
          glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
          glGenerateMipmap(GL_TEXTURE_2D);
  ​
          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_MIPMAP_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;
  }
  ​

完整项目代码:

https://github.com/mc-liyanliang/OpenGL-Shader/tree/master

相关文章

  • 从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用
  • 土木想往土木软件开发方向发展,应该如何准备土木想往土木软件开发方向发展,应该如何准备
  • OpenGL实现billboard效果(CPU)OpenGL实现billboard效果(CPU)
  • 截面特性计算程序-附源码截面特性计算程序-附源码
  • OpenGL开发环境搭建-GLFW与GLAD配置 超详细OpenGL开发环境搭建-GLFW与GLAD配置 超详细
  • Midas W-满堂支架快速建模助手开发Midas W-满堂支架快速建模助手开发

OpenGL
fog

Post navigation

PREVIOUS
OpenGL实现billboard效果(CPU)
NEXT
WinDbg检查内存泄漏

发表回复 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

近期文章

  • ANR崩溃日志查看方法
  • 通过数学方法来计算short类型的变量w的低八位x和高八位
  • 3dTiles数据解析
  • Games101和Games202脑图汇总
  • LearnOpenGL脑图汇总
  • IBL计算总结
  • C++实现一个简单的语言解释器
  • OpenGL-法线贴图(Normal Mapping)
  • OpenGL-卡通着色(Cartoon)
  • OpenGL几何着色器实现贝塞尔曲线
  • WinDbg检查内存泄漏
  • OpenGL雾化效果实现-每像素雾化
  • OpenGL实现billboard效果(CPU)
  • 算法:寻找异常数字
  • OpenGL 几何着色器的应用
  • Midas XD-构件详图开发
  • Midas XD-选筋助手开发
  • Civil Designer开发-检测规范自动生成控制截面
  • Civil Designer开发-公路桥梁承载能力检算评定
  • Midas W-满堂支架快速建模助手开发

全站热点

  • C++编写的情人节小程序 (2,082)
  • 提取最小封闭区域 (1,696)
  • Modern OpenGL绘制圆柱体 (1,607)
  • OpenGL开发环境搭建-GLFW与GLAD配置 超详细 (1,465)
  • 截面特性计算程序-附源码 (1,290)
  • OpenGL绘制旋转立方体 (1,110)
  • 判断一个点是否在闭合区域内 (1,032)
  • WordPress分页插件 – WP-PageNavi的使用(替换现有脚本) (948)
  • OpenGL实现billboard效果(CPU) (865)
  • Midas W-满堂支架快速建模助手开发 (837)
  • 从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用 (748)
  • Midas XD [错误] 右侧挡土墙的最下端深度必须小于地基的最下端深度 (709)
  • 两跨连续梁影响线绘制-附源码 (686)
  • 土木想往土木软件开发方向发展,应该如何准备 (680)
  • OpenGL几何着色器实现贝塞尔曲线 (664)
  • 通过Spy++抓取窗口以查询对话框id (613)
  • 使用ODA数据库出现 “ODA_ASSUME”: 找不到标识符的错误 (547)
  • #pragma message 编译时提示信息 (527)
  • OpenGL雾化效果实现-每像素雾化 (508)
  • midas XD2020的开发 (476)

分类

  • C# (3)
  • C++ (19)
  • GIS (1)
  • MFC (3)
  • ObjectARX (2)
  • OpenGL (11)
  • Revit开发 (1)
  • 学习笔记 (2)
  • 岩土 (2)
  • 算法 (1)
  • 结构设计 (7)
  • 职场生涯 (1)
  • 计算几何 (3)

归档

  • 2024 年 12 月 (1)
  • 2024 年 10 月 (1)
  • 2024 年 9 月 (1)
  • 2023 年 3 月 (2)
  • 2022 年 10 月 (1)
  • 2022 年 3 月 (1)
  • 2022 年 2 月 (1)
  • 2022 年 1 月 (5)
  • 2021 年 11 月 (7)
  • 2021 年 6 月 (3)
  • 2021 年 5 月 (2)
  • 2021 年 3 月 (2)
  • 2021 年 2 月 (8)
  • 2021 年 1 月 (18)

标签

3dtiles anr Bezier Curves BillBoard C++ CDN CivilDesigner DLL EasyX fog glTF MFC Midas W Midas XD NormalMapping ObjectARX ODA OpenGL OpenXML Open XML PBR revit WinDbg 基坑设计 影响线 截面特性 桥梁 桥梁检测 桥梁设计 算法 计算几何 设计模式

书签

  • 李燕良的CSDN
  • 崔济东的博客
  • C++爱好者博客
  • 陈学伟的博客
  • 贾苏的博客
  • 陈睦锋的博客
  • 孙勇的博客

统计

  • 1
  • 157
  • 86
  • 388
  • 145
  • 268,860
  • 77,773

实时访问地域

© 2025   liyanliang.net Copyright. All Rights Reserved.