I have two viewports that are currently display 4 points in each of their corners. One viewport (left side) has gray corners, the other (right) has red corners. The two viewports are placed next to each other, with the red viewport intentionally made smaller. The viewport with red corners is also drawing a GL_TRIANGLES.
You can see them here:
The points in the triangle should be in the bottom left corner, top left corner and bottom right corner of the red viewport, but the bottom right corner is significantly short.
I think the second (red) glViewport is still using measurements from a previous object, the other viewport probably.
Am I setting up the second viewport correctly?
I want to have the second viewport 100 pixels across, not 900 pixels, squeezed into 100 pixels.
Here is my code.
I am using the latest version of glut and currently still learning how to use OpenGL/glut.
// windows/pannels
int winWidth = 900; // window width
int winHeight = 600; // window height
int pannelToolsWidth = 100;
int pannelToolsHeight = winHeight;
int pannelToolsX = winWidth - pannelToolsWidth;
int pannelToolsY = 0;
int drawSpaceWidth = winWidth - pannelToolsWidth;
int drawSpaceHeight = winHeight;
// drawing
float red = 0.0f;
float green = 0.0f;
float blue = 0.0f;
float lineSize = 1.0f;
float pointSize = 1.0f;
// ...
// draws a pannel. Make sure to define a colour before calling.
void drawPannel(int x, int y, int width, int height)
{
glBegin(GL_TRIANGLES);
glVertex2f(float(x), float(y));
glVertex2f(float(x), float(height));
glVertex2f(float(width), 0.0);
glEnd();
//glBegin(GL_TRIANGLES);
// glVertex2f(, );
// glVertex2f(, );
// glVertex2f(, );
//glEnd();
}
// Starts a new glViewport and visualises the bounderies with coloured points.
// scene: id of the viewport (viewports draw different things)
// x/y: viewports draw from the bottom left corner
void drawViewport(int x, int y, int width, int height, float red, float green, float blue, int scene)
{
// draw viewport (colours used to visualise limits)
glViewport(x, y, width, height);
glColor3f(red, green, blue);
glBegin(GL_POINTS);
glVertex2f(0.0f, float(winHeight));
glVertex2f(float(winWidth), float(winHeight));
glVertex2f(0.0f, 0.0f);
glVertex2f(float(winWidth), 0.0f);
glEnd();
// draw viewport content. text methods should be called last because the glRasterPos2i() effects the viewport
switch (scene)
{
// add more cases for other viewports here.
case 0:
// colour
// drawing
// text
break;
case 1:
glColor3f(0.8, 0.8, 0.7);
drawPannel(0, 0, pannelToolsWidth, pannelToolsHeight);
break;
default:
// do nothing
break;
}
}
void init()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //set clear background colour
glPointSize(10.0); //set point size
glColor3f(1.0f, 1.0f, 1.0f); //set draw colour
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, winWidth, 0, winHeight); //setup 2D projection
}
void collectScene()
{
glClear(GL_COLOR_BUFFER_BIT);
// viewport(s)
drawViewport(0, 0, drawSpaceWidth, drawSpaceHeight, 0.5, 0.5, 0.5, 0); // paint area
drawViewport(pannelToolsX, pannelToolsY, pannelToolsWidth, pannelToolsHeight, 1, 0, 0, 1); // GUI area
glFlush();
glutSwapBuffers(); //swap front and back buffers
}
//called when no event in queue
void idle()
{
glutPostRedisplay();
}
int main()
{
// create the window
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); // double buffer with RGBA
glutInitWindowSize(winWidth, winHeight);
glutInitWindowPosition(100, 100); // from top left
glutCreateWindow("Paint");
init();
glutDisplayFunc(collectScene);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
Thank you
Projection matrix is relative to the viewport, indeed it is usually set after glViewport call. In your case it doesn't change.
Related
I want to draw tow circles with the same radii but exclude the overlapped area when drawing.
I want to draw or set dots on gray area.
I implement the mathematical aspect behind it and here is my code:
void draw_venn(){
float radian_to_degree_theta=2 * 3.14 / 360,
r = 0.5,
distance=0.3,
theta=0.0,
theta2=0.0,
xR=0.0,
yR=0.0,
xG=0.0,
yG=0.0,
sum_radii=0,
dis=0.0;
sum_radii=r+r;
for (r = 0.5; r >=0; r-=0.001)
{
for (float degree = 0; degree < 361; degree+=0.1)
{
theta =degree*radian_to_degree_theta;
xR=r*cos(theta)+distance;
yR=r*sin(theta);
xG=r*cos(theta)-distance;
yG=r*sin(theta);
dis=sqrt(pow(xR-xG,2) + pow(yR-yG,2));
if (dis <= sum_radii)
{
set_point(xR,yR,0.1,1,0,0);
set_point(xG,yG,0.1,0,1,0);
}
}
}
}
void set_point(float x,float y,float size,float R,float G,float B){
glPointSize(size);
glBegin (GL_POINTS);
glColor3f (R, G, B);
glVertex2f(x, y);
glEnd ();
}
void draw(void)
{
glClearColor (1, 1, 1, 0);
glClear (GL_COLOR_BUFFER_BIT);
glPushMatrix();
draw_ven();
glPopMatrix ();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(1400, 1400);
glutInitWindowPosition(700, 500);
glutCreateWindow("GL Sample");
glutDisplayFunc(draw);
glutMainLoop();
return 0;
}
and here is the result:
How can I find if a point is inside the overlapping area?
I reviewed and tested out your code. Trigonometry can get a bit tricky. Following is the "draw_venn" function with some refinements to produce an overlap effect.
void draw_venn()
{
float radian_to_degree_theta=2 * 3.141 / 360,
r = 0.5,
distance=0.3,
theta=0.0,
theta2 = 0.0,
xR=0.0,
yR=0.0,
xG=0.0,
yG=0.0,
dis=0.0;
glPointSize(1);
glColor3f(1,0,0);
glBegin(GL_POINTS);
for (r = 0.5; r >=0; r-=0.001)
{
for (float degree = 0; degree < 361; degree+=0.1)
{
theta =degree*radian_to_degree_theta;
theta2 = (180.0 - degree) * radian_to_degree_theta;
xR=r*cos(theta2)+distance;
yR=r*sin(theta2);
xG=r*cos(theta)-distance;
yG=r*sin(theta);
dis = sqrt(pow((distance - xG), 2) + pow(yG, 2));
if (dis < 0.5)
{
set_point(xR,yR,0.1,0,0,1); /* Color the overlap blue */
set_point(xG,yG,0.1,0,0,1); /* This works due to symmetry */
}
else
{
set_point(xR,yR,0.1,1,0,0); /* Set the symmetrical circle colors */
set_point(xG,yG,0.1,0,1,0);
}
}
}
glEnd();
}
Pointing out the two significant revisions, first I derive a mirror image value for "theta" and place that into variable "theta2". That is used to draw the red circle. This assures that the circle images are being built in equal but opposite directions so that the coordinates are symmetrical. Second, I revised the formula for checking if the green image coordinates fall within the red circle's outermost radius. Using the Pythagorean theorem calculation for the hypotenuse, the formula determines if the hypotenuse value is smaller than the outermost radius length (0.5). If it is smaller make that point for the green circle blue, and since the circle points are being built and colored symmetrically, also make the corresponding point for the red circle blue.
The result of those revisions is a Venn Diagram showing an overlap.
I hope that helps and gives you a springboard to proceed.
Regards.
Add 8bit Stencil Buffer to your context
I do it by setting up pixelformat like this:
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory( &pfd, sizeof( pfd ) ); // set the pixel format for the DC
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
Enable and Clear Stencil with 0 and setup it for incrementation
Disable color and depth output
Render circles
Enable color and depth output
Set up Stencil test to not equal 2
You can also use equal to 1 in case you overlap more than just 2 objects
Render circles
Disable Stencil test
I see it like this:
//---------------------------------------------------------------------------
void glCircle(float x,float y,float r)
{
int e;
float a,da=2.0*M_PI/72.0;
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x,y);
for (e=1,a=0.0;e;a+=da)
{
if (a>=2.0*M_PI) { e=0; a=0.0; }
glVertex2f(x+(r*sin(a)),y+(r*cos(a)));
}
glEnd();
}
//---------------------------------------------------------------------------
void gl_draw()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
float aspect=float(xs)/float(ys); //xs,ys is screen resolution
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0,aspect,1.0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
// turn off color,depth
glStencilMask(0xFF);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
// clear stencil and setup it for increment
glEnable(GL_STENCIL_TEST);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS,1,0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
// render stencil
glCircle(-0.3,0.0,0.6);
glCircle(+0.3,0.0,0.6);
// turn on color,depth
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
// render screen (where Stencil is not 2)
glStencilFunc(GL_NOTEQUAL,2,0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glColor3f(1.0,0.0,0.0); glCircle(-0.3,0.0,0.6);
glColor3f(0.0,1.0,0.0); glCircle(+0.3,0.0,0.6);
glDisable(GL_STENCIL_TEST);
glFlush();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
And output:
In case you also want to know if pixel is inside both circles you can use:
GLint a;
glReadPixels(X,ys-1-Y,1,1,GL_STENCIL_INDEX,GL_INT,&a);
if (a==2); // X,Y is inside both circles
else; // X,Y is not inside both circles
In case You insist on rendering the stuff pixel by pixel then do it at least properly As your current approach is horibly slow for many reasons... For example you can do this like this:
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glTranslatef(-1.0,-1.0,0.0);
glScalef(2.0/xs,2.0/ys,1.0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
int x0=(4*xs)/10,y0=ys/2,r0=xs/4; // circle0
int x1=(6*xs)/10,y1=ys/2,r1=xs/4; // circle1
int x,y,xx0,xx1,yy0,yy1,rr0=r0*r0,rr1=r1*r1;
glBegin(GL_POINTS);
glColor3f(1.0,0.0,0.0);
for (x=-r0;x<=r0;x++){ xx0=x; xx0*=xx0; xx1=x+x0-x1; xx1*=xx1;
for (y=-r0;y<=r0;y++){ yy0=y; yy0*=yy0; yy1=y+y0-y1; yy1*=yy1;
if (xx0+yy0<=rr0)
if (xx1+yy1>=rr1)
glVertex2i(x0+x,y0+y); }}
glColor3f(0.0,1.0,0.0);
for (x=-r1;x<=r1;x++){ xx1=x; xx1*=xx1; xx0=x+x1-x0; xx0*=xx0;
for (y=-r1;y<=r1;y++){ yy1=y; yy1*=yy1; yy0=y+y1-y0; yy0*=yy0;
if (xx1+yy1<=rr1)
if (xx0+yy0>=rr0)
glVertex2i(x1+x,y1+y); }}
glEnd();
glFlush();
SwapBuffers(hdc);
Where xs,ys is GL screen resolution.
See related:
I have an OpenGL Tessellated Sphere and I want to cut a cylindrical hole in it
OpenGL 3D-raypicking with high poly meshes
Is there a more efficient way of texturing a circle?
in image appearing red opaque but i set the glColor3f(1.0f, 0.0f, 0.0f);
//command compiler g++ console tested with Visual Studio Code
//g++ GL01Hello.cpp -o GL01Hello.exe -L"C:/MinGW/freeglut/lib" -lglu32 -lopengl32 -lfreeglut -I"C:\MinGW\freeglut\include\GL"
/*
* GL01Hello.cpp:With Load Background Image and Poligon Test OpenGL/GLUT C/C++ Setup
* Tested Visual Studio Code with MinGW
* To compile with -lfreeglut -lglu32 -lopengl32 and
*/
#include <windows.h> // for MS Windows
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <ctime>
#include <freeglut.h> // GLUT, include glu.h and gl.h
using namespace std;
float spin = 0.0;
GLuint texture = 0;
int w1 = 0;
int h1 = 0;
// for random color primitive polygon
//static GLubyte redc,greenc,bluec;
bool prim_polygonmode = false;
// glut_load_image
GLuint LoadTexture( const char * filename )
{
GLuint texture;
int width, height;
unsigned char * data;
FILE * file;
file = fopen( filename, "rb" );
if(!file)
std::cout<<"File not Found"<<std::endl;
if ( file == NULL ) return 0;
width = 1360;
height = 768;
data = (unsigned char *)malloc( width * height * 3 );
//int size = fseek(file,);
fread( data, width * height * 3, 1, file );
fclose( file );
for(int i = 0; i < width * height ; ++i)
{
int index = i*3;
unsigned char B,R;
B = data[index];
R = data[index+2];
data[index] = R;
data[index+2] = B;
}
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );//Necessary for correct elements value 4 default
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT );
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,GL_RGB, GL_UNSIGNED_BYTE, data );
free( data );
return texture;
}
/* Initialize OpenGL Graphics just n this case for colors */
void initGL() {
// Set "clearing" or background color
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black and opaque
//randomnumber color by ctime library
srand(time(NULL));
//redc = rand()%255;
//greenc = rand()%255;
//bluec = rand()%255;
}
/* Called back when there is no other event to be handled */
void idle() {
spin = spin + 0.075;
if (spin > 360.0)
spin = 0;
glutPostRedisplay(); // Post a re-paint request to activate display()
}
/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei width, GLsizei height) { // GLsizei for non-negative integer
// Compute aspect ratio of the new window
w1 = width;
h1 = height;
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);
// Set the aspect ratio of the clipping area to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity();
if (width >= height) {
// aspect >= 1, set the height from -1 to 1, with larger width
gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -1.0, 1.0);
} else {
// aspect < 1, set the width to -1 to 1, with larger height
gluOrtho2D(-1.0, 1.0, -1.0 / aspect, 1.0 / aspect);
}
}
void orthogonalStart()
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(-w1/2, w1/2, -h1/2, h1/2);
glMatrixMode(GL_MODELVIEW);
}
void orthogonalEnd()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void background()
{
glBindTexture( GL_TEXTURE_2D, texture );
orthogonalStart();
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPolygonOffset(1,1);
// texture width/height
const int iw = 1360;
const int ih = 768;
glPushMatrix();
glTranslatef( -iw/2, -ih/2, 0 );
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f); // always default color white stars, if no this line will random color same of polygon
glTexCoord2i(0,0); glVertex2i(0, 0);
glTexCoord2i(1,0); glVertex2i(iw, 0);
glTexCoord2i(1,1); glVertex2i(iw, ih);
glTexCoord2i(0,1); glVertex2i(0, ih);
glEnd();
glPopMatrix();
orthogonalEnd();
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClear(GL_COLOR_BUFFER_BIT);// Clear the color buffer (background
glEnable( GL_TEXTURE_2D );
background();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// A SQUARE PARAMETERS
if (prim_polygonmode) { // draw polygon mode lines
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
} else {
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPolygonOffset(1,1);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glRotatef(spin , 0., 0., 1.);
glTranslatef(50.0, 50.0, 0);
glTranslatef(-50.0, -50.0, 0);
glBegin(GL_QUADS); // Each set of 4 vertices form a quad
//glColor3ub(redc, greenc, bluec); // Random red green blue value
glColor3f(1.0f, 0.0f, 0.0f); // Random red green blue value
glVertex2f(-0.5f, -0.5f); // x, y default 0.5f values
glVertex2f( 0.5f, -0.5f);
glVertex2f( 0.5f, 0.5f);
glVertex2f(-0.5f, 0.5f);
glEnd();
//angle += 5.0f;
glPopMatrix();
// glFlush(); // Render now
glutSwapBuffers(); // Double buffered - swap the front and back buffers
}
/* Callback handler for special-key event */
void specialKeys(int key, int x, int y) {
switch (key) {
case GLUT_KEY_F1: // F1: Toggle wireframe and solid polygon
prim_polygonmode = !prim_polygonmode; // Toggle state
break;
}
}
/* Main function: GLUT runs as a console application starting at main() */
int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(1360, 768); // Set the window's initial width & height
glutInitWindowPosition(0, 0);
// Position the window's initial top-left corner
glutCreateWindow("OpenGL Setup Test"); // Create a window with the given title
glutSpecialFunc(specialKeys); // Register callback handler for special-key event
glutDisplayFunc(display); // Register display callback handler for window re-paint
glutReshapeFunc(reshape);
glutIdleFunc(idle);
// GLuint texture;
texture = LoadTexture( "stars.bmp" );
initGL();
glutMainLoop();// Enter the event-processing loop
//Free our texture
glDeleteTextures( 1, &texture );
return 0;
}
This code have a set background and small animation of square.
Dont know wihy cant set more the solid colors. Then the wireframe square i got a very litle line red need got the bright color red.Maybe any filte, ou buffer causing that?
if possible please help me.
OpenGL is a state engine. Once a state is set, it is persistent until it is change again.
This means if 2 dimensional texturing is enabled, all the following geometry is "textured".
Note, when glVertex2f is called then the current texture coordinate is associated with the vertex coordinate. If you don't explicitly set a texture coordinate, then the last texture coordinate which was set is still the current texture coordinate and will be associated to the vertex coordinate. This may cause a random like behavior.
If texturing is enabled, then by default the color of the texel is multiplied by the current color, because by default the texture environment mode (GL_TEXTURE_ENV_MODE) is GL_MODULATE. See glTexEnv.
That all means:
If you want to draw a geometry with a texture then enable texturing and set a "white" color:
glEnable(GL_TEXTURE_2D)
glColor3f(1.0f, 1.0f, 1.0f);
background();
If you want to draw a uniform colored geometry, then set the color and disable texturing:
glDisable(GL_TEXTURE_2D);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
// [...]
glEnd();
hello I am using glut and opengl with c++ , I have home I want to draw blue QUADS in it my problem when I draw the QUADS all the sense color in blue , so how I can to color only QUADS in blue color and Prevents to color all sense in blue color what I do wrong how to remove the blue color from all the sense and color only my QUAD?
my try:
void drawSquare1()
{
glBegin(GL_QUADS);
glColor3d(1,0,0);
glVertex3f(-0.5,-0.5,-0.5);
glColor3d(1,1,0);
glVertex3f(0.5,-0.5,-0.5);
glColor3d(1,1,1);
glVertex3f(0.5,0.5,-0.5);
glColor3d(0,1,1);
glVertex3f(-0.5,0.5,-0.5);
glEnd();
}
void render(void) // Our Rendering Is Done Here
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
GLfloat xtrans = -g_xpos;
GLfloat ztrans = -g_zpos;
GLfloat ytrans = -g_ypos;
if(g_yrot > 360)
g_yrot -= 360;
else if(g_yrot < 0)
g_yrot += 360;
GLfloat sceneroty = (360.0f - g_yrot);
int numpolygons;
glRotatef(g_lookupdown,1.0f,0,0);
glRotatef(sceneroty,0,1.0f,0);
glTranslatef(xtrans, ytrans, ztrans);
numpolygons = g_sector1.numpolygons;
for (int loop_m = 0; loop_m < numpolygons; loop_m++)
texture_object(loop_m);
gluQuadricDrawStyle(my_shape[0],GLU_FILL);
glBindTexture(GL_TEXTURE_2D, textures[1].texID);
glScalef(0.1,0.1,0.1);
glTranslatef(0.78,14.3,-4.2);
gluSphere(my_shape[0], 1.0,50,50);
gluQuadricDrawStyle(my_shape[1],GLU_FILL);
glBindTexture(GL_TEXTURE_2D, textures[8].texID);
glTranslatef(-20,0,0);
gluSphere(my_shape[1], 1.0,50,50);
gluQuadricDrawStyle(my_shape[2],GLU_FILL);
glBindTexture(GL_TEXTURE_2D, textures[22].texID);
glTranslatef(40,0,0);
gluSphere(my_shape[2], 1.0,50,50);
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPushMatrix(); // Store The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
glOrtho(-10,window_width,0,window_height,-10,10); // Set Up An Ortho Screen
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
drawSquare1();
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPopMatrix(); // Restore The Old Projection Matrix
//glPushMatrix();
drawSquare1();
//glPopMatrix();
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glutSwapBuffers ( );
}
int main(int argc, char** argv) // Main Function For Bringing It All Together.
{
//cout << "Hello World!" << endl;
//cin.get();
glutInit(&argc, argv); // GLUT Initializtion
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE); // (CHANGED)
if (g_gamemode)
{
glutGameModeString("640x480:16"); // Select The 640x480 In 16bpp Mode
if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
glutEnterGameMode(); // Enter Full Screen
else g_gamemode = false; // Cannot Enter Game Mode, Switch To Windowed
}
screen_width = glutGet(GLUT_SCREEN_WIDTH);
screen_height = glutGet(GLUT_SCREEN_HEIGHT);
window_width = screen_width/1.4;
window_height = screen_height/1.4;
if (!g_gamemode)
{
glutInitWindowSize(window_width,window_height); // Window Size If We Start In Windowed Mode
glutInitWindowPosition((screen_width-window_width)/2,(screen_height-window_height)/2);
glutCreateWindow("Frank's 3-D House"); // Window Title
}
init();
glutIgnoreKeyRepeat(true); // Disable Auto Repeat (NEW)
// glutKeyboardFunc(myKey); // register the key handler.
glutDisplayFunc(render); // Register The Display Function
glutReshapeFunc(reshape); // Register The Reshape Handler
glutKeyboardFunc(keyboard); // Register The Keyboard Handler
//glRasterPos2f(lineMargin, currentHight); // set the cursor to the initial position.
glutSpecialFunc(special_keys); // Register Special Keys Handler
glutSpecialUpFunc(special_keys_up); // Called When A Special Key Released (NEW)
glutIdleFunc(game_function); // Process User Input And Does Rendering (CHANGED)
glutMouseFunc(mouse) ;
glutMainLoop(); // Go To GLUT Main Loop
return 0;
}
and this picture of run my code:
By default the texture environment mode (GL_TEXTURE_ENV_MODE) is GL_MODULATE. See glTexEnv.
This means if texturing is enabled (glEnable(GL_TEXTURE_2D)), then the color from the texture is multiplied by the color which is currently set by glColor.
To fix your issue, I recommend to set glColor4f(1.0f,1.0f,1.0f,1.0f); before the geometry is drawn:
void render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
.....
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
for (int loop_m = 0; loop_m < numpolygons; loop_m++)
texture_object(loop_m);
.....
}
Note, the current color is changed in the function drawSquare1 and keeps its state.
I am a beginner in OpenGl and I am struggling a bit with setting up the glOrtho camera to match the window size so that I can draw a line using the window's coordinates. For example, if I want to draw a line from coordinates 0,10 (x,y) to 600,10. I managed to draw the line (which will be a "Separator" from the viewport and a toolbar with buttons) in my current set up but it was by "try end error" approach and the coordinates that I needed to put don't make any sense to me. When I tried to draw a line using the above-mentioned coordinates, the line simply did not show up. What I need to change in the glOrtho set up in order to work with these (1000x600) screen size and draw my vertices and not these:
glVertex3f(-2.0, 11.0, 0.0);
glVertex3f(20.0, 11.0, 0.0);
Note, my current window size is 1000x600 (width/height)
This is the line (on the top that crosses the whole screen):
This is my OGWindow class that handles all of the drawing:
void OGWindow::MyReSizeGLScene(int fwidth, int fheight)
{
// Store window size in class variables so it can be accessed in myDrawGLScene() if necessary
wWidth = fwidth;
wHeight = fheight;
// Calculate aspect ration of the OpenGL window
aspect_ratio = (float) fwidth / fheight;
// Set camera so it can see a square area of space running from 0 to 10
// in both X and Y directions, plus a bit of space around it.
Ymin = -1;
Ymax = 12;
Xmin = -1;
// Choose Xmax so that the aspect ration of the projection
// = the aspect ratio of the viewport
Xmax = (aspect_ratio * (Ymax -Ymin)) + Xmin;
glMatrixMode(GL_PROJECTION); // Select The Projection Stack
glLoadIdentity();
glOrtho(Xmin, Xmax, Ymin, Ymax, -1.0, 1.0);
glViewport(0, 0, wWidth, wHeight); // Viewport fills the window
}
void OGWindow::myDrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the drawing area
OGWindow::myDrawModel();
drawToolbar();
glutSwapBuffers(); // Needed if we're running an animation
glFlush();
}
void OGWindow::myDrawModel(GLvoid)
{
switch ( squareColour ) {
case RED:
glColor3f(1.0, 0.0, 0.0);
break;
case BLUE:
glColor3f(0.0, 0.0, 1.0);
break;
}
glBegin( GL_QUADS );
glVertex3f( squareX, squareY, 0.0 ); // Coordinates of bottom-left corner of square
glVertex3f( squareX + squareWidth, squareY, 0.0 );
glVertex3f( squareX + squareWidth, squareY + squareHeight, 0.0 );
glVertex3f( squareX, squareY + squareHeight, 0.0 );
glEnd();
}
// Convert from screen coords returned by mouse
// to world coordinates.
// Return result in worldX, worldY
void OGWindow::screen2World(int screenX, int screenY, double & worldX, double & worldY)
{
// Dimensions of rectangle viewed by camera projection
double projWidth = Xmax -Xmin;
double projHeight = Ymax - Ymin;
// Screen coords with origin at bottom left
int screenLeft = screenX;
int screenUp = wHeight - screenY;
worldX = Xmin + screenLeft * projWidth / wWidth ;
worldY = Ymin + screenUp * projHeight / wHeight ;
}
//Method to draw the toolbar separator line
void OGWindow::drawToolbar(GLvoid) {
//draw toolbar line separator
glColor3f(0.0,0.0,0.0);
glBegin(GL_LINES);
glVertex3f(-2.0, 11.0, 0.0);
glVertex3f(20.0, 11.0, 0.0);
glEnd();
//draw create button
glPushMatrix();
glTranslatef(2.0, 10.0, 0.0);
glutSolidCube(2.0);
glPopMatrix();
}
This is my main class where I am ivoking the methods from OGWindow:
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize( 1000, 600 );
glutInitWindowPosition(0, 0);
glutCreateWindow("OpenGL Demo");
glEnable(GL_DEPTH_TEST); // enable the depth buffer test
glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
glutMouseFunc(mouseClick);
glutMotionFunc(mouseMotion);
glutPassiveMotionFunc(mousePassiveMotion);
glutIdleFunc(Idle);
theWindow.initGL();
glutMainLoop();
}
Check out the documentation of glOrtho function. As you see, there are 6 parameters: left, right, bottom, top, near, far. You made mistake by setting window width to top instead of bottom parameter. Here's proper use of function:
glOrtho (0, 1000, 600, 0, -1.0, 1.0)
So, first your ortho settings. If you want your camera to match the screen dimensions, glOrtho has to use the same dimensions.
// This will anchor the camera to the center of the screen
// Camera will be centered on (0,0)
glOrtho( -screenWidth/2.f, screenWidth/2.f, -screenHeight/2.f, screenHeight/2.f, -1, 1 );
// This will anchor the camera to the lower left corner of the screen
// Camera will be centered on (screenWidth/2, screenHeight/2)
glOrtho( 0, screenWidth, 0, screenHeight, -1, 1 );
Try both and see the difference. Although if you are making some sort of editor, where your camera doesn't move, you may be looking for the second ortho setup.
Second, you only ever use (apparently) the GL_PROJECTION matrix mode. You must use this mode to set the camera projection and GL_MODELVIEW to apply transforms to the camera or the objects.
So when you call resize and don't change the matrix mode back to GL_MODELVIEW, you'll be applying translations to the projection matrix.
If you did forget to initialize the modelview matrix it may contain garbage values and yield unexpected results.
I have some code to move a toy car from left to right.
I want to transform the code to stop its movement by the pressing of any key for example 's'....could someone help me do that...here is my code so far.
#include <GL/glut.h> // Header File For The GLUT Library
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
//#include <unistd.h> // Header File For sleeping.
/* ASCII code for the escape key. */
#define ESCAPE 27
/* The number of our GLUT window */
int window;
/* rotation angle for the triangle. */
float rtri = 0.0f;
/* rotation angle for the quadrilateral. */
float rquad = 0.0f;
/* A general OpenGL initialization function. Sets all of the initial parameters. */
// We call this right after our OpenGL window is created.
void InitGL(int Width, int Height)
{
// This Will Clear The Background Color To Black
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset The Projection Matrix
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
void ReSizeGLScene(int Width, int Height)
{
if (Height==0) // Prevent A Divide By Zero If The Window Is Too Small
Height=1;
glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
float ballX = -0.5f;
float ballY = 0.0f;
float ballZ = 0.0f;
void drawBall(void) {
glColor3f(0.0, 1.0, 0.0); //set ball colour
glTranslatef(ballX,ballY,ballZ); //moving it toward the screen a bit on creation
//glRotatef(ballX,ballX,ballY,ballZ);
glutSolidSphere (0.3, 20, 20); //create ball.
glTranslatef(ballX+1.5,ballY,ballZ); //moving it toward the screen a bit on creation
glutSolidSphere (0.3, 20, 20); //
}
/* The main drawing function. */
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(rtri,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
//glRotatef(rtri,1.0f,0.0f,0.0f); // Rotate The Triangle On The Y axis
// draw a triangle (in smooth coloring mode)
glBegin(GL_POLYGON); // start drawing a polygon
glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
glVertex3f(-1.0f, 1.0f, 0.0f); // Top left
glVertex3f(0.4f, 1.0f, 0.0f);
glVertex3f(1.0f, 0.4f, 0.0f);
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f( 1.0f,0.0f, 0.0f); // Bottom Right
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f(-1.0f,0.0f, 0.0f);// Bottom Left
//glVertex3f();
glEnd(); // we're done with the polygon (smooth color interpolation)
drawBall();
rtri+=0.005f; // Increase The Rotation Variable For The Triangle
if(rtri>2)
rtri=-2.0f;
rquad-=15.0f; // Decrease The Rotation Variable For The Quad
// swap the buffers to display, since double buffering is used.
glutSwapBuffers();
}
/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y)
{
/* sleep to avoid thrashing this procedure */
// usleep(100);
/* If escape is pressed, kill everything. */
if (key == ESCAPE)
{
/* shut down our window */
glutDestroyWindow(window);
/* exit the program...normal termination. */
exit(0);
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
/* get a 640 x 480 window */
glutInitWindowSize(640, 480);
/* the window starts at the upper left corner of the screen */
glutInitWindowPosition(0, 0);
/* Open a window */
window = glutCreateWindow("Moving Car");
/* Register the function to do all our OpenGL drawing. */
glutDisplayFunc(&DrawGLScene);
/* Go fullscreen. This is as soon as possible. */
//glutFullScreen();
/* Even if there are no events, redraw our gl scene. */
glutIdleFunc(&DrawGLScene);
/* Register the function called when our window is resized. */
glutReshapeFunc(&ReSizeGLScene);
/* Register the function called when the keyboard is pressed. */
glutKeyboardFunc(&keyPressed);
/* Initialize our window. */
InitGL(640, 480);
/* Start Event Processing Engine */
glutMainLoop();
return 1;
}
conditionally disable the following bit of code:
rtri+=0.005f; // Increase The Rotation Variable For The Triangle
if(rtri>2)
rtri=-2.0f;
rquad-=15.0f; // Decrease The Rotation Variable For The Quad
this can be done by adding the following to the keyPressed function
if (key == S)
{
updateGeom = false;//stop updating
}
if (key == D)
{
updateGeom = true;//start updating
}
and changing the above mentioned code as
if(updageGeom){
rtri+=0.005f; // Increase The Rotation Variable For The Triangle
if(rtri>2)
rtri=-2.0f;
rquad-=15.0f; // Decrease The Rotation Variable For The Quad
}
you need to add a global boolean updateGeom as well