天天看點

openGL API glDepthFunc詳解

openGL API glDepthFunc詳解

文章目錄

  • ​​openGL API glDepthFunc詳解​​
  • ​​官方說明​​
  • ​​翻譯​​
  • ​​例子​​
  • ​​主程式main.cpp​​
  • ​​頂點着色器 vertShader.glsl​​
  • ​​片元着色器 fragShader.glsl​​
  • ​​運作效果​​
  • ​​源碼下載下傳​​

官方說明

​​官方文檔解釋​​

Name

glDepthFunc — specify the value used for depth buffer comparisons

C Specification

void glDepthFunc( GLenum func);

Parameters

func

Specifies the depth comparison function. Symbolic constants GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, and GL_ALWAYS are accepted. The initial value is GL_LESS.

Description

glDepthFunc specifies the function used to compare each incoming pixel depth value with the depth value present in the depth buffer. The comparison is performed only if depth testing is enabled. (See glEnable and glDisable of GL_DEPTH_TEST.)

func specifies the conditions under which the pixel will be drawn. The comparison functions are as follows:

GL_NEVER

Never passes.

GL_LESS

Passes if the incoming depth value is less than the stored depth value.

GL_EQUAL

Passes if the incoming depth value is equal to the stored depth value.

GL_LEQUAL

Passes if the incoming depth value is less than or equal to the stored depth value.

GL_GREATER

Passes if the incoming depth value is greater than the stored depth value.

GL_NOTEQUAL

Passes if the incoming depth value is not equal to the stored depth value.

GL_GEQUAL

Passes if the incoming depth value is greater than or equal to the stored depth value.

GL_ALWAYS

Always passes.

The initial value of func is GL_LESS. Initially, depth testing is disabled. If depth testing is disabled or if no depth buffer exists, it is as if the depth test always passes.

Notes

Even if the depth buffer exists and the depth mask is non-zero, the depth buffer is not updated if the depth test is disabled. In order to unconditionally write to the depth buffer, the depth test should be enabled and set to GL_ALWAYS.

Errors

GL_INVALID_ENUM is generated if func is not an accepted value.

Associated Gets

glGet with argument GL_DEPTH_FUNC

glIsEnabled with argument GL_DEPTH_TEST

Version Support

OpenGL Version

Function / Feature Name 2.0 2.1 3.0 3.1 3.2 3.3 4.0 4.1 4.2 4.3 4.4 4.5

glDepthFunc ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔

See Also

glDepthRange, glEnable, glPolygonOffset

Copyright

Copyright © 1991-2006 Silicon Graphics, Inc. Copyright © 2010-2014 Khronos Group. This document is licensed under the SGI Free Software B License. For details, see https://khronos.org/registry/OpenGL-Refpages/LICENSES/LicenseRef-FreeB.txt.

翻譯

glDepthFunc

函數名:

glDepthFunc——指定用于深度緩沖比較值;

函數原型:

void glDepthFunc (int func)

參數說明:

func指定深度比較函數。

描述:

func值

openGL API glDepthFunc詳解

例子

主程式main.cpp

#include "glew/glew.h"
#include "glfw/glfw3.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "Utils.h"
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

Utils utils = Utils();
double cameraX = 0.0f, cameraY = 0.0f, cameraZ = 0.0f;
double cubeX = 0.0f, cubeY = 0.0f, cubeZ = 0.0f;
GLuint renderingProgram = 0;

// variable allocation for display
GLuint mvLoc = 0, projLoc = 0;
int width = 0, height = 0;
float aspect = 0.0;
glm::mat4 pMat(1.0), vMat(1.0), mMat(1.0), mvMat(1.0), tMat(1.0), rMat(1.0);

static const int Screen_Width = 1920;
static const int Screen_Height = 1080;
static const int NumberVAOs = 1;
static const int numberVBOs = 2;
GLuint vao[NumberVAOs] = { 0 };
GLuint vbo[numberVBOs] = { 0 };

void setupVertices(void)
{
  float vertexPositions[108] = {
    -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
  };

  //生成頂點數組對象
  glGenVertexArrays(NumberVAOs, vao);
  //激活頂點數組對象
  glBindVertexArray(vao[0]);
  //生成頂點緩沖區對象
  glGenBuffers(numberVBOs, vbo);
  //激活頂點緩沖區對象
  glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  //把頂點資料vertexPositions拷貝到頂點緩沖區
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
}


void init(GLFWwindow* window)
{
  renderingProgram = Utils::createShaderProgram("vertShader.glsl", "fragShader.glsl");

  glfwGetFramebufferSize(window, &width, &height);
  aspect = (float)width / (float)height;

  //必須要建立透視投影矩陣計算公式,否則第一幀渲染時,立方體不在視口中 :1.0472 radians = 60 degrees
  pMat = glm::perspective(glm::radians(45.f), aspect, 0.01f, 1000.f);

  cameraX = 0.f;
  cameraY = 0.f;
  cameraZ = 8.f;

  cubeX = 0.f;
  cubeY = -2.f;
  cubeZ = 0.f;

  setupVertices();

}

void display(GLFWwindow* window, double currentTime)
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glClearColor(0.f, 0.7f, 1.f, 1.f);

  //啟動着色器程式,在GPU上安裝GLSL代碼,這不會運作着色器程式,
  glUseProgram(renderingProgram);

  /*Utils::printProgramLog(renderingProgram);*/   //printProgramLog()是私有函數
  //擷取uniform變量在着色器程式中的位置序号,通過該序号可以設定一緻變量的值,如果沒有該變量則傳回-1
  mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");
  projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");

  glfwGetFramebufferSize(window, &width, &height);
  aspect = (float)width / (float)height;
  //glm::perspective使用模闆定義,是以函數各個參數類型要一緻
  glm::perspective(glm::radians(45.f), aspect, 0.01f, 1000.f);

  //相機平移矩陣
  //vMat = glm::translate(vMat, glm::vec3(-cameraX, -cameraY, -cameraZ));
  vMat = glm::translate(glm::mat4(1.f), glm::vec3(-cameraX, -cameraY, -cameraZ));
  //給模型使用的平移矩陣
  tMat = glm::translate(glm::mat4(1.f), glm::vec3(glm::sin(0.35f * currentTime) * 2.f, glm::cos(0.52f * currentTime) * 2.f, glm::cos(0.7f * currentTime) * 2.f));
  //給模型使用的旋轉矩陣:currentTime控制旋轉速度
  //rMat = glm::rotate(glm::mat4(1.f), 1.75f * (float)(currentTime*0.5), glm::vec3(0.f, 1.f, 0.f));
  rMat = glm::rotate(glm::mat4(1.f), 1.75f * (float)(currentTime), glm::vec3(0.f, 1.f, 0.f));
  rMat = glm::rotate(rMat, 1.75f * (float)(currentTime), glm::vec3(1.f, 0.f, 0.f));
  rMat = glm::rotate(rMat, 1.75f * (float)(currentTime), glm::vec3(0.f, 0.f, 1.f));

  mMat = tMat * rMat;
  mvMat = mMat * vMat;

  //更改一個uniform矩陣變量或數組的值。要更改的uniform變量的位置由location指定,location的值應該由glGetUniformLocation函數傳回
  // 将透視矩陣和MV 矩陣複制給相應的統一變量
  glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));
  glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));
  
  //激活頂點緩沖區,目前隻用了第一個頂點緩沖區,第二個vbo[1]頂點緩沖區暫時沒用
  glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);

  //指定了渲染時索引值為 index 的頂點屬性數組的資料格式和位置
  /*Parameters
  index
    指定要修改的頂點屬性的索引值

    size
    指定每個頂點屬性的元件數量。必須為1、2、3或者4。初始值為4。(夢維:如position是由3個(x, y, z)組成,而顔色是4個(r, g, b, a))

    type
    指定數組中每個元件的資料類型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值為GL_FLOAT。

    normalized
    指定當被通路時,固定點資料值是否應該被歸一化(GL_TRUE)或者直接轉換為固定點值(GL_FALSE)。

    stride
    指定連續頂點屬性之間的偏移量。如果為0,那麼頂點屬性會被了解為:它們是緊密排列在一起的。初始值為0。

    pointer
    指定一個指針,指向數組中第一個頂點屬性的第一個元件。初始值為0。
    */
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
  glEnableVertexAttribArray(0);

  //開啟深度測試
  glEnable(GL_DEPTH_TEST);
  //指定用于深度緩沖比較值;
  glDepthFunc(GL_LEQUAL);

  glDrawArrays(GL_TRIANGLES, 0, 36);
}

void windows_size_callback(GLFWwindow* window, int newWidth, int newHeight)
{
  aspect = (float)newWidth / (float)newHeight;
  glViewport(0, 0, newWidth, newHeight);
  pMat = glm::perspective(glm::radians(45.f), aspect, 0.001f, 1000.f);
}


int main(int argc, char** argv)
{
  int glfwState = glfwInit();
  if (GLFW_FALSE == glfwState)
  {
    cout << "GLFW initialize failed, Invoke glfwInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << std::endl;
    glfwTerminate();
    exit(EXIT_FAILURE);
  }

  /*因為我們要使用OpenGL 4.6,是以我們把GLFW_CONTEXT_VERSION_MAJOR和GLFW_CONTEXT_VERSION_MINOR對應的hint都設定為4和6。
  因為我們要使用OpenGL核心模式(這個後面會提到更多),是以我們把GLFW_OPENGL_PROFILE對應的hint設定為GLFW_OPENGL_CORE_PROFILE,
  表示使用OpenGL核心模式。最後,把GLFW_RESIZABLE對應的hint設定為GLFW_FALSE,表示視窗不允許使用者調整大小。
  之是以這樣做是因為如果允許使用者調整大小,大小發生變化後,視窗的繪制區域預設不變(依然是原來視窗的區域),
  也就是說視窗上繪制的圖像的大小、位置不會發生改變。為了避免這種現象發生,我們就簡單地不讓使用者調整視窗大小
  (當然也有更好的方法,就是用GLFW設定一個視窗大小的回調函數,但這樣比較簡單)。*/
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
  glfwWindowHint(GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_PROFILE);
  glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

  GLFWwindow* window = glfwCreateWindow(Screen_Width, Screen_Height, "Draw rotate color cube", nullptr, nullptr);
  if (!window)
  {
    cout << "GLFW create window failed, Invoke glfwCreateWindow()......Error file:" << __FILE__ << ".....Error line:" << std::endl;
    glfwTerminate();
    exit(EXIT_FAILURE);
  }

  /*此函數使調用線程上的指定視窗的 OpenGL 或 OpenGL ES 上下文成為目前上下文。
    一次隻能在單個線程上使上下文成為目前上下文,并且每個線程一次隻能有一個目前上下文。
    線上程之間移動上下文時,必須先使其在舊線程上變為非目前狀态,然後再在新線程上變為目前狀态。
  */
  glfwMakeContextCurrent(window);

  int glewState = glewInit();
  if (GLEW_OK != glewState)
  {
    cout << "GLEW initialize failed, Invoke glewInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << std::endl;
    exit(EXIT_FAILURE);
  }

  /*此函數設定目前 OpenGL 或 OpenGL ES 上下文的交換間隔,即從調用glfwSwapBuffers開始等待的螢幕更新次數,
    然後再交換緩沖區并傳回。這有時稱為垂直同步、垂直回掃同步或僅vsync。
    支援WGL_EXT_swap_control_tear和GLX_EXT_swap_control_tear擴充的上下文也接受負交換間隔,這允許驅動程式立即交換,
    即使幀到達有點晚。您可以使用glfwExtensionSupported檢查這些擴充。
    上下文必須在調用線程上是最新的。在沒有目前上下文的情況下調用此函數将導緻GLFW_NO_CURRENT_CONTEXT錯誤。
    此功能不适用于 Vulkan。如果您使用 Vulkan 進行渲染,請改為檢視交換鍊的目前模式。
  */
  glfwSwapInterval(1);

  glfwSetWindowSizeCallback(window, windows_size_callback);

  init(window);

  while (!glfwWindowShouldClose(window))
  {
    display(window, glfwGetTime());
    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  glfwDestroyWindow(window);
  glfwTerminate();
  exit(EXIT_SUCCESS);

  return 0;
}      

頂點着色器 vertShader.glsl

#version 430 core

layout(location = 0) in vec3 aPosition;

uniform mat4 mMat;
uniform mat4 vMat;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

out vec4 varyingColor;

void main()
{
  gl_Position = proj_matrix * mv_matrix * vec4(aPosition, 1.f);
  varyingColor = vec4(aPosition, 1.f) * 0.5f + vec4(0.5f, 0.5f, 0.5f, 0.5f);
}      

片元着色器 fragShader.glsl

#version 430 core

in vec4 varyingColor;

out vec4 color;

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

void main()
{
  color = varyingColor;
}      

運作效果

源碼下載下傳