我正在尝试使用GLFW(使用 g++ -o nxtBluePixel nxtBluePixel.cpp -lglfw -lGLEW -lGL 进行编译)来简单地绘制一个蓝色框并将其上/下/左/右移动。当盒子接触可见区域的边缘时,我想输出一条“越界”消息,逻辑上应该是-1或1(在那些所谓的标准化OpenGL坐标中,所以我读到)。但是盒子继续在外部的“不可见”区域中移动(并且是不可见的),但直到一段时间才显示消息(在边缘边界之外的按键上至少有 10 次点击左右......ChatGPT 4 无法帮助我,它说:
“正确的边界检查:如果您希望在该点即将离开可见区域时立即出现“越界”消息,那么您原来不带大 epsilon 的检查在逻辑上是正确的。但是,如果该消息也出现晚或太早,可能是由于点位置的更新或渲染方式,而不是边界检查本身。”
有什么想法吗?我从来没有使用过 OpenGL,所以我想尝试一下...但这通常是我讨厌的那种非常烦人的问题!
这是我的代码:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
#include <cctype>
GLint worldWidth = 400;
GLint worldHeight = 300;
// Starting position of the pixel
float currX = 0.0f;
float currY = 0.0f;
float stepSize = 1.0f / worldWidth;
float speed = 2.0f;
void updateWorld(char keyPressed, float speed){
switch (keyPressed) {
case 'W':
//up
currY += stepSize*speed;
break;
case 'A':
//left
currX -= stepSize*speed;
break;
case 'S':
//down
currY -= stepSize*speed;
break;
case 'D':
//right
currX += stepSize*speed;
break;
}
//using openGL 'normalized' coords i.e. between -1 and 1
if (currX >= 1.0 || currX <= -1.0 || currY >= 1.0 || currY <= -1.0){
printf("OUT OF BOUNDS !!!!");
}
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
char key_str = '0';
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
switch (key) {
case GLFW_KEY_W:
key_str = 'W';
break;
case GLFW_KEY_A:
key_str = 'A';
break;
case GLFW_KEY_S:
key_str = 'S';
break;
case GLFW_KEY_D:
key_str = 'D';
break;
case GLFW_KEY_Q:
printf("Bye ...");
glfwSetWindowShouldClose(window, GL_TRUE);
break;
default:
printf("unknown key pressed \n");
break;
}
updateWorld(key_str, speed);
}
}
int main(void) {
GLFWwindow* window;
// Initialize the library
if (!glfwInit())
return -1;
//remove win frame
//glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
// Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(worldWidth, worldHeight, "Move Pixel with Keyboard", NULL, NULL);
if (!window) {
glfwTerminate();
return -1;
}
// Make the window's context current
glfwMakeContextCurrent(window);
// Set the keyboard input callback
glfwSetKeyCallback(window, key_callback);
// Initialize GLEW
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cerr << "Failed to initialize GLEW" << std::endl;
return -1;
}
//glfwGetFramebufferSize(window, &worldWidth, &worldHeight);
// Define the viewport dimensions
glViewport(0, 0, worldWidth, worldHeight);
// Set point size
glPointSize(10.0f); // Increase if you want the "pixel" to be bigger
// Loop until the user closes the window
while (!glfwWindowShouldClose(window)) {
// Render here
glClear(GL_COLOR_BUFFER_BIT);
// Set the drawing color to blue
glColor3f(0.0f, 0.0f, 1.0f); // RGB: Blue
// Draw a point at the current position
glBegin(GL_POINTS);
glVertex2f(currX, currY); // Use the updated position
glEnd();
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
glfwTerminate();
return 0;
}
在最坏的情况下,我可以使用
printf
逐步调试...但是这将需要很长时间,并且不一定能让我理解这种行为的根源,因为我看到有一个“epsilon”但它随着分辨率的变化而变化,所以我没有公式,总是需要“反复试验”来确定用于从理论 -1 或 1 边界中添加或减去的“epsilon”。
我找到了答案(我把它放在这个的编辑中,因为这里的愚蠢工具假装我的代码没有格式化,他们所谓的 ctrl-K 不起作用,并且 [?] 不存在!)