I am trying to use a function to render a triangle with OpenGL.
The shape isn't appearing and I don't know why. I think it might be just because of the locations of the vertices.
Main method:
int main() {
glutInitWindowSize(400, 400);
glutInitWindowPosition(200, 200);
glutCreateWindow("Test");
Initialize();
glutDisplayFunc(Draw);
glutMainLoop();
return 0;
}
Initialise method:
void Initialize() {
glClearColor(0.1, 0.1, 0.1, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
drawTriangle function:
void drawTriangle(int v1x, int v1y, int v2x, int v2y, int v3x, int v3y, int red, int green, int blue)
{
//arguments are: "vertex 1 x coordinate", "vertex 1 y coordinate" etc
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_TRIANGLES);
glVertex2f(v1x, v1y); // v1
glVertex2f(v2x, v2y); // v2
glVertex2f(v3x, v3y); // v3
glEnd();
glFlush();
}
Draw method:
void Draw() {
drawTriangle(3.0, 2.9, 300, 300, 100, 100, 10, 0, 0);
}
Your coordinates are not fitting inside the defined ortho block
replace : glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
with this: glOrtho(0.0, 400.0, 0.0, 400.0, -1.0, 1.0);
The above is a temporary fix, it will help you understand how glOrtho works. Also, you are passing float arguments into the drawTriangle function, so you must replace all the parameters from int to float
Related
As the title says I'm tyring to model a simple giraffe out of arraycubes in open GL wiht C++, now I got the concepts done, but ran into an issue, when I start on the neck for some reaosn I lose 5 out of the 6 faces of my cube, the example I'm following doesn't result in this. I linked a small video below to show the visual result and I'm wondering what might be causing this. If there's an easier way to go about this as well please do let me know.
Visual Result
Code Sample
#include <glut.h>
float angle[4];
GLfloat corners[8][3] = { {-0.5,0.5,-0.5},{0.5,0.5,-0.5},
{0.5,-0.5,-0.5},{-0.5,-0.5,-0.5},
{-0.5,0.5,0.5},{0.5,0.5,0.5},
{0.5,-0.5,0.5},{-0.5,-0.5,0.5} };
void drawFace(int a, int b, int c, int d) {
glBegin(GL_POLYGON);
glVertex3fv(corners[a]);
glVertex3fv(corners[b]);
glVertex3fv(corners[c]);
glVertex3fv(corners[d]);
glEnd();
}
void ArrayCube() {
glColor3f(1.0, 1.0, 1.0);
drawFace(0, 3, 2, 1);
glColor3f(1.0, 1.0, 1.0);
drawFace(3, 0, 4, 7);
glColor3f(1.0, 1.0, 1.0);
drawFace(2, 3, 7, 6);
glColor3f(1.0, 1.0, 1.0);
drawFace(1, 2, 6, 5);
glColor3f(1.0, 1.0, 1.0);
drawFace(4, 5, 6, 7);
glColor3f(1.0, 1.0, 1.0);
drawFace(5, 4, 0, 1);
}
void LowerNeck()
{
glPushMatrix();
glTranslatef(0.5, 0.25, -0.125);
glScalef(0.0, 0.5, 0.25);
ArrayCube();
glPopMatrix();
}
void MainBody()
{
glPushMatrix();
glScalef(1.25, 0.25, 0.5);
ArrayCube();
glPopMatrix();
}
void DrawGiraffe()
{
glRotatef(angle[0], 0.0, 1.0, 0.0);
MainBody();
LowerNeck();
}
void rotate() {
angle[0] += 1.0;
if (angle[0] > 360) angle[0] -= 360;
glutPostRedisplay();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.6, 0.6, 0.6, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
DrawGiraffe();
glutSwapBuffers();
}
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 2.5);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Basic 3D");
glutDisplayFunc(display);
init();
glutIdleFunc(rotate);
glutMainLoop();
}
For the second object (the neck) you apply a scale transformation on x that scales the x component of all the following drawn vertices to 0.0:
glScalef(0.0, 0.5, 0.25);
That 0.0 should've probably been a 1.0.
That's the reason you only see one quad in the render video: That's the quad/face (actually two faces) which still have a dimension in Y and Z. The faces that have a dimension on x are squished to degenerate quads and not displayed at all.
So I am still a newbie with opengl and I used this tutorial as a reference
https://www.youtube.com/watch?v=8p76pJsUP44
I am now trying to draw a set of 4 triangles that made up a square (it's my project assignment) and this is my code
#include <Windows.h>
#include <GL\glew.h>
#include <GL\freeglut.h>
#include <iostream>
using namespace std;
void changeViewPort(int w, int h)
{
glViewport(0, 0, w, h);
}
void draw() {
glBegin(GL_TRIANGLES);
glColor3f(0.0, 0.0, 255.0);
glVertex3f(0.0, 0.0, 0.0); // top triangle
glVertex3f(-1.0,1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glColor3f(50.0, 50.0, 255.0);
glVertex3f(0.0, 0.0, 0.0); // right triangle
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glColor3f(75.0, 75.0, 255.0);
glVertex3f(0.0, 0.0, 0.0);//bottom triangle
glVertex3f(1.0, -1.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glColor3f(50.0, 50.0, 255.0);
glVertex3f(0.0, 0.0, 0.0); //left triangle
glVertex3f(-1.0, -1.0, 0.0);
glVertex3f(-1.0, 1.0, 0.0);
glEnd();
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw();
glutSwapBuffers();
}
int main(int argc, char* argv[]) {
// Initialize GLUT
glutInit(&argc, argv);
// Set up some memory buffers for our display
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
// Set the window size
glutInitWindowSize(350, 300);
// Create the window with the title "Hello,GL"
glutCreateWindow("Hello, GL");
// Bind the two functions (above) to respond when necessary
glutReshapeFunc(changeViewPort);
glutDisplayFunc(render);
//glutDisplayFunc(draw);
// Very important! This initializes the entry points in the OpenGL driver so we can
// call all the functions in the API.
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW error");
return 1;
}
glutMainLoop();
return 0;
}
notice that in my draw function, I am just trying to create 4 different triangles with different shades of blue.
However, whenever this code is executed, only the top triangle is blue while the rest stays white
Does anyone know why this wouldnt work ? I even tried to create a for loop version of the draw function but it also didnt work
void draw() {
double x = 1.0;
double y = 1.0;
double coords[8] = { -x,y,x,y,x,-y,-x,-y };
for (int i = 0; i < 7; i=i+2) { // i = [0,2,4,6]
switch (i) {
case 0:
glColor3f(0, 0, 255);
break;
case 2:
glColor3f(50, 50, 255);
break;
case 4:
glColor3f(75, 75, 255);
break;
case 6:
glColor3f(50, 50, 255);
break;
}
if (i == 6) { //4th and 1st coordinate
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(coords[i], coords[i + 1], 0.0);
glVertex3f(coords[0], coords[1], 0.0);
glEnd();
}
else {
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(coords[i], coords[i + 1], 0.0);
glVertex3f(coords[i + 2], coords[i + 3], 0.0);
glEnd();
}
}
}
glColor3f takes color components in the [0, 1] range as input and not [0, 255] as currently used.
Colors in OpenGL are stored in [0, 1] range. Unsigned ints map onto that range linearly automatically, but floats are just straight up stored.
See https://msdn.microsoft.com/en-us/library/windows/desktop/dd318399(v=vs.85).aspx
Im very new to OpenGL and can't understand why my code doesn't work.
It is supposed to draw 3 axis: x y and z. But only x and y are displayed.
int main()
int main(int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL lesson");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void reshape ()
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-15, 15, -15, 15, -15, 15);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(1, 1, 1, 0);
}
void display()
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
// draw line for x axis
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
// draw line for y axis
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
// draw line for Z axis
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
glutSwapBuffers();
}
Could someone help, please?
Axiz Z is drawn, but due to the camera's default position, there will be just a single pixel drawn.
The camera's default position is looking in the Z direction, perpendicular to the XY plane. You might want to look into gluLookAt to place your camera elsewhere or gluPerspective for a different viewing volume (more commonly used for 3D rendering than glOrtho).
I am new to OpenGL. I want to write a program that displays two shapes of two different colors, a Torus and a Sphere and two independent light sources that rotate around them.
So far I have this code which makes a light source that rotates around the Torus nicely. However I am unable to figure out how to add a Sphere and a new light source that rotates around it.
EDIT:
Here is my whole code. The light rotates when you push the 's' or 'd' key on keyboard
#include "stdafx.h"
#include <windows.h>
#include <glut.h>
static int spin = 0;
bool updown = false;
bool leftright = false;
GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 };
GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat direction[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat direction2[] = { 1.0, 0.0, 0.0, 0.0 };
void display() {
GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan);
glMaterialfv(GL_FRONT, GL_SPECULAR, white);
glMaterialf(GL_FRONT, GL_SHININESS, 30);
glTranslatef(-2.0, 1.0, 0.0);
glPushMatrix ();
if(updown){
glRotated ((GLdouble) spin, 1.0, 0.0, 0.0);
}
if(leftright){
glRotated ((GLdouble) spin, 0.0, 1.0, 0.0);
}
glLightfv (GL_LIGHT0, GL_POSITION, position);
glTranslated (0.0, 0.0, 1.5);
glDisable (GL_LIGHTING);
glColor3f (0.0, 1.0, 1.0);
glEnable (GL_LIGHTING);
glPopMatrix();
glutSolidTorus(0.275, 0.85, 16, 40);
glPopMatrix();
glFlush();
}
void reshape(GLint w, GLint h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
GLfloat aspect = GLfloat(w) / GLfloat(h);
glLoadIdentity();
if (w <= h) {
glOrtho(-2.5, 2.5, -2.5/aspect, 2.5/aspect, -10.0, 10.0);
} else {
glOrtho(-2.5*aspect, 2.5*aspect, -2.5, 2.5, -10.0, 10.0);
}
}
void init() {
glLightfv(GL_LIGHT0, GL_AMBIENT, black);
glLightfv(GL_LIGHT0, GL_DIFFUSE, yellow);
glLightfv(GL_LIGHT0, GL_SPECULAR, white);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void keyboard(unsigned char button, int x, int y)
{
switch (button) {
case 's':
updown = true;
leftright = false;
spin = (spin + 30) % 360;
glutPostRedisplay();
break;
case 'd':
updown = false;
leftright = true;
spin = (spin + 30) % 360;
glutPostRedisplay();
break;
default:
break;
}
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(80, 80);
glutInitWindowSize(800, 600);
glutCreateWindow("Shapes and light");
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
init();
glutMainLoop();
}
I believe the problem is more conceptual. OpenGL is stateful. What that means in practice is that you modify the state, draw something, modify the state again, draw something else. The state of OpenGL 1.x includes the matrix stack, materials, and the lights.
I believe in your mind, you want to add a new light object, then add a new object to draw, then have OpenGL render that. That is not how OpenGL works. There are no real objects in OpenGL.
What happens when you draw something, e.g. with glutSolidTorus, is that OpenGL puts pixels into buffers, including the screen. To determine the color of these pixels, it looks at the state you put it in before. So in order to draw two objects, you would first set up lighting, material, position for the first object, call glutSolidTorus, then set up the lighting, material, position for the second object, call glutSolidSphere. Note that you don't need to "add a new material", or "add a new light" for rendering the sphere. All you need to do is change the state before rendering, e.g. by moving GL_LIGHT0 to a different position.
void init (void)
{
glClearColor (1.0, 1.0, 1.0, 0.0);
//glMatrixMode(GL_MODELVIEW);
//gluLookAt(x0, y0, z0, xref, yref, zref, Vx, Vy, Vz);
glMatrixMode(GL_PROJECTION);
gluPerspective(45, 2, -1, 1);
//glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar);
//gluPerspective(45.0, 45, -1, 1);
}
void displayFcn (void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 1.0, 0.0);
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.1, 0.0, 0.0);
glVertex3f(0.50, 0.866025, 0.0);
glEnd();
glFlush();
}
void reshapeFcn(GLint newWidth, GLint newHeight)
{
glViewport(0,0,newWidth, newHeight);
winWidth = newWidth;
winHeight = newHeight;
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(400,200);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("Test");
init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(reshapeFcn);
glutMainLoop();
}
Could someone explain a little bit and give suggestions how to make that triangle visible.
I don't think that you're allowed to set 'zNear' negative. That will do weird things to the depth buffer and mean that you see things behind the eye. Docs say it's always positive. You're also liable to get somewhat strange results if you fix the aspect ratio to 2, regardless of the aspect ratio of the window.
You also need to set the current matrix back to MODEL_VIEW as datenwolf has shown. You don't need to use gluLookAt, but you need to do something to move the triangle away from the origin where the eye is located. You could do that by setting the z component to some negative value, or by applying a translation before the vertices:
glPushMatrix();
glTranslated(0,0,-5);
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.1, 0.0, 0.0);
glVertex3f(0.50, 0.866025, 0.0);
glEnd();
glPopMatrix();
gluPrespective and gluLookAt multiply on top of the current matrix on the selected stack. You need to load an identity first to make sense. Also you need to set a viewport before rendering. Best practice is to set all matrices and the viewport in the display function, and nowhere else. Sticking to that rule will make your life a lot easier. Also in OpenGL one usually doesn't have a dedicated initializtion phase. Resources are loaded on demand.
void displayFcn (void)
{
glViewport(0,0,winWidth, winHeight);
glClearColor (1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, 2, 1, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x0, y0, z0, xref, yref, zref, Vx, Vy, Vz);
glColor3f(0.0, 1.0, 0.0);
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.1, 0.0, 0.0);
glVertex3f(0.50, 0.866025, 0.0);
glEnd();
glFinish();
}
void reshapeFcn(GLint newWidth, GLint newHeight)
{
winWidth = newWidth;
winHeight = newHeight;
glutPostRedisplay();
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(400,200);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("Test");
glutDisplayFunc(displayFcn);
glutReshapeFunc(reshapeFcn);
glutMainLoop();
}