I am trying to achieve a perspective view for a rectangular plane in the X-Z axis like below.
The code below almost achieves that.
What am i doing wrong? I find the documentation to be lacking/confusing.
#include <GL/glut.h>
const int RED_COLOR[3] = {255, 0, 0};
// color to draw in
void setDrawColor(const int decimalCodeRGB[3]) {
float denominator = 255.0;
//convert to float
float r = decimalCodeRGB[0] / denominator;
float g = decimalCodeRGB[1] / denominator;
float b = decimalCodeRGB[2] / denominator;
glColor3f(r, g, b); // set draw color
}
void drawPlane() {
GLfloat A[3] = { -1, 0, 1 };
GLfloat B[3] = { 1, 0, 1 };
GLfloat C[3] = { 1, 0, -1 };
GLfloat D[3] = { -1, 0, -1 };
glBegin(GL_POLYGON);
glVertex3fv(A);
glVertex3fv(B);
glVertex3fv(C);
glVertex3fv(D);
glEnd();
}
GLfloat CamX = 0, CamY = 2, CamZ = 1;
// Display Call Back
void draw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear all drawings in buffer
glLoadIdentity();
gluLookAt(CamX, CamY, CamZ, 0, 0, 0, 0, 1, 0);
drawPlane();
glutSwapBuffers();// Render Now i.e convert Buffer to Picture
return;
}
// Initialization
void initialize()
{
glClearColor(0.1f, 0.1f, 0.1f, 0.1f); // Set Background Color
setDrawColor(RED_COLOR); // sets the drawing color to red
glEnable(GL_DEPTH_TEST); // enable viewing the 3d
glMatrixMode(GL_PROJECTION); // change to perspective projection
glLoadIdentity(); // what does this do?
glFrustum(-1, 1, -1, 1, 2, 10); // what does this do?
glMatrixMode(GL_MODELVIEW); // what does this do?
}
// Main
int main(int argc, char* argv[])
{
glutInit(&argc, argv); // Initialize GLUT
int x = 512, y = 512; // x and y value
glutInitWindowPosition(
(int)(glutGet(GLUT_SCREEN_WIDTH) - x) / 2,
(int)(glutGet(GLUT_SCREEN_HEIGHT) - y) / 2); // Position the window's center
glutInitWindowSize(x, y); // Set the window's initial width & height
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); // initialise the buffers needed. double buff, one for RGB color the other for x,y, z
glutCreateWindow("3D Bowling Game"); // Create a window with the given title
initialize(); // Custom initialisation
glutDisplayFunc(draw); // Register display callback handler for window re-paint
glutMainLoop(); // Enter the event-processing loop
return 0;
}
// End
How do I change the camera to 45 degrees to Z axis?
Am i calling the functions in the right Order?
Related
I drew a rectangle in the X-Z play of a 3D, XYZ, plane using the code below.
#include <GL/glut.h>
void drawPlane() {
GLfloat A[3] = { 0, 0, 0};
GLfloat B[3] = { 1, 0, 0};
GLfloat C[3] = { 1, 0, 1};
GLfloat D[3] = { 0, 0, 1};
glBegin(GL_POLYGON);
glVertex3fv(A);
glVertex3fv(B);
glVertex3fv(C);
glVertex3fv(D);
glEnd();
}
// Display Call Back
void draw(){
glLoadIdentity();
glTranslatef(0.0, 0.5, 1); //i thought this would do the camera thing
drawPlane();
glutSwapBuffers();// Render Now
return;
}
// Initialization
void initialize()
{
glClearColor(0.1f, 0.1f, 0.1f, 0.1f); // Set Background Color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear all drawings in buffer
}
// Main
int main(int argc, char* argv[])
{
glutInit(&argc, argv); // Initialize GLUT
int x = 512, y = 512; // x and y value
glutInitWindowPosition(
(int)(glutGet(GLUT_SCREEN_WIDTH) - x) / 2,
(int)(glutGet(GLUT_SCREEN_HEIGHT) - y) / 2); // Position the window's center
glutInitWindowSize(x, y); // Set the window's initial width & height
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); // ESSENTIAL BUT HAVE NO IDEA WHAT THIS DOES
glutCreateWindow("3d Bowling Game"); // Create a window with the given title
glutDisplayFunc(draw); // Register display callback handler for window re-paint
glutMainLoop(); // Enter the event-processing loop
initialize();
return 0;
}
How do I change the camera angle in order to view all of the coordinates like below.
The screenshot below shows the desired result.
below is the actual result
I used the glutWireSphere API for drawing my sphere, however, it is not showing.
#include <GL/glut.h>
const int RED_COLOR[3] = {255, 0, 0};
const int GREEN_COLOR[3] = { 0, 0, 255};
// color to draw in
void setDrawColor(const int rgb[3]) {
float d = 255.0; // d = max value in an rgb color spectrum
glColor3f(rgb[0]/d, rgb[1]/d, rgb[2]/d); // set draw color R=x/255 G=y/255 B=z/255 where x,y,z are values in rgb channel respectively
}
void drawPlane() {
GLfloat A[3] = { -1, 0, 1 };
GLfloat B[3] = { 1, 0, 1 };
GLfloat C[3] = { 1, 0, -1 };
GLfloat D[3] = { -1, 0, -1 };
glBegin(GL_POLYGON);
glVertex3fv(A);
glVertex3fv(B);
glVertex3fv(C);
glVertex3fv(D);
glEnd();
}
GLfloat CamX = 0, CamY = 2, CamZ = 2;
// Display Call Back
void draw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear all drawings in buffer
glLoadIdentity();
gluLookAt(CamX, CamY, CamZ, 0, 0, 0, 0, 1, 0);
drawPlane();
setDrawColor(GREEN_COLOR); // sets the drawing color to GREEN
glutWireSphere(0.2, 20, 20);
glutSwapBuffers();// Render Now i.e convert Buffer to Picture
return;
}
// Initialization
void initialize()
{
glClearColor(0.1f, 0.1f, 0.1f, 0.1f); // Set Background Color
setDrawColor(RED_COLOR); // sets the drawing color to red
glEnable(GL_DEPTH_TEST); // enable viewing the 3d
glMatrixMode(GL_PROJECTION); // change to perspective projection
glLoadIdentity(); // what does this do?
glFrustum(-1, 1, -1, 1, 2, 10); // what does this do?
glMatrixMode(GL_MODELVIEW); // what does this do?
}
// Main
int main(int argc, char* argv[])
{
glutInit(&argc, argv); // Initialize GLUT
int x = 512, y = 512; // x and y value
glutInitWindowPosition(
(int)(glutGet(GLUT_SCREEN_WIDTH) - x) / 2,
(int)(glutGet(GLUT_SCREEN_HEIGHT) - y) / 2); // Position the window's center
glutInitWindowSize(x, y); // Set the window's initial width & height
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); // initialise the buffers needed. double buff, one for RGB color the other for x,y, z
glutCreateWindow("3D Bowling Game"); // Create a window with the given title
initialize(); // Custom initialisation
glutDisplayFunc(draw); // Register display callback handler for window re-paint
glutMainLoop(); // Enter the event-processing loop
return 0;
}
what am i doing wrong?
I need to make a game for a project on college. Everything works fine, the only problem is translating mouse coords (0,0 in top left corner) to openGL coords (0,0 in center of the screen).
In class we got the formula for doing this:
double openglX = ((double)x - [half horizontal res]) / [horizontal res] * [horizontal opengl range];
double openglY = -((double)y - [half vertical res]) / [vertical res] * [vertical opengl range];
#include <iostream>
#include <list>
#include <vector>
#include <cstdlib>
#include <ctime>
#define NDEBUG
#include <GL/freeglut.h>
const int GAME_LOGIC_REFRESH_TIME = 10;
/* GLUT callback Handlers */
void resize(int width, int height)
{
const float ar = (float)width / (float)height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
gluLookAt(0, 0, 45, 0, 0, 0, 0, 1, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void gameLogic(int value)
{
if (value == 0)
{
}
else if(value==1)
{
}
}
void move_ship(int x, int y)
{
double openglX = ((double)x - 600) / 1200 * 46;
double openglY = -((double)y - 500) / 1000 * 38;
player.SetPosition(openglX);
}
/* helper functions for settings options and parameters */
void InitGLUTScene(const char* window_name)
{
glutInitWindowSize(1200, 1000);
glutInitWindowPosition(40, 40);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
glutCreateWindow(window_name);
glClearColor(0, 0, 0, 0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
}
void SetCallbackFunctions()
{
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutTimerFunc(GAME_LOGIC_REFRESH_TIME, gameLogic, 0);
glutMouseFunc(mouse);
glutPassiveMotionFunc(move_ship);
}
void SetObjectsPositions()
{
}
int main(int argc, char *argv[])
{
srand(time(NULL));
glutInit(&argc, argv);
InitGLUTScene("Space Invaders");
SetCallbackFunctions();
SetObjectsPositions();
glutMainLoop();
return 0;
}
Calculations in move_ship are quite good close to center of the screen, but at the edges they are off enough, that it's a big problem and the player can't reach the edge of the screen.
The first thing I notice is you have some magical numbers in your method move_ship() . Your callback resize() is able to change the width and height, so using constants in move_ship() seems like a bug to me.
The formula should be
void mouseToGl(
double& x, double& y, // output GL coords
double mx, double my, // mouse coords in pixels (0,0 is top left)
double W, double H) // screen dimension width, height
{
x = 2.0 * (mx / W) - 1.0;
y = 2.0 * ((my - W + 1) / W) - 1.0;
}
I am making a 3d project in OpenGL which contain a ground (drawn as line loops). The issue I have is when the project starts only a single line is drawn as shown in the next image:
When I resize or maximize the window then the actual ground gets displayed like this:
Any idea how to resolve this issue? I'm a beginner in OpenGL programming.
Here is the code :
void drawHook(void);
void timer(int);
void drawFlorr();
float L = 100;
const int screenWidth = 1000; // width of screen window in pixels
const int screenHeight = 1000; // height of screen window in pixels
float ww = 800;
float wh = 800;
float f = 520, n = 10.0;
static GLdouble ort1[] = { -200, 200, -33, 140 };
static GLdouble viewer[] = { 525, 25, -180 };
static GLdouble objec[] = { 525.0, 25, -350 };
float x, y = 0.0, z, z1;
float xmax = screenWidth - 200.0;
float zmax = screenWidth - 200.0;
float xmin, zmin;
float step = 5.0;
float fov = 80;
void myInit(void)
{
glClearColor(0.0,0.0,0.0,0.0); // background color is white
glPointSize(2.0); // a 'dot' is 2 by 2 pixels
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, screenWidth, 0.0, screenHeight);//dino window
glViewport(0, 0, screenWidth, screenHeight);
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(viewer[0], viewer[1], viewer[2], objec[0], objec[1], objec[2], 0, 1, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, 1.333, n, f);
glPointSize(2.0);
glMatrixMode(GL_MODELVIEW);
drawFlorr();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // set display mode
glutInitWindowSize(screenWidth, screenHeight); // set window size
glutInitWindowPosition(10, 10); // set window position on screen
glutCreateWindow("Dino Line Drawing"); // open the screen window
glutDisplayFunc(myDisplay); // register redraw function
myInit();
//glutTimerFunc(1,timer,1);
glutMainLoop(); // go into a perpetual loop
return 1;
}
void drawFlorr()
{
xmin = -100;
zmin = -100;
for (x = xmin; x < xmax; x += step)
{
for (z = zmin; z < zmax; z += step)
{
z1 = -z;
glBegin(GL_LINE_LOOP);
glVertex3f(x, y, z1);
glVertex3f(x, y, z1-step+1.0);
glVertex3f(x + step - 1.0, y, z1 - step + 1.0);
glVertex3f(x+step-1.0, y, z1);
glEnd();
}
}
}
Your code is broken in many ways:
Your myDisplay function uses whatever the current matrix mode is to set the view matrix on.
Initially, you leave the matrix mode as GL_PROJECTION in myInit()
These two together mean that for the first frame, you just use identity as MODELVIEW matrix, and just overwrite the projection matrix twice. After a resize, the frame ais drawn again, and your code does waht you probably intented to do.
However, there is more:
You do not have any resize handler, so your viewport will not change when you resize the window.
You are setting an ortho matrix initailly for the projection, although you are not planning to use it at all.
and, the most import point:
All of your code depends on deprecated functionality which is not even available in modern OpenGL at all. You should really not use this in 2016, but learn modern OpenGL instead (with "modern" meaning "only a decade old" here).
I've got a taks from university and have to make a small example of solar system, the objects have to rotate etc. The problem is that when I do not call GluLookAt() everything looks fine, but I would like to change the view and when I call the function, there occurs that one orbit renders completely strangely.
I do not know if problem is with wrong creation of the first orbit, or with the proper values in gluLookAt parameters. Can anyone help?
Here's how it looks without calling gluLookAt():
Here's how it looks after gluLookAt():
Here's the code:
#include "stdafx.h"
#include <GL\glut.h>
#include <math.h>
GLfloat yRotated=1;
GLfloat movement = 0;
void drawCircle(float r) { // radius
glBegin(GL_LINE_LOOP);
for (int i = 0; i <= 300; i++) {
double angle = 2 * 3.14 * i / 300;
double x = r*cos(angle);
double y = r*sin(angle);
glVertex3d(x, y, -5.5);
}
glEnd();
}
void display(void) {
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
//gluLookAt(5, 5, 5, 0, 0, -8, 0, 1, 0); // 3rd coordinate - depth
float radius1 = 6;
float radius2 = 1;
//first orbit
glColor3f(1, 1, 1);
glPushMatrix();
glTranslatef(0, 0, -5.5);
drawCircle(radius1);
glPopMatrix();
//second orbit with rotation
glPushMatrix();
glRotatef(yRotated, 0, 0, 1);
glPushMatrix();
glTranslatef(radius1 / 2, 0, 0);
drawCircle(radius2);
glPopMatrix();
glPopMatrix();
//first czajnik
glColor3f(0.8, 0.2, 0.1);
glPushMatrix();
glTranslatef(0.0, 0.0, -5.5);
// glScalef(1.0, 1.0, 1.0);
glRotatef(yRotated, 0, 0, 1);
glRotatef(90, 1, 0, 0);
glutSolidSphere(1,20,20);
//second czajnik
glPushMatrix();
glColor3f(0, 0, 1);
glTranslatef(radius1/2, 0, 0);
glRotatef(yRotated, 0, 1, 0);
glutSolidSphere(0.5, 20, 20);
//third czajnik
glPushMatrix();
glTranslatef(radius2, 0, 0);
glColor3f(1, 1, 0);
glRotatef(yRotated, 0, 1, 0);
glutSolidSphere(0.2, 20, 20);
glPopMatrix();
//second czajnik pop
glPopMatrix();
//first czajnik pop
glPopMatrix();
glFlush();
}
void idle() {
yRotated += 0.1;
Sleep(2);
display();
}
void myReshape(int w, int h) {
if (w == 0 || h == 0) return;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0, (GLdouble)w / (GLdouble)h, 0.5, 20.0);
glViewport(0, 0, w, h);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(900, 600);
glutCreateWindow("Solar system");
//window with a title
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glClearColor(0, 0, 0, 1.0);
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
Some of your objects are at different z values, e.g. 1st orbit at -5.5, second at 0, because you "popped" the matrix.
In general, do not do so many push\pops nested into each other, matrix stack isn't made of rubber.
There is more efficient circle drawing procedure than to calculate sine and cosine for each step, e.g. to get advantage of circle being a figure of rotation:
inline void circle(F32 r, U32 quality)
{
if (r < F_ALMOST_ZERO) return;
F32 th = M_PI /(quality-1);
F32 s = sinf(th);
F32 c = cosf(th);
F32 t;
F32 x = r;
F32 y = 0;
::glBegin (GL_LINE_LOOP);
for(U32 i = 0; i < quality; i++)
{
glVertex2f(x, y);
t = x;
x = c*x + s*y;
y = -s*t + c*y;
}
::glEnd();
}
it can be optimized further by using symmetry, but this one is the basis.