【问题标题】:having coordinates/ glortho issues with my drawings我的图纸有坐标/ glortho 问题
【发布时间】:2020-11-30 18:22:27
【问题描述】:

在过去的几个小时里,我对我的代码做了一些改动,因为我的网格很乱,所以我把它变成了一个空白,我确保我得到了我首先被绘制出来的边界现在放置在我想要的位置,但是我的网格现在位于下图中显示的错误位置

我认为这是一个 glortho 问题,但我不知道输入什么代码会改变我想要放置我的绘图的位置。

#include "include\freeglut.h"   // OpenGL toolkit - in the local shared folder
#include <iostream>

using namespace std;

#define X_CENTRE 0.0            /* 0,0 */
#define Y_CENTRE 0.0

#define LENGTH   20.0 

GLboolean grid = false;

int w;
int h;


/* reshape callback function executed when window is moved or resized */
void reshape(int width, int height)
{
h = width;
w = height;
//set the matrix mode to PROJECTION
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
// use orthographic (parallel) projection
glOrtho(-200.0, 200.0, -200.0, 200.0, -200.0, 200.0);
//set the matrix mode to MODEL
glMatrixMode(GL_MODELVIEW);

}

void drawGrid() {
GLint i;

glEnable(GL_LINE_STIPPLE); //Activates the line-style feature

glLineStipple(1, 0xAAAA);  // Plots a dashed polyline

glColor3f(0.8, 0.8, 0.8);

if (grid) {
    glBegin(GL_LINES);
    for (i = 2; i <= 9; i++)
    {
        glVertex3f(i * 0.1 * w, 0.0, 0.0);
        glVertex3f(i * 0.1 * w, 0.9 * h, 0.0);
    }

    for (i = 1; i <= 9; i++)
    {
        glVertex3f(0.1 * w, i * 0.1 * h, 0.0);
        glVertex3f(w, i * 0.1 * h, 0.0);
    }
    glEnd();
    glDisable(GL_LINE_STIPPLE);
}

}

void drawBoundary(float length, float x, float y)
{

glBegin(GL_LINE_LOOP);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(X_CENTRE - length - 20, Y_CENTRE - length);   //these 4 points 
draw the game boundary
glVertex2f(X_CENTRE - length - 20, Y_CENTRE + length);   //these 4 points 
draw the game boundary
glVertex2f(X_CENTRE + length + 20, Y_CENTRE + length);   //these 4 points 
draw the game boundary
glVertex2f(X_CENTRE + length + 20, Y_CENTRE - length);   //these 4 points 
draw the game boundary
glEnd();

glFlush();     /* execute drawing commands in buffer */

   }

/*     {



    /* display callback function called whenever contents of window need 
to be re-displayed     */
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);   /* clear window */
glLoadIdentity();

drawGrid();

drawBoundary(170, 0, 0);

glutSwapBuffers();


}


GLvoid IdleFunc(GLvoid)
{
glutPostRedisplay();
}

void myGridmenu(GLint id)
{
if (id == 1)
{
    grid = 1.0;
}
else
{
    grid = 0.0;
}
glutPostRedisplay();
}

/* graphics initialisation */
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);   /* window will be cleared to black */
}


int main(int argc, char* argv[])//standard c entry signature
{
/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use double-buffered window and RGBA colour model */
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
/* window width = 400 pixels, height = 400 pixels */
glutInitWindowSize(500, 500);
/* window upper left corner at (100, 100) */
glutInitWindowPosition(100, 100);
/* creates an OpenGL window and set its title bar*/
glutCreateWindow("Coursework 1");
init();

glutDisplayFunc(display);

//glutSpecialFunc(specialKeys);
//  glutSpecialUpFunc(keyGoneUp);

glutReshapeFunc(reshape);

//Create a grid that the user can turn on and off
glutCreateMenu(myGridmenu);

glutAddMenuEntry("Grid on", 1);
glutAddMenuEntry("Grid off", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);


//  SetupRC();
glutIdleFunc(IdleFunc);
glutMainLoop();

return 0;

}

【问题讨论】:

    标签: c++ c++11 opengl visual-c++ glut


    【解决方案1】:

    wh 取决于正交投影而不是视口。由于投影不是从 (0, 0) 开始,而是从 (-200, -200) 开始,因此您必须添加 2 个附加变量startXstartY

    int w = 1;
    int h = 1;
    int startX = 0;
    int startY = 0;
    
    
    /* reshape callback function executed when window is moved or resized */
    void reshape(int width, int height)
    {
        startX = -200;
        startY = -200;
        h = 400;
        w = 400;
        //set the matrix mode to PROJECTION
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glViewport(0, 0, width, height);
        // use orthographic (parallel) projection
        glOrtho(-200.0, 200.0, -200.0, 200.0, -200.0, 200.0);
        //set the matrix mode to MODEL
        glMatrixMode(GL_MODELVIEW);
    }
    
    void drawGrid() {
        GLint i;
    
        glEnable(GL_LINE_STIPPLE); //Activates the line-style feature
        glLineStipple(1, 0xAAAA);  // Plots a dashed polyline
    
        glColor3f(0.8, 0.8, 0.8);
    
        if (grid) {
            glBegin(GL_LINES);
            for (i = 1; i <= 9; i++)
            {
                glVertex3f(startX + i * 0.1 * w, startY, 0.0);
                glVertex3f(startX + i * 0.1 * w, h - startY, 0.0);
            }
    
            for (i = 1; i <= 9; i++)
            {
                glVertex3f(startX, startY + i * 0.1 * h, 0.0);
                glVertex3f(w - startX, startY + i * 0.1 * h, 0.0);
            }
            glEnd();
            glDisable(GL_LINE_STIPPLE);
        }
    }
    

    【讨论】:

    • 非常感谢,非常感谢
    【解决方案2】:

    去掉 void drawBoundary(...) 中的 20 并使用 drawBounndary(w/2, 0, 0) 调用。

    我还怀疑你真的希望 (X_CENTRE, Y_CENTRE) 有 (x,y)?!

    void display(void)
    {
        glClear(GL_COLOR_BUFFER_BIT);   /* clear window */
        //glColor3f(red, green, blue);        /* white drawing objects */
        glColor3f(0.8, 0.8, 0.8);
    
        GLint i;
    
        glEnable(GL_LINE_STIPPLE); //Activates the line-style feature
    
        glLineStipple(1, 0xAAAA);  // Plots a dashed polyline
    
        if (grid) {
            glBegin(GL_LINES);
            for (i = 1; i <= 9; i++)
            {
                glVertex3f((i * 0.1 - 0.5 ) * w , 0.0, 0.0);
                glVertex3f((i * 0.1 - 0.5 ) * w, 0.9 * h, 0.0);
            }
    
            for (i = 1; i <= 9; i++)
            {
                glVertex3f(0.1 * w, (i * 0.1 - 0.5 ) * h, 0.0);
                glVertex3f(w, (i * 0.1 - 0.5 )* h, 0.0);
            }
            glEnd();
            glDisable(GL_LINE_STIPPLE);
        }
    
        drawBoundary(w/2, 0, 0);
    
        glFlush();     /* execute drawing commands in buffer */
    }
    

    【讨论】:

    • 我对我的代码做了一些改动,我将再次编辑这个问题
    • 对不起,如果我不清楚,请检查已编辑的问题。
    【解决方案3】:

    这里的问题是您计算边界位置的方式与计算网格位置的方式完全不同,例如:

    边界的最左边点似乎计算为:

    X_CENTRE - length - 20
    

    等于0 - 170 - 20 或-190

    但网格中水平线最左边的位置计算为:

    0.1 * w
    

    等于0.1 * 500 或 50

    当你对这些点使用如此截然不同的方程时,你永远不会让它们排成一行。

    编辑:回答评论:

    从边界开始,您需要先使用上面的首选方程计算左下角的 x 坐标:

    x = //your preferred equation here
    

    然后使用上面首选方程的 y 等效项对左下角的 y 坐标执行相同的操作。您需要的信息在您已经发布的代码中,因此您可以自行解决。

    y = //your preferred equation here
    

    接下来计算出边界右上角的 x 和 y 坐标

    x2 = x + ?? //你需要在这里做些什么改变? y2 = y + ?? //你需要在这里做些什么改变?

    同样,此信息包含在您已经发布的代码中,因此您可以自己弄清楚。

    现在您可以使用以下对确定需要将哪些值传递给 glVertex2f:

    (x, y) //bottom left (x, y2) //top left (x2, y2) //top right (x2, y) //bottom right

    这是使用任一方程绘制边界所需的全部知识。

    对于网格的水平线,您将使用与计算边界相同的 x 和 x2,但 y 在循环的每次迭代中都会发生变化,因此您需要表格中的方程

    yi = y + (i * ??? /* what goes here */)
    

    那么对于网格的垂直线 y 和 y2 将与边界相同,并且 x 以如下形式改变循环的每次迭代:

    xi = x + (i * ??? /* what goes here */)
    

    然后绘制线条只是将以下对传递给glVertex2f:

    (x, yi) //left of line (x2, yi) //right of line

    (xi, y) //bottom of line (xi, y2) //top of line

    重要的是您要与计算边界和网格的 x 和 y 的方式保持一致,并且您需要执行此操作的所有信息都已在您发布的代码中提供。

    【讨论】:

    • 所以它们必须相同?我该怎么做呢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多