问题
I have made a bit of a change to my code in the last couple of hours as everything was messy with my grid so I made it into a void and I made sure I got the boundary that I was drawn out first as it is now placed where I want it to be, however my grid is now in the wrong place shown in the image below
I think it is a glortho issue but I don't know what code to put in which will change where I want my drawings to be placed.
#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;
}
回答1:
The w
and h
depend on the orthographic projection rather than the viewport. Since the projection doesn't start at (0, 0), but at (-200, -200), you've to add 2 additional variables startX
, startY
:
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:
Get rid of the 20's in void drawBoundary(...) and call with drawBounndary(w/2, 0, 0).
Also I suspect you really want (X_CENTRE, Y_CENTRE) there to be (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:
The problem here is that the way you are calculating the positions for your boundary is completely different from the way you are calculating the positions for the grid eg:
Far left point of boundary seems to be calculated as:
X_CENTRE - length - 20
Which equals 0 - 170 - 20
or -190
But the far left position of the horizontal lines in the grid is calculated as:
0.1 * w
Which equals 0.1 * 500
or 50
You'll never get them to line up while you are using such wildly different equations for the points.
EDIT: to answer comment:
Start with the boundary, you need to first work out the x coordinate of the bottom left using your preferred equation from above:
x = //your preferred equation here
Then do the same for the y coordinate of the bottom left using the y equivalent of the preferred equation from above. The information you need for this is in the code you've already posted so its up to you to figure this out.
y = //your preferred equation here
Next work out the x and y coordinates of the top right corner of your boundary using
x2 = x + ?? //what change do you need to make here? y2 = y + ?? //what change do you need to make here?
Again this information is in the code you've already posted so it is for you to figure out.
now you can determine what values need to be passed to glVertex2f using the following pairs:
(x, y) //bottom left
(x, y2) //top left
(x2, y2) //top right
(x2, y) //bottom right
This is all you need to know to draw the boundary using either equation.
For the horizontal lines of the grid you would use the same x and x2 as calculated for the boundary but y changes for each iteration of the loop so you need an equation in the form
yi = y + (i * ??? /* what goes here */)
Then for the vertical lines of the grid y and y2 would be the same as for boundary and x changes each iteration of the loop in the form:
xi = x + (i * ??? /* what goes here */)
Then drawing the lines is simply passing the following pairs to glVertex2f:
(x, yi) //left of line
(x2, yi) //right of line
(xi, y) //bottom of line
(xi, y2) //top of line
The important thing is that you are consistent with how you calculate x and y for the boundary and grid and all the information you need to do this is already provided in the code you've already posted.
来源:https://stackoverflow.com/questions/65079087/having-coordinates-glortho-issues-with-my-drawings