When I do not call glfwSwapInterval, there will be no tearing and the screen will display normally. But if I call glfwSwapInterval, it will cause tearing.
Calling glfwSwapInterval (0) will cause the entire screen to tear. When calling glfwSwapInterval (1), the tearing situation is not as severe and will only start tearing at the position where there is a line above the screen.
When I do not call glfwSwapInterval, the glfwSwapBuffers usage time is 3.52859e-05.
When I call glfwSwapInterval (1), glfwSwapBuffers take 0.0156.
When I call glfwSwapInterval (0), the glfwSwapBuffers take 1.52588e-05.
If I switch to window mode, there won’t be tearing, but I am developing in full screen mode. Although I don’t call glfwSwapInterval or it can work normally, I still hope to understand why this is happening.
Here is my code:
class MainWindow
{
public:
GLFWwindow* window;
unsigned int SCR_WIDTH;
unsigned int SCR_HEIGHT;
unsigned int MAX_WIDTH;
unsigned int MAX_HEIGHT;
bool isWindow = false;
bool isStop = false;
int simpCountMSAAA = 8;
bool enableMSAA = false;
bool enableKeyDown = false;
bool enableMoveMuose = false;
bool enableScrollMouse = false;
bool enableVSYNC = false;
bool enableShowMouse = true;
bool enableDebug = false;
std::map<GLchar, Character> Characters;
GLuint fontsVAO, fontsVBO;
int Init()
{
glfwInit();
#ifdef _DEBUG
enableDebug = true;
#endif
if (enableDebug)
{
AllocConsole();
freopen("CONOUT$", "w", stdout);
freopen("CONIN$", "r", stdin);
}
HDC hdc = GetDC(NULL);
MAX_WIDTH = GetDeviceCaps(hdc, DESKTOPHORZRES);
MAX_HEIGHT = GetDeviceCaps(hdc, DESKTOPVERTRES);
if (isWindow)
{
SCR_WIDTH = 800;
SCR_HEIGHT = 600;
}
else
{
SCR_WIDTH = MAX_WIDTH;
SCR_HEIGHT = MAX_HEIGHT;
glfwWindowHint(GLFW_REFRESH_RATE, GLFW_DONT_CARE);
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
if (isWindow)
{
glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE);
}
else
{
glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
}
if (true)
{
glfwWindowHint(GLFW_SAMPLES, simpCountMSAAA);
}
else
{
glfwWindowHint(GLFW_SAMPLES, 0);
}
// 创建GLFW窗口
window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "StrategicDefenseInitiative", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
FT_Library ft;
if (FT_Init_FreeType(&ft))
std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;
FT_Face face;
if (FT_New_Face(ft, "./Fonts/simsun.ttc", 0, &face))
std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl;
FT_Set_Pixel_Sizes(face, 48, 48);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //禁用字节对齐限制
for (GLubyte c = 0; c < 128; c++)
{
if (FT_Load_Char(face, c, FT_LOAD_RENDER))
{
std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;
continue;
}
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RED,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Character character = {
texture,
glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
face->glyph->advance.x
};
Characters.insert(std::pair<GLchar, Character>(c, character));
}
glBindTexture(GL_TEXTURE_2D, 0);
FT_Done_Face(face);
FT_Done_FreeType(ft);
glGenVertexArrays(1, &fontsVAO);
glGenBuffers(1, &fontsVBO);
glBindVertexArray(fontsVAO);
glBindBuffer(GL_ARRAY_BUFFER, fontsVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
}
I also found that if I call the Init function twice, I will create two windows, one of which will be blank, and no matter what I call, there will be no tearing. I really want to know why?
If you could provide suggestions, I would greatly appreciate it.