I'm trying to make a textured table object in openGL using GLUT in C but it fails when it comes to 'visability' of certain elements e.g. When the table is turned upside-down you should see its legs but otherwise it should be hidden (at least partially hidden). I'm posting the code below, you can use L and J keys on keyboard to rotate by X and I/K keys to turn by Y factor. Thanks in advance!
#include <GL/glut.h>
#include <math.h>
#define TEXWIDTH 32
#define TEXHEIGHT 32
GLubyte def_tekstury[TEXHEIGHT][TEXWIDTH][3];
GLuint id_tekstury;
int done = 0;
const unsigned char left = 'j';
const unsigned char right = 'l';
const unsigned char down = 'k';
const unsigned char up = 'i';
const GLfloat GL_PI=3.1415f;
int proba[4] = {1,2,31,32};
void generate_def_tekstury()
{
int s, t;
/* generujemy zolto-czerwona szachownice o polach 4x4 */
for (s = 0; s < TEXWIDTH; ++s) {
for (t = 0; t < TEXHEIGHT; ++t) {
if ((s % 8 < 4 && t % 8 < 4) || (s % 8 >= 4 && t % 8 >= 4)) {
def_tekstury[t][s][0] = 255;
def_tekstury[t][s][1] = 255;
def_tekstury[t][s][2] = 0;
} else {
def_tekstury[t][s][0] = 255;
def_tekstury[t][s][1] = 0;
def_tekstury[t][s][2] = 0;
}
}
}
/* kwadrat w lewym downnym rogu jest bialy, w lewym gornym zielony */
for (s = 0; s < 4; ++s) {
for (t = 0; t < 4; ++t) {
def_tekstury[t][s][0] = 255;
def_tekstury[t][s][1] = 255;
def_tekstury[t][s][2] = 255;
}
for (t = TEXHEIGHT - 4; t < TEXHEIGHT; ++t) {
def_tekstury[t][s][0] = 0;
def_tekstury[t][s][1] = 255;
def_tekstury[t][s][2] = 0;
}
}
}
void init()
{
glClearColor(0.560784, 0.560784, 0.737255, 0.0);
glEnable(GL_TEXTURE_2D);
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
/* tworzymy nowa teksture*/
glGenTextures(1, &id_tekstury);
/* wybierz jako biezaca */
glBindTexture(GL_TEXTURE_2D, id_tekstury);
/* ustaw jej parametry */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
/* zaladuj dane tekseli */
generate_def_tekstury();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, TEXWIDTH,
TEXHEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, def_tekstury);
}
void keyboard(unsigned char key, int x, int y)
{
if (key == down)
{
glRotatef(-10,0.0f,1.0f,0.0f);
glutPostRedisplay();
}
if (key == left)
{
glRotatef(-10,-1.0f,0.0f,0.0f);
glutPostRedisplay();
}
if (key == right)
{
glRotatef(10,1.0f,0.0f,0.0f);
glutPostRedisplay();
}
if (key == up)
{
glRotatef(10,0.0f,1.0f,0.0f);
glutPostRedisplay();
}
}
void display(void)
{
int c,c1;
GLfloat x,y,z,kat;
if(done == 0)
{
glOrtho(-7.0, 7.0 , -7.0, 7.0, -7.0, 7.0);
done = 1;
}
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 0.0);
glRotatef(20,1.0f,0.0f,0.0f);
glRotatef(20,0.0f,1.0f,0.0f);
//gluLookAt(- , eyeY , eyeZ , centerX , centerY , centerZ , upX , upY , upZ )
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
glFrontFace(GL_CW);
//zmianarysowaniatylniej
//glPolygonMode(GL_BACK, GL_LINE);
glBegin(GL_QUADS);
//spod stołu
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-1.0f,5.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(开发者_如何学Python-5.0f,-1.0f,-5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-1.0f,-5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-1.0f,5.0f);
//wierzch stołu
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,5.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-0.6f,5.0f);
//lewa
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-5.0f,-1.0f,-5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-5.0f,-1.0f,5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,5.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,-5.0f);
//prawa
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-0.6f,5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-1.0f,5.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(5.0f,-1.0f,-5.0f);
//przod
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-5.0f,-1.0f,5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-1.0f,5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-0.6f,5.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,5.0f);
//sciana tylnia
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-1.0f,-5.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-5.0f,-1.0f,-5.0f);
glEnd();
x=0.0;
y=0.0;
z=0.0;
kat=0.0;
for(c=-1; c<2; c=c+2)
{
for(c1=-1; c1<2; c1=c1+2)
{
glBegin(GL_QUAD_STRIP);
for(kat = 0.0f; kat < (2.0f*GL_PI); kat += (GL_PI/32.0f))
{
x = 0.4f*sin(kat)-3.0f*c;
z = 0.4f*cos(kat)-3.0f*c1;
glTexCoord2f(0.0f, 1.0f);
glVertex3f(x, -0.6, z);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(x, 4.0, z);
}
glEnd();
}
}
glFlush();
}
int main(int argc, char *argv[])
{
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(800, 600);
glutInit(&argc, argv);
glutCreateWindow("Okno OpenGL");
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
What you need is enable Z buffering aka depth testing. First you need a depth buffer (also you surely want double buffering, otherwise you can see how the image is rendered, causeing flicker):
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
then you must enable depth testing with
glEnable(GL_DEPTH_TEST);
to make depth testing work properly, you must clear the depth buffer when starting to render a new frame:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
And since we enabled double buffering issue a buffer swap at the end of display()
// glFlush();
glutSwapBuffers(); // Buffer swapping implies a glFlush()
精彩评论