If i comment out DrawGLScene(), i see a large shaded triangle, if I comment out drawtri() i see a square texture drawn. But I am not able to combine both - when both func's are called, I see only triangle outline and the texture is rendered with a strong red filter applied.
What could be the problem?
void DrawGLScene()
{
int x, y;
float float_x, float_y, float_xb, float_yb;
float x0=0,y0=0,x1=10,y1=10,z=-3;
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glEnable(GL_TEXTURE_2D);
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-12.0f); // move 12 units into the screen.
glBindTexture(GL_TEXTURE_2D, texture[0]); // choose the texture to use.
glPolygonMode(GL_BACK, GL_FILL);
glPolygonMode(GL_FRONT, GL_LINE);
glBegin(GL_QUADS);
glTexCoord2f( 0,0);
glVertex3f( x0, y0, z );
glTexCoord2f( 0, 1 );
glVertex3f( x0, y1, z );
glTexCoord2f( 1, 1);
glVertex3f( x1, y1, z );
glTexCoord2f( 1, 0 );
glVertex3f( x1, y0,z );
glEnd();
glDisable(GL_TEXTURE_2D);
// since this is double buffered, swap the buffers to display what just got drawn.
// glutSwapBuffers();
}
void drawtri() {
glBegin(GL_TRIANGLES);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd();
}
void zdisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen and Depth Buffer
glLoadIdentity();
glTranslatef(0.0f,0.0f,-3.0f);
//drawtri();
DrawGLScene();
glutSwapBuffers();
}
The red filter is caused by the applied color:
glColor3f(0.0f,0.0f,1.0f);
Reset the color to white before drawing the quad:
glColor3f(1.0f,1.0f,1.0f);
The outline is caused by the following specification:
glPolygonMode(GL_FRONT, GL_LINE);
Specify fill mode:
glPolygonMode(GL_FRONT, GL_FILL);
When calling both functions, did you actually call the methods in the order in which the code shows them? Because I suspect that the order was reversed. If I'm right, I think you must reset the glPolygonMode when drawing the triangle. Try adding glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) before the call to glBegin(GL_TRIANGLES).
Related
how can i create the full-screen effect with a texture image ?
till now i do this :
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
texture[0] = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
"my_img.jpg",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glutSwapBuffers();
}
this code places my image in the top-left position of the screen, but i would like the full-screen texture effect.
So, How can i accomplish that ?
As #BrettHale already suggested in the comment, just set all the matrices to the identity transformation:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Then get rid of any other transformations you have in place, like the glTranslatef() call you currently have in the code. Use 0.0f instead of 1.0f for the last coordinate of your vertices, and you should be good to go.
ok , I did it , and now it works. for a full-screen image i added this function
void resize(int height, int width) {
const float ar = (float) widthX / (float) heightY;
glViewport(0, 20, widthX, heightY);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar+1, ar-1, -1.0, 1.0, 2.0, 90.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
}
make sure to add this :
glutReshapeFunc(resize); // calling the "resize function"
I am trying to draw text using openGL which will be displayed in a window, over a kinect camera image. The program can draw squares and other shapes fine, but when I call the method to draw the text, it crashes. It seems to be crashing on the
glutStrokeCharacter(font, c);
Everything else works and when I comment out just this line the program still runs fine. Below is a code snippet of how I try and draw the text.
void Button::DrawSquare(bool selected)
{
glEnable( GL_POINT_SMOOTH );
glLineWidth(7);
if (selected == true) glColor3f(0,1,0);
else glColor3f((123.0/255.0f),(205/255.0f),(237.0/255.0f));
glBegin(GL_LINE_LOOP);
glVertex2f(X, Y);
glVertex2f(X+length, Y);
glVertex2f(X+length, Y+width);
glVertex2f(X, Y+width);
glEnd();
glLineWidth(3);
glColor3f(0,0,0);
glBegin(GL_LINE_LOOP);
glVertex2f(X, Y);
glVertex2f(X+length, Y);
glVertex2f(X+length, Y+width);
glVertex2f(X, Y+width);
glEnd();
glLineWidth(4);
//Start drawing text
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
if (selected == true) glColor3f(0,1,0);
else glColor3f(1,1,0);
void *font = GLUT_BITMAP_TIMES_ROMAN_10;
glRasterPos2i(this->X+15,this->Y+35);
string s(*this->trackname);
for (string::iterator i = s.begin(); i != s.end(); ++i)
{
char c = *i;
glutStrokeCharacter(font, c);// <<-- Line that gives error
}
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glColor3f(255,255,255);
}
The drawing of the squares just before the text works fine.
Here is a minimal working example of how to render text using glutBitmapCharacter:
static const std::string text_to_render = "testing 1 2 3 4";
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glDisable( GL_DEPTH_TEST ); // disable to render text in front of anything else
glRasterPos2f(0, 0); // center of screen
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GLvoid * font = GLUT_BITMAP_TIMES_ROMAN_10;
glColor3f(1.0f, 0.0f, 0.0f);
for(char chr : text_to_render)
{
glutBitmapCharacter(font, chr);
}
glEnable(GL_DEPTH_TEST); // re-enable depth test
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glutSwapBuffers();
}
The only difference here is that I'm disabling OpenGL's GL_DEPTH_TEST and I'm loading the identity matrices after pushing the current matrices.
Let me know if this is of any help.
I've been searching on how to draw an Indicator-Axis in my OpenGL scene. The project's nested in a Qt OpenGL widget, but I think the problem is independent of Qt.
I have found on here and forums from years ago that suggest storing the viewport and data, loading new ones for the botttom corner, apply my rotations and draw, then restore the matrices. This seems the most beneficial to me, but I'm guessing I'm still missing some critical info in my OpenGL knowledge.
For now I just have it drawing a red line from -x to x, so I expected to have a red square in the bottom left of the screen:
void GLWidget::drawAxis()
{
float tempPro[16];
float tempMod[16];
glGetFloatv(GL_PROJECTION_MATRIX, &tempPro[0]);
glGetFloatv(GL_MODELVIEW_MATRIX, &tempMod[0]);
glViewport(0, 0, 50, 50);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, 1.0f, 0.1f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
glEnable( GL_LINE_SMOOTH );
glLineWidth( 1.5 );
glVertex3f(-1000, 0, 0);
glVertex3f(1000, 0, 0);
glEnd();
glPopMatrix();
glViewport(0, 0, 960, 600);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(tempPro);
gluPerspective(45.0f, (960.0/600.0), 0.1f, 400.0f);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(tempMod);
}
Instead I get nothing, just a large empty scene, and I'm unsure how to proceed. My paintGL is essentially:
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Camera.Render();
glTranslatef(0.0, 0.0, 0.0);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(50.0f, 0.0f, 50.0f);
glVertex3f(50.0f, 0.0f, -50.0f);
glVertex3f(-50.0f, 0.0f, -50.0f);
glVertex3f(-50.0f, 0.0f, 50.0f);
glEnd();
drawAxis();
}
Not calling the draw-axis function still gives me my plane, with it, I get a large blank scene. Am I missing something in how I'm implementing the drawAxis? Should I setup another camera for the function or something like that?
You can use glPushMatrix() and glPopMatrix() to save and restore the state of your Projection and ModelView matrices.
Your not setting up your ModelView matrix to anything useful.
Try something like this:
void GLWidget::drawAxis()
{
glViewport(0, 0, 50, 50);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
gluPerspective(45.0f, 1.0f, 0.1f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//This really has to come from your camera....
gluLookAt(10.0f,10.0f,10.0f, 0.0f,0.0f,0.0f, 0.0f,0.1f,0.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glEnable( GL_LINE_SMOOTH );
glLineWidth( 1.5 );
glBegin(GL_LINES);
glVertex3f(-1000, 0, 0);
glVertex3f(1000, 0, 0);
glEnd();
//Restore View
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glViewport(0, 0, 960, 600);
}
Graphics: AMD Radeon HD 7900 Series
Running: Windows 7(64 bit)
Program: CodeBlocks(32 bit)
OpenGL Library: GLee
This is where I setup the window. Its an SDL window using OpenGL rendering.
void Init(int w, int h, bool fullScr)
{
if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
}
winW = w*scale;
winH = h*scale;
original_winW = w;
origianl_winH = h;
putenv("SDL_VIDEO_WINDOW_POS");
putenv("SDL_VIDEO_CENTERED=1");
getenv("SDL_VIDEO_WINDOW_POS");
getenv("SDL_VIDEO_CENTERED");
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 ); // *new*
//Sets up the screen and displays the window
screen = SDL_SetVideoMode( winW, winH, 32, SDL_OPENGL | (fullScr*SDL_FULLSCREEN) ); // *changed*
screenRect.x = 0;
screenRect.y = 0;
screenRect.w = winW;
screenRect.h = winH;
SDL_ShowCursor(false);
SetGLState();
}
This is the SetGLState() mentioned above.
void SetGLState(){
glEnable( GL_TEXTURE_2D ); //Enable 2d texturing
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); //Set clear color (rgba)
glViewport( 0, 0, winW, winH ); //Set the viewport
glClear( GL_COLOR_BUFFER_BIT ); //Clear back buffer?
glMatrixMode( GL_PROJECTION ); //Set to projection
glLoadIdentity();
glOrtho(0.0f, winW, winH, 0.0f, -1.0f, 1.0f); //Create orthogonal projection matrix
glMatrixMode( GL_MODELVIEW ); //Set back to model view
glLoadIdentity();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
This is where the images are drawn to the screen
void DrawImage(GLSurface image, float x, float y)
{
// Bind the texture to which subsequent calls refer to
if(boundTexture != image.Surface){glBindTexture( GL_TEXTURE_2D, image.Surface ); boundTexture = image.Surface; }
glReadPixels(x,y,image.w*2,image.h*2,GL_UNSIGNED_BYTE,NULL,NULL);
glLoadIdentity();
glScalef(scale,scale,1);
glRotatef(image.rotation[0], 1.0f, 0.0f, 0.0f);
glRotatef(image.rotation[1], 0.0f, 1.0f, 0.0f);
glRotatef(image.rotation[2], 0.0f, 0.0f, 1.0f);
if(scale == 7.5)x += 48;
glBegin( GL_QUADS );
//Bottom-left vertex (corner)
glColor3b(127,127,127);
glTexCoord2i( 0, 0 ); //Position on texture to begin interpolation
glVertex3f( x, y, 0.f ); //Vertex Coords
//Bottom-right vertex (corner)
glTexCoord2i( 1, 0 );
glVertex3f( x+image.w, y, 0.f );
//Top-right vertex (corner)
glTexCoord2i( 1, 1 );
glVertex3f( x+image.w, y+image.h, 0.f );
//Top-left vertex (corner)
glTexCoord2i( 0, 1 );
glVertex3f( x, y+image.h, 0.f );
glEnd();
}
This window doesn't draw anything, and I can't figure out why. I haven't looked at this code in awhile, but I know that on a previous install of windows, I had it working. All of my other projects run, but this one doesn't. It just renders a blank screen. The weird thing is--I have a resize function for this window. When that function gets called, the screen displays a white screen instead of a black one.
Edit**
This code is called at the end once everything has been drawn to the screen. It was already included in my code.
void Flip(){
SDL_GL_SwapBuffers();
glClear( GL_COLOR_BUFFER_BIT );
}
All the state set in SetGLState is drawing state. Call it from the DrawImage function. Most importantly, glClear must be put in the draw function, it doesn't make sense anywhere else.
That call to glReadPixels makes no sense.
And you must swap the buffers when done SDL_SwapBuffers (IIRC, haven't used SDL in some time).
I am attempting to draw a quadrilateral (square) on the screen. I inserted this into a pre-existing program that drew a cylinder. This is in an orthographic modelview matrix, and I am almost positive the clipping volume is correct (It's 200 in any direction from the origin). In the display function I'm using, I pushed a matrix, translated forward (0.0,0.0,-20.0), called quadriliteral, and then popped the matrix. Are the any common openGL settings people use that I'm unaware of that may make this not visible? Is there a way to get the current clipping volume and print it out in the console?
void quadrilateral()
{
glLoadIdentity();
glColor3f(0.5f,0.0f,0.8f);
glBegin(GL_QUADS);
glVertex3f(-10.0f,-10.0f,0.0f);
glVertex3f(-10.0f,10.0f,0.0f);
glVertex3f(10.0f,10.0f,0.0f);
glVertex3f(10.0f,-10.0f,0.0f);
glEnd();
}
//This is called from a main function elsewhere
void draw(void)
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Cylinder");
glutReshapeFunc(CChangeSize);
glutSpecialFunc(CSpecialKeys);
glutKeyboardFunc(Ckeyboard);
glutDisplayFunc(CRenderScene);
CSetupRC();
glPopMatrix();
}
void CSetupRC()
{
// Light values and coordinates
GLfloat ambientLight[] = {0.4f, 0.4f, 0.4f, 1.0f };
GLfloat diffuseLight[] = {0.7f, 0.7f, 0.7f, 1.0f };
GLfloat specular[] = { 0.9f, 0.9f, 0.9f, 1.0f};
GLfloat lightPos[] = { -50.0f, 200.0f, 200.0f, 1.0f };
GLfloat specref[] = { 0.6f, 0.6f, 0.6f, 1.0f };
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glEnable(GL_CULL_FACE); // Do not calculate inside of solid object
glFrontFace(GL_CCW);
// Enable lighting
glEnable(GL_LIGHTING);
// Setup light 0
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientLight);
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
// Position and turn on the light
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);
// Enable color tracking
glEnable(GL_COLOR_MATERIAL);
// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// All materials hereafter have full specular reflectivity
// with a moderate shine
glMaterialfv(GL_FRONT, GL_SPECULAR,specref);
glMateriali(GL_FRONT,GL_SHININESS,64);
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 0.0f );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_2D);
}
// Called to draw scene
void CRenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Save the matrix state
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// Rotate about x and y axes
glRotatef(CxRot, 1.0f, 0.0f, 0.0f);
glRotatef(CyRot, 0.0f, 1.0f, 0.0f);
// Draw the cylinder
cylinder();
glPopMatrix();
// CylinderTwo
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// Rotate about x and y axes
glRotatef(CxRot, 1.0f, 0.0f, 0.0f);
glRotatef(CyRot, 0.0f, 1.0f, 0.0f);
// Draw the cylinder
glRotatef(120.0f, 1.0f, 1.0f, 1.0f);
cylinderTwo();
glPopMatrix();
// Random square
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(-30.0f,20.0f,10.0f);
quadrilateral();
glPopMatrix();
// Swap buffers
glutSwapBuffers();
}
It looks like your winding order is incorrect:
glEnable(GL_CULL_FACE);
this line means it will cull back faces.
glFrontFace(GL_CCW);
and this sets the front face to counter clockwise.
glVertex3f(-10.0f,-10.0f,0.0f);
glVertex3f(-10.0f,10.0f,0.0f);
glVertex3f(10.0f,10.0f,0.0f);
glVertex3f(10.0f,-10.0f,0.0f);
Here you have clockwise ordering of your vertices meaning you are drawing with the back to camera. either disable culling:
glDisable(GL_CULL_FACE);
make the front face clockwise:
glFrontFace(GL_CW);
or change the order of your vertices to a counter clockwise order.
Looks to me that your quad is wound backwards. You've enabled GL_CULL_FACE, which throws out any clockwise wound polygons, and your quad has a clockwise winding.
Either disable backface culling, or switch the order of your vertices to counter-clockwise.