使用 GLFW 库进行实验:窗口边界问题和归一化坐标

问题描述 投票:0回答:1

我正在尝试使用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”。

c++ opengl glfw
1个回答
0
投票

我找到了答案(我把它放在这个的编辑中,因为这里的愚蠢工具假装我的代码没有格式化,他们所谓的 ctrl-K 不起作用,并且 [?] 不存在!)

© www.soinside.com 2019 - 2024. All rights reserved.