Draw a triangle with OpenGL - c++

Write a C++ program which will draw a triangle having vertices at (300,210),
(340,215) and (320,250). Center of the triangle lies at (320,240).
#include <GL/glut.h>
#include <stdlib.h>
void display(void)
{
glClearColor(1,1,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(0.5,0,0);
glVertex2f(300.0,210.0);
glVertex2f(340.0,215.0);
glVertex2f(320.0,250.0);
glEnd();
glFlush();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(640,500);
glutInitWindowPosition(1,1);
glutCreateWindow("Triangle");
glutDisplayFunc(display);
glutMainLoop();
return EXIT_SUCCESS;
}
Issue triangle isn't appearing only a yellow screen appears.

Your program needs an appropriate view/projection matrix. glOrtho(0, 640, 480, 0, -1, 1) should do the trick. Ideally it should be called with MatrixMode set to GL_PROJECTION.

The coordinate system in OpenGL is from -1 -> 1. You'll have to convert your coordinates from your desired pixel values.
This can be done by some linear interpolation. Something like this should work:
float c = -1.0 + 2.0*desiredPixel/pixelWidth
You would need to do this conversion for all your triangle coordinates.

Below is a simple and valid triangle code:
glBegin(GL_TRIANGLES);
glColor3f(0.1, 0.2, 0.3);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(0, 1, 0);
glEnd();

glMatrixMode(GL_PROJECTION);
gluOrtho2D(0,400,0,500);
This solved my issue mostly 3D perspective was not working i think

Related

Depth Test in opengl

My program refuses to do depth testing. The two sphere objects are always drawn in the order they are created, not according to their position. Sphere alpha is positioned at (0, 0, 1) and Sphere beta is positioned (0, 0, -10), yet OpenGL still draws beta on top of alpha. I set depth test to enabled in my program.
Nothing appears to work. I want OpenGL to do depth test automatically on any objects drawn in the window. Any help or advise would be greatly appreciated. Here is the full code.
#include "GL/freeglut.h"
#include "GL/gl.h"
#include "GL/glu.h"
const int SPHERE_RES = 200;
double Z_INIT = -28.0;
double RADIUS = 2;
double Red[3] = {1, 0, 0};
double Blue[3] = {0, 0, 1};
using namespace std;
/*
* Method handles resize of the window
*/
void handleResize (int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double ratio = (float)w/ (float)h;
gluPerspective(45.0, ratio, 1.0, 100.0);
}
/*
* Color and depth is enabled and in this method
*/
void configureColor(void)
{
glClearColor(1.0f, 1.0f, 1.0f, 0.0f); //Set background to white
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear window.
glDepthFunc(GL_ALWAYS);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void display (void) {
configureColor();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat sun_direction[] = { 0.0, 0.0, -1.0, 0.0};
glLightfv(GL_LIGHT0, GL_POSITION, sun_direction);
GLUquadric* quad = gluNewQuadric();
//first sphere is drawn
glColor3f(Red[0], Red[1], Red[2]);
glPushMatrix();
glLoadIdentity();
glTranslatef(0, 0, Z_INIT);
glTranslatef(0, 0, 1.0);
gluSphere(quad, RADIUS, SPHERE_RES, SPHERE_RES);
glPopMatrix();
//second sphere is supposed to be drawn behind it,
//but it is drawn on top.
glColor3f(Blue[0], Blue[1], Blue[2]);
glPushMatrix();
glLoadIdentity();
glTranslatef(0, 0, Z_INIT);
glTranslatef(0, 0, -10.0);
gluSphere(quad, RADIUS, SPHERE_RES, SPHERE_RES);
glPopMatrix();
free(quad);
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); //initializes the GLUT
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow("OpenGL - First window demo");
glutReshapeFunc(handleResize);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
I am using Ubuntu 14.04 operating system.
glDepthFunc(GL_ALWAYS);
This is the reason you see the spheres in the order they are drawn. Setting the depth function to GL_ALWAYS simply means all depth tests always pass, for any fragment, be it closer or farther.
You need GL_LESS for the result you want. A fragment having depth lesser than the one in the frame buffer wins; the closer (lesser z) one wins over the farther (greater z) one.
You can either call glDepthFunc(GL_LESS) or comment out glDepthFunc(GL_ALWAYS) since GL_LESS is the default.

OpenGL glDrawElements only Black Screen

i was trying to draw a cube, using the glDrawElements function, but even the simple code below only gives me a black screen. If helps, i'm programming on XCode 6.
//
// main.cpp
// Copyright (c) 2014 Guilherme Cardoso. All rights reserved.
//
#include <iostream>
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <vector>
#include <math.h>
const GLfloat width = 500;
const GLfloat height = 500;
GLubyte cubeIndices[24] = {0,3,2,1,2,3,7,6
,0,4,7,3,1,2,6,5,4,5,6,7,0,1,5,4};
GLfloat vertices[][3] =
{{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},
{1.0,1.0,-1.0}, {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0},
{1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0}};
GLfloat colors[][3] =
{{0.0,0.0,0.0},{1.0,0.0,0.0},
{1.0,1.0,0.0}, {0.0,1.0,0.0}, {0.0,0.0,1.0},
{1.0,0.0,1.0}, {1.0,1.0,1.0}, {0.0,1.0,1.0}};
void display(){
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(3, GL_FLOAT, 0, colors);
glVertexPointer(3, GL_FLOAT, 0, vertices);
//glDrawArrays(GL_QUADS, 0, 24);
glDrawElements(GL_QUADS, 24,GL_UNSIGNED_BYTE, cubeIndices);
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
}
void mouse(int button, int state, int x, int y){
}
void keyboard(unsigned char key, int x, int y){
if(key=='q' || key == 'Q') exit(0);
}
void init(){
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,width ,height, 0);
glMatrixMode(GL_MODELVIEW);
glClearColor (1.0, 1.0, 1.0,1.0);
//glColor3f(0.0,0.0,0.0);
}
void idle(){
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutCreateWindow("Assignment 3");
glutPositionWindow(0, 0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
init();
glutMainLoop();
}
i already checked some tutorials, and is no much different of what i'm doing.
You never clear the color and especially the depth buffer. You should do that at the beginning of your display() function.
Also, your matrix setup is a bit weird. You set up some ortho projection for the pixels, but try to draw a cube in the range [-1,1], so it will be 2 pixel wide on the screen.
Actually your code is drawing the cube just fine. Look closely :P
The main issue is your projection. The initial GL viewing volume is a -1 to 1 cube, but the cube you're drawing is -1 to 1. The call to gluOrtho2D defines the projection in OpenGL coordinates, which you make the same as pixels, but since your cube is -1 to 1 it is only two pixels big, the rest being offscreen.
Instead, drop the gluOrtho2D, which sets the Z dimension -1 to 1 and only allows you to set X/Y, and create a slightly bigger projection...
glOrtho(-2, 2, -2, 2, -2, 2);
Note: As #derhass suggests, calling glClear is important especially with depth testing enabled (without it, the cube from the last draw call will hide the updated cube).

Drawing a Cone and Cylinder using GLUT

I've been trying to draw a cone and a cylinder using GLUT. The code I've written so far takes two points from the user, which represents the height of the cone/cylinder, and I want to draw a cone and a cylinder using the two points.
I looked up Google and found standard functions called glutWireCone() and gluCylinder(), but I'm unable to understand how to use these functions to draw in the manner that I want to draw. Can someone tell me how to draw a cone and a cylinder using the two points? Please let me know if you need some extra information to understand my question correctly.
Here are my init() and main() functions for you to know the settings of my program:
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, 0, -1000.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutInitWindowPosition(220, 80);
glutCreateWindow("Mini Paint - 3D");
init();
glutDisplayFunc(display);
glutMouseFunc(mouseClick);
glutMotionFunc(mouseMove);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Well lets take that gluCylinder function and apply it to your display function. Look at it's parameters:
void gluCylinder(GLU quadric* quad,
GLdouble base,
GLdouble top,
GLdouble height,
GLint slices,
GLint stacks);
So you want to draw a cylinder given the height parameter as input. I'm guessing everything else will remain constant. every time you render you'll want to use glPushMatrix and maybe glRotatef depending on how you would like its orientation, ending this call with a glPopMatrix
Ex: OnRender(float pHeight)
void OnRender(float pHeight) {
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); //clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity();
gluCylinder(quadratic, 0.1f, 0.1f, pHeight, 32, 32);
glFlush();
}
declaring a quadratic object:
GLUquadricObj *quadratic;
quadratic = gluNewQuadric();
gluCylinder documentation: https://www.opengl.org/sdk/docs/man2/xhtml/gluCylinder.xml

What's going on with my program (openGL in c++)?

I am starting with openGL and c++, and I was wondering why I don't see anything on the window. Here is my code:
#include <GLUT/GLUT.h>
#include <stdlib.h>
void init() {
glClearColor(0, 0, 1, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -10);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3i(-0.5, -0.5, 0);
glVertex3i(0, 0.5, 0);
glVertex3i(0.5, -0.5, 0);
glEnd();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE| GLUT_RGBA);
glutInitWindowPosition(200, 200);
glutInitWindowSize(400, 400);
glutCreateWindow("Window");
init();
glutDisplayFunc(display);
glutMainLoop();
}
I have a few questions:
If I run the program like this all I see is a white window... Didn't I set the color to blue?
When I do glutSwapBuffers() at the end of display function and run the program, I see the blue window without the triangle. So, I thought glutSwapBuffers() function only worked with double buffering.
And the most important, where the hell is my triangle? O.o Didn't I translate the camera with glTranslatf() function to -10 in the z-axes? If you are wondering why I used gluPerspective, I have to say that I am trying out new things, but neither works if I use gluOrtho2D().
I don't know if I am missing something or what. Maybe I need to search more information about this, but I think most of the code is correct.
1 & 2) Well you don't have to call glutSwapBuffers() when using single buffer. But you have to call glFlush(), so the draw commands are executed on the GPU.
3) I noticed that you are creating vertices with double coordinates, but you are calling integer version of glVertex** function (decimal part will be truncated) - it means that you will be drawing triangle with zero size.
Use glVertex3d() or glVertex3f() instead of glVertex3i().
Small note: intermediate mode is deprecated in the latest OpenGL.

Calling glRasterPos2i and glutBitmapString in the presence of ModelView transforms

I'm trying to display a text-overlay (basically a help screen which shows my keyboard shortcuts) on top of a 3D Texture I'm rendering. The texture works great and I've got some east-to-use rotations and translations for the user.
My thought was to use
const unsigned char tmp[100] = "text to render";
glRasterPos2i(x, y);
glColor4b(255, 255, 255, 255);
glutBitmapString(GLUT_BITMAP_HELVETICA_18, tmp);
As recommended in How do I use glutBitmapString() in C++ to draw text to the screen? .
This works great except that the text now rotates with the object instead of remaining in a static location on the screen. I read some documentation and found that the glRasterPos functions are manipulated when you manipulate the model view matrix:
The object coordinates presented by glRasterPos are treated just like those of a glVertex command: They are transformed by the current modelview and projection matrices and passed to the clipping stage.
-Source
I then found via another post that you could push and pop the current matrix with glPushMatrix and glPopMatrix.
-Source
When I do this, the text disappears all together. At first I thought I might have had the coordinates wrong for the text, but I tried x=y=0 through x=y=25 in intervals of .01 and never saw the text. It's still possible I'm misunderstanding where this should be drawn, but I'm not sure what to try next.
My drawing function is calling something akin to:
glLoadIdentity();
glPushMatrix();
glTranslatef(0,0,-sdepth);
glRotatef(-stheta, 1.0, 0.0, 0.0);
glRotatef(sphi, 0.0, 0.0, 1.0);
glRotatef(rotateX,0,1,1);
glRotatef(rotateY,1,0,0);
glTranslatef(-0.5,-0.5,-0.5);
glPopMatrix();
glRasterPos2i(2, 2);
glColor4b(255, 255, 255, 255);
glutBitmapString(GLUT_BITMAP_HELVETICA_18, tmp);
Anyone have any recommendations for debug/troubleshooting steps to try to get this text to display in a single, static location on the screen?
Well, if glRasterPos is treated the same way as glVertex, then you need to set up proper projection (GL_PROJECTION) matrix (using gluOrtho2D) before calling glRasterPos.
Give this a shot:
#include <GL/glut.h>
#include <string>
using namespace std;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3ub(255,0,0);
glPushMatrix();
glScalef(5,5,5);
glBegin(GL_QUADS);
glVertex2f(-1,-1);
glVertex2f(1,-1);
glVertex2f(1,1);
glVertex2f(-1,1);
glEnd();
glPopMatrix();
glColor3ub(0,255,0); // A
glRasterPos2i(0,0); // B
string tmp( "wha-hey!" );
for( size_t i = 0; i < tmp.size(); ++i )
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, tmp[i]);
}
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double aspect_ratio = (double)w / (double)h;
glOrtho(-10*aspect_ratio, 10*aspect_ratio, -10, 10, -1, 1);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(800,600);
glutCreateWindow("Text");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return EXIT_SUCCESS;
}
Oddly enough swapping lines A and B causes the glColor3ub() call to not take effect. I think that's what you were running into with the code sequence you posted.
As an aside glColor4b() takes chars which max out at 127. You should switch to glColor4ub() if you want to persist in passing in 255.
Documented here ("The sequence of glRasterPos(), glColor(), glBitmap() doesn't result in the desired bitmap color"), but no explanation given :(
EDIT: Ah ha! The current raster position contains its own color state, which is only updated during a glRasterPos() call.