如何使opengl文本可见/改变颜色?

时间:2018-05-31 06:31:43

标签: c opengl

我正在使用openGL进行建设性实体几何的迷你项目。我正在尝试创建两个窗口,第一个显示我的名字,大学名称和其他细节,第二个将显示实体几何窗口。我的第二个屏幕工作得很好,我可以在我的第一个屏幕上打印文字,但由于背景是黑色的,文字应该有不同的颜色,但它只是黑色,所以它不可见.Below是代码,可以任何人检查我的代码并告诉我哪里出错。

#include<GL/glut.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<GL/gl.h>

int isMainScreen=1;
enum {
  CSG_A, CSG_B, CSG_A_OR_B, CSG_A_AND_B, CSG_A_SUB_B, CSG_B_SUB_A
};

/* just draw single object */
void one(void (*a) (void))
{
  glEnable(GL_DEPTH_TEST);
  a();
  glDisable(GL_DEPTH_TEST);
}
/* "or" is easy; simply draw both objects with depth buffering on */
void or(void (*a) (void), void (*b) (void))
{
  glEnable(GL_DEPTH_TEST);
  a();
  b();
  glDisable(GL_DEPTH_TEST);
} 
/* Set stencil buffer to show the part of a (front or back face) that's inside b's volume. Requirements: GL_CULL_FACE enabled, depth func GL_LESS Side effects: depth test, stencil func, stencil op */
void
firstInsideSecond(void (*a) (void), void (*b) (void), GLenum face, GLenum test)
{
  glEnable(GL_DEPTH_TEST);
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glCullFace(face);     /* controls which face of a to use */
  a();                           /* draw a face of a into depth buffer */
  /* use stencil plane to find parts of a in b */
  glDepthMask(GL_FALSE);
  glEnable(GL_STENCIL_TEST);
  glStencilFunc(GL_ALWAYS, 0, 0);
  glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
  glCullFace(GL_BACK);
  b();                  /* increment the stencil where the front face of b is drawn */
  glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
  glCullFace(GL_FRONT);
  b();                  /* decrement the stencil buffer where the back face of b is drawn */
  glDepthMask(GL_TRUE);
  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  glStencilFunc(test, 0, 1);
  glDisable(GL_DEPTH_TEST);
  glCullFace(face);
  a();                  /* draw the part of a that's in b */
}

void
fixDepth(void (*a) (void))
{
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_STENCIL_TEST);
  glDepthFunc(GL_ALWAYS);
  a();                  /* draw the front face of a, fixing the depth buffer */
  glDepthFunc(GL_LESS);
}
/* "and" two objects together */
void
and(void (*a) (void), void (*b) (void))
{
  firstInsideSecond(a, b, GL_BACK, GL_NOTEQUAL);
  fixDepth(b);
  firstInsideSecond(b, a, GL_BACK, GL_NOTEQUAL);
  glDisable(GL_STENCIL_TEST);  /* reset things */
}
/* subtract b from a */
void
sub(void (*a) (void), void (*b) (void))
{
  firstInsideSecond(a, b, GL_FRONT, GL_NOTEQUAL);
  fixDepth(b);
  firstInsideSecond(b, a, GL_BACK, GL_EQUAL);
  glDisable(GL_STENCIL_TEST);  /* reset things */
}

enum {
  SPHERE = 1, CONE
};

/* Draw a cone */
GLfloat coneX = 0.f, coneY = 0.f, coneZ = 0.f;
void
cone(void)
{
  glPushMatrix();
  glTranslatef(coneX, coneY, coneZ);
  glTranslatef(0.f, 0.f, -30.f);
  glCallList(CONE);
  glPopMatrix();
}

/* Draw a sphere */
GLfloat sphereX = 0.f, sphereY = 0.f, sphereZ = 0.f;
void
sphere(void)
{
  glPushMatrix();
  glTranslatef(sphereX, sphereY, sphereZ);
  glCallList(SPHERE);
  glPopMatrix();
}
int csg_op = CSG_A;

/* add menu callback */
void 
menu(int csgop)
{
  csg_op = csgop;
  glutPostRedisplay();
}

GLfloat viewangle;
void redraw(void)
{
  /* clear stencil each time */
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
  glPushMatrix();
  glRotatef(viewangle, 0.f, 1.f, 0.f);
  switch (csg_op) {
  case CSG_A:    one(cone);
                break;
  case CSG_B:    one(sphere);
                        break;

  case CSG_A_OR_B:    or(cone, sphere);
                    break;
  case CSG_A_AND_B:    and(cone, sphere);
                       break;
  case CSG_A_SUB_B:    sub(cone, sphere);
      break;
  case CSG_B_SUB_A:    sub(sphere, cone);
       break;
  }
  glPopMatrix();
  glutSwapBuffers();
}
/* animate scene by rotating */
enum {
  ANIM_LEFT, ANIM_RIGHT
};
int animDirection = ANIM_LEFT;

void 
anim(void)
{
  if (animDirection == ANIM_LEFT)
    viewangle -= 3.f;
  else
    viewangle += 3.f;
  glutPostRedisplay();
}

/* ARGSUSED1 */
/* special keys, like array and F keys */
void 
special(int key, int x, int y)
{
  switch (key) {
  case GLUT_KEY_LEFT:    glutIdleFunc(anim);
                            animDirection = ANIM_LEFT;
            break;
  case GLUT_KEY_RIGHT:    glutIdleFunc(anim);
                      animDirection = ANIM_RIGHT;
                      break;
  case GLUT_KEY_UP:
  case GLUT_KEY_DOWN:
                    glutIdleFunc(0);
                    break;
  }
}
/* ARGSUSED1 */
void 
key(unsigned char key, int x, int y)
{
  switch (key) {
  case 'a': viewangle -= 10.f;
    glutPostRedisplay();
                break;
  case 's':
    viewangle += 10.f;
    glutPostRedisplay();
    break;
    case '\13':
        isMainScreen=1;
        break;
        mydisplay();
    case '\033':
    exit(0);
}
}

int picked_object;
int xpos = 0, ypos = 0;
int newxpos, newypos;
int startx, starty;

void
mouse(int button, int state, int x, int y)
{
  if (state == GLUT_UP) {
    picked_object = button;
    xpos += newxpos;
    ypos += newypos;
    newxpos = 0;
    newypos = 0;
  } else {              /* GLUT_DOWN */
    startx = x;
    starty = y;
  }
}
#define DEGTORAD (2 * 3.1415 / 360)
void 
motion(int x, int y)
{
  GLfloat r, objx, objy, objz;

  newxpos = x - startx;
  newypos = starty - y;

  r = (newxpos + xpos) * 50.f / 512.f;
  objx = r * cos(viewangle * DEGTORAD);
  objy = (newypos + ypos) * 50.f / 512.f;
  objz = r * sin(viewangle * DEGTORAD);

  switch (picked_object) {
  case CSG_A:
    coneX = objx;
    coneY = objy;
    coneZ = objz;
    break;
  case CSG_B:
    sphereX = objx;
    sphereY = objy;
    sphereZ = objz;
    break;
  }
  glutPostRedisplay();
}

void drawString1(float x, float y, float z, char * string) {
    char * c;
    glRasterPos3f(x, y, z);
    for (c = string; * c != '\0'; c++) {
        glutBitmapCharacter(GLUT_BITMAP_9_BY_15, * c);
    }
}


double vp_width = 512.0; // update by reshape
double vp_height = 512.0; // update by reshape


void frontscreen(void)
{
    glDisable(GL_LIGHTING);
    glMatrixMode( GL_PROJECTION );
    glPushMatrix();
    glLoadIdentity();
    glOrtho( 0, vp_width, vp_height, 0.0, -1.0, 1.0 );
    glMatrixMode( GL_MODELVIEW );
    glPushMatrix();
    glLoadIdentity();
    glColor3f(0.7,0.0,1.0);
    drawString1(200.0,50.0,0.0,"MVJ College of Engineering");
    glColor3f(0.7,0.0,1.0);
    drawString1(165.0,90.0,0.0,"DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING");
    glColor3f(1.0,0.5,0.6);
    drawString1(185.0,130.0,0.0,"A MINI PROJECT ON:COMPUTER GRAPHICS");
    glColor3f(1,0,0);
    drawString1(175.0,170.0,0.0,"PROJECT TITLE:CONSTRUCTIVE SOLID GEOMETRY");
    glColor3f(1,0.5,0);
    drawString1(20,380,0.0,"BY:");
    glColor3f(0.5,0,0.5);
    drawString1(10,410,0.0,"NAME: ANSHU");
    glColor3f(0.5,0,0.5);
    drawString1(10,425,0.0,"USN:1MJ15CS016");
    glColor3f(0.5,0,0.5);
    drawString1(10,440,0.0,"SEC:A");
    glColor3f(0.5,0,0.5);
    drawString1(10,455,0.0,"SEMESTER:VI");
    glColor3f(1,0.5,0);
    drawString1(420,380,0.0,"GUIDE:");
    glColor3f(0.5,0,0.5);
    drawString1(390,400,0.0,"NAME:Ms. Devisivashankari p");
    glColor3f(1,0.1,1);
    drawString1(200,480,0.0,"PRESS ENTER TO START");
    glMatrixMode( GL_PROJECTION );
    glPopMatrix();
    glMatrixMode( GL_MODELVIEW );
    glPopMatrix();

    glutSwapBuffers();   // <----- glutSwapBuffers insted of glFlush
    glutPostRedisplay();
}


void mydisplay() {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    if (isMainScreen) {
        frontscreen();  
    } else {
        redraw();
    }
}


int main(int argc, char **argv)
{
  static GLfloat lightpos[] =
  {25.f, 50.f, -50.f, 1.f};
  static GLfloat sphere_mat[] =
  {1.f, .5f, 0.f, 1.f};
  static GLfloat cone_mat[] =
  {0.f, .5f, 1.f, 1.f};
  GLUquadricObj *sphere, *cone, *base;

  glutInit(&argc, argv);
  glutInitWindowSize(1024,720);
  glutInitDisplayMode(GLUT_STENCIL | GLUT_DEPTH | GLUT_DOUBLE);
  (void) glutCreateWindow("csg");
  glutDisplayFunc(frontscreen);
  glutKeyboardFunc(key);
  glutSpecialFunc(special);
  glutMouseFunc(mouse);
  glutMotionFunc(motion);

  glutCreateMenu(menu);
  glutAddMenuEntry("A only", CSG_A);
  glutAddMenuEntry("B only", CSG_B);
  glutAddMenuEntry("A or B", CSG_A_OR_B);
  glutAddMenuEntry("A and B", CSG_A_AND_B);
  glutAddMenuEntry("A sub B", CSG_A_SUB_B);
  glutAddMenuEntry("B sub A", CSG_B_SUB_A);
  glutAttachMenu(GLUT_RIGHT_BUTTON);

  glEnable(GL_CULL_FACE);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);

  glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

  /* make display lists for sphere and cone; for efficiency */

  glNewList(SPHERE, GL_COMPILE);
  sphere = gluNewQuadric();
  glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,sphere_mat);
  gluSphere(sphere, 20.f, 64, 64);
  gluDeleteQuadric(sphere);
  glEndList();
  glNewList(CONE, GL_COMPILE);
  cone = gluNewQuadric();
  base = gluNewQuadric();
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, cone_mat);
  gluQuadricOrientation(base, GLU_INSIDE);
  gluDisk(base, 0., 15., 64, 1);
  gluCylinder(cone, 15., 0., 60., 64, 64);
  gluDeleteQuadric(cone);
  gluDeleteQuadric(base);
  glEndList();
  glMatrixMode(GL_PROJECTION);
  glOrtho(-50., 50., -50., 50., -50., 50.);
  glMatrixMode(GL_MODELVIEW);
  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}

frontscreen方法是第一个应该出现的屏幕。

1 个答案:

答案 0 :(得分:1)

  

我可以在我的第一个屏幕上打印文字,但由于背景是黑色的,文字应该有不同的颜色,但它只是黑色,所以它不可见

启用光照(GL_LIGHTING)后,颜色将从材质参数(glMaterial)中获取。

如果您仍想使用当前颜色,则必须启用GL_COLOR_MATERIAL 并设置颜色材质参数(glColorMaterial):

glEnable( GL_COLOR_MATERIAL );
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );

另见Basic OpenGL Lighting

我建议您在绘制文本时禁用光照:

void frontscreen(void)
{
    glDisable( GL_LIGHTING );

    .....
}

但是在绘制场景时启用光照:

void redraw(void)
{
    glEnable( GL_LIGHTING );

    .....
}