Как заставить работать OpenGL Specular Light? - PullRequest
2 голосов
/ 25 марта 2019

Как заставить зеркальное освещение работать в OpenGL?Я использую python, и я пытался узнать, как он работает одинаково, я уже смог заставить текстурирование работать, глубину, создавать основной игровой процесс, но теперь я пытался заставить зеркальное освещение работать как фонарик, такЯ постоянно меняю его положение на одно и то же от игрока и направление, куда смотрит игрок, но это не работает!

import pyglet, math
from pyglet.gl import *

tela = pyglet.window.Window(height=500, width=500, caption="Halloween")
glEnable(GL_DEPTH_TEST)
glEnable(GL_TEXTURE_2D)
glEnable(GL_LIGHTING)
glLightfv(GL_LIGHT0, GL_AMBIENT, (GLfloat*4)(0,0,0,1))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat*4)(0,0,0,1))
glEnable(GL_LIGHT0)
tela.set_mouse_visible(False)
pos = [0,0,0]
rotX = rotY = pre = 0
comando = {"a":0,"d":0,"w":0,"s":0}
Dparede = pyglet.image.load("inf/Parede_Branca.png").get_image_data().get_data('RGBA', 225*4)
parede = pyglet.resource.image("inf/Parede_Branca.png").get_texture()
Dchao = pyglet.image.load("inf/Madeira.png").get_image_data().get_data('RGBA', 225*4)
chao = pyglet.resource.image("inf/Madeira.png").get_texture()

@tela.event
def on_draw():
    global pos, comando, rotX, rotY, parede, chao, Dchao, Dparede
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    if comando["w"] == 1:
        pos[2] += math.cos(math.pi*rotX/180)
        pos[0] += math.sin(math.pi*rotX/180)
    if comando["s"] == 1:
        pos[2] -= math.cos(math.pi*rotX/180)
        pos[0] -= math.sin(math.pi*rotX/180)
    if comando["d"] == 1:
        pos[2] += math.sin(math.pi*rotX/180)
        pos[0] -= math.cos(math.pi*rotX/180)
    if comando["a"] == 1:
        pos[2] -= math.sin(math.pi*rotX/180)
        pos[0] += math.cos(math.pi*rotX/180)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45, 1, 0.1, 1000)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    if pos[0] < -188:
        pos[0] = -188
    if pos[2] < -188:
        pos[2] = -188
    if pos[0] > 188:
        pos[0] = 188
    if pos[2] > 188:
        pos[2] = 188
    glLightfv(GL_LIGHT0, GL_SPECULAR, (GLfloat*4)(1,1,1,1))
    glLightfv(GL_LIGHT0, GL_POSITION, (GLfloat*4)(pos[0],pos[1]-1,pos[2],1))
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, (GLfloat*3)(pos[0]+1000*(math.sin(math.pi*rotX/180)),pos[1]+1000*(math.cos(math.pi*rotY/180)), pos[2]+1000*(math.cos(math.pi*rotX/180))))
    glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, (GLfloat*1)(45))

    gluLookAt(pos[0], pos[1], pos[2], pos[0]+math.sin(math.pi*rotX/180), pos[1]+math.cos(math.pi*rotY/180), pos[2]+math.cos(math.pi*rotX/180), 0, 10, 0)

    glBindTexture(GL_TEXTURE_2D, chao.id)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 225, 225, 0, GL_RGBA, GL_UNSIGNED_BYTE, Dchao)

    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat*4)(1,1,1,1))
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, (GLfloat*1)(100))
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (GLfloat*4)(0,0,0,1))

    # chão
    glBegin(GL_POLYGON)
    glTexCoord2f(0,0)
    glVertex3f(-200,-20,200)
    glTexCoord2f(0,10)
    glVertex3f(-200,-20,-200)
    glTexCoord2f(10,10)
    glVertex3f(200,-20,-200)
    glTexCoord2f(10,0)
    glVertex3f(200,-20,200)
    glEnd()

    glBindTexture(GL_TEXTURE_2D, parede.id)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 225, 225, 0, GL_RGBA, GL_UNSIGNED_BYTE, Dparede)

    # teto
    glBegin(GL_POLYGON)
    glTexCoord2f(0,0)
    glVertex3f(-200,20,200)
    glTexCoord2f(0,50)
    glVertex3f(-200,20,-200)
    glTexCoord2f(50,50)
    glVertex3f(200,20,-200)
    glTexCoord2f(50,0)
    glVertex3f(200,20,200)
    glEnd()

    # parede
    glBegin(GL_POLYGON)
    glTexCoord2f(0,0)
    glVertex3f(-200,20,200)
    glTexCoord2f(0,50)
    glVertex3f(-200,20,-200)
    glTexCoord2f(10,50)
    glVertex3f(-200,-20,-200)
    glTexCoord2f(10,0)
    glVertex3f(-200,-20,200)
    glEnd()

    # parede
    glBegin(GL_POLYGON)
    glTexCoord2f(0,0)
    glVertex3f(-200,-20,-200)
    glTexCoord2f(0,50)
    glVertex3f(200,-20,-200)
    glTexCoord2f(10,50)
    glVertex3f(200,20,-200)
    glTexCoord2f(10,0)
    glVertex3f(-200,20,-200)
    glEnd()

    # parede
    glBegin(GL_POLYGON)
    glTexCoord2f(0,0)
    glVertex3f(200,-20,-200)
    glTexCoord2f(0,50)
    glVertex3f(200,-20,200)
    glTexCoord2f(10,50)
    glVertex3f(200,20,200)
    glTexCoord2f(10,0)
    glVertex3f(200,20,-200)
    glEnd()

    # parede
    glBegin(GL_POLYGON)
    glTexCoord2f(0,0)
    glVertex3f(-200,-20,200)
    glTexCoord2f(0,50)
    glVertex3f(200,-20,200)
    glTexCoord2f(10,50)
    glVertex3f(200,20,200)
    glTexCoord2f(10,0)
    glVertex3f(-200,20,200)
    glEnd()

@tela.event
def on_key_press(k,m):
    global comando
    if k == pyglet.window.key.A:
        comando["a"] = 1
    if k == pyglet.window.key.D:
        comando["d"] = 1
    if k == pyglet.window.key.W:
        comando["w"] = 1
    if k == pyglet.window.key.S:
        comando["s"] = 1
    if k == pyglet.window.key.Q:
        tela.close()

@tela.event
def on_key_release(k,m):
    global comando
    if k == pyglet.window.key.A:
        comando["a"] = 0
    if k == pyglet.window.key.D:
        comando["d"] = 0
    if k == pyglet.window.key.W:
        comando["w"] = 0
    if k == pyglet.window.key.S:
        comando["s"] = 0

@tela.event
def on_mouse_motion(x, y, dx, dy):
    global rotX, rotY, pre
    if pre == 0:
        rotX-=dx/2
        if rotY >= 0:
            rotY = -1
        if rotY <= -180:
            rotY = -179
        rotY+=dy
        if x > 400 or x < 100 or y > 400 or y < 100:
            tela.set_mouse_position(250,250)
            pre = 1
    else:
        pre = 0

def SRO(dt):
    on_draw()

pyglet.clock.schedule_interval(SRO, 1/120)

pyglet.app.run()

Я уже пытался изменить glMaterial или изменить другие вещив освещении, но ничего не работает правильно, я просто хочу, чтобы освещение работало как фонарик, пожалуйста, дайте ответы с кодом

1 Ответ

4 голосов
/ 25 марта 2019

То, что вы хотите сделать, невозможно, из-за gouraud shading модели освещения с фиксированной функцией. См. Также OpenGL Освещение на плоскости текстуры не работает , что является вопросом о подобной проблеме. Вам придется тесселировать поверхности (стены и полы) на меньшие плитки, потому что свет рассчитывается только для координат вершин и интерполируется на поверхности. Зеркальные блики в середине поверхности не появятся.

Я знаю, что вас это не удовлетворит. Но обратите внимание, что рисование с помощью glBegin / glEnd последовательностей, набора матриц с фиксированными функциями и фиксированной функции для каждой модели освещения вершин устарело с десятилетий. См. конвейер с фиксированными функциями и Legacy OpenGL . Прочитайте о Vertex Specification и Shader , чтобы узнать о современном способе рендеринга.

Если вы хотите что-то «увидеть», вам нужно пропустить прожектор, потому что он не будет работать с вашей геометрией:

glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, (GLfloat*1)(45))

но активируйте рассеянный свет:

glEnable(GL_LIGHTING)
glLightfv(GL_LIGHT0, GL_AMBIENT, (GLfloat*4)(1,1,1,1))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat*4)(1,1,1,1))
glEnable(GL_LIGHT0)

Для расчета света необходим вектор нормали поверхности.

Активировать модель освещения GL_LIGHT_MODEL_TWO_SIDE сторона:

glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE)

Установить нормальные векторы с помощью glNormal3f:

# chão
glBegin(GL_POLYGON)
glNormal3f(0, -1, 0)
glTexCoord2f(0,0)
glVertex3f(-200,-20,200)
glTexCoord2f(0,10)
glVertex3f(-200,-20,-200)
glTexCoord2f(10,10)
glVertex3f(200,-20,-200)
glTexCoord2f(10,0)
glVertex3f(200,-20,200)
glEnd()

glBindTexture(GL_TEXTURE_2D, parede.id)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, Dparede)

# teto
glBegin(GL_POLYGON)
glNormal3f(0, -1, 0)
glTexCoord2f(0,0)
glVertex3f(-200,20,200)
glTexCoord2f(0,50)
glVertex3f(-200,20,-200)
glTexCoord2f(50,50)
glVertex3f(200,20,-200)
glTexCoord2f(50,0)
glVertex3f(200,20,200)
glEnd()

# parede
glBegin(GL_POLYGON)
glNormal3f(-1, 0, 0)
glTexCoord2f(0,0)
glVertex3f(-200,20,200)
glTexCoord2f(0,50)
glVertex3f(-200,20,-200)
glTexCoord2f(10,50)
glVertex3f(-200,-20,-200)
glTexCoord2f(10,0)
glVertex3f(-200,-20,200)
glEnd()

# parede
glBegin(GL_POLYGON)
glNormal3f(0, 0, 1)
glTexCoord2f(0,0)
glVertex3f(-200,-20,-200)
glTexCoord2f(0,50)
glVertex3f(200,-20,-200)
glTexCoord2f(10,50)
glVertex3f(200,20,-200)
glTexCoord2f(10,0)
glVertex3f(-200,20,-200)
glEnd()

# parede
glBegin(GL_POLYGON)
glNormal3f(-1, 0, 0)
glTexCoord2f(0,0)
glVertex3f(200,-20,-200)
glTexCoord2f(0,50)
glVertex3f(200,-20,200)
glTexCoord2f(10,50)
glVertex3f(200,20,200)
glTexCoord2f(10,0)
glVertex3f(200,20,-200)
glEnd()

# parede
glBegin(GL_POLYGON)
glNormal3f(0, 0, 1)
glTexCoord2f(0,0)
glVertex3f(-200,-20,200)
glTexCoord2f(0,50)
glVertex3f(200,-20,200)
glTexCoord2f(10,50)
glVertex3f(200,20,200)
glTexCoord2f(10,0)
glVertex3f(-200,20,200)
glEnd()

Когда положение источника света установлено на glLightfv(GL_LIGHT0, GL_POSITION, pos), то положение умножается на матрицу вида текущей модели.
Это означает, что если положение установлено до того, как будет установлена ​​матрица вида (gluLookAt), то положение освещения относительно камеры (положение в пространстве просмотра).
Если он установлен после того, как была установлена ​​матрица вида, то положение источника света должно быть в мировых координатах, поскольку оно преобразуется матрицей вида.

Если вы хотите, чтобы источник света находился в положении камеры, вам нужно установить свет в положение (0, 0, 0), за до , матрица просмотра устанавливается с помощью gluLookAt.

glLightfv(GL_LIGHT0, GL_POSITION, (GLfloat*4)(0,0,0,1))
gluLookAt(pos[0], pos[1], pos[2], pos[0]+math.sin(math.pi*rotX/180), pos[1]+math.cos(math.pi*rotY/180), pos[2]+math.cos(math.pi*rotX/180), 0, 10, 0) 

Если вы хотите, чтобы прожектор (более или менее) работал, то единственная возможность - использовать очень маленький параметр GL_SHININESS (например, 1):

glLightfv(GL_LIGHT0, GL_POSITION, (GLfloat*4)(0,0,0,1))
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, (GLfloat*3)(0, 0, -1))
glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, (GLfloat*1)(45))

gluLookAt(pos[0], pos[1], pos[2], pos[0]+math.sin(math.pi*rotX/180), pos[1]+math.cos(math.pi*rotY/180), pos[2]+math.cos(math.pi*rotX/180), 0, 10, 0)

glLightfv(GL_LIGHT0, GL_AMBIENT, (GLfloat*4)(0,0,0,1))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat*4)(0,0,0,1))
glLightfv(GL_LIGHT0, GL_SPECULAR, (GLfloat*4)(1,1,1,1))

# [...]

glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, (GLfloat*1)(1))
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat*4)(1,1,1,1))


Другой возможностью было бы реализовать простую шейдерную программу освещения :

Создание исходного кода программы шейдера:

vert_code = b"""
varying vec3 N;
varying vec3 v;
varying vec2 uv;

void main(void)  
{     
    uv = gl_MultiTexCoord0.xy; 
    v = vec3(gl_ModelViewMatrix * gl_Vertex);       
    N = normalize(gl_NormalMatrix * gl_Normal);
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  
}
"""

frag_code = b"""
varying vec3 N;
varying vec3 v; 
varying vec2 uv;  
uniform sampler2D u_texture;  
void main (void)  
{  
    vec3 L = normalize(gl_LightSource[0].position.xyz - v);   
    vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0)  
    vec3 R = normalize(-reflect(L,N));  

    //calculate Ambient Term:  
    vec4 Iamb = gl_FrontLightProduct[0].ambient;    

    float spotCos = dot(gl_LightSource[0].spotDirection, -E);
    float sotCutOff = step(gl_LightSource[0].spotCosCutoff, spotCos);

    //calculate Diffuse Term:  
    vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0);
    Idiff = clamp(Idiff, 0.0, 1.0) * sotCutOff;     

    // calculate Specular Term:
    vec4 Ispec = gl_FrontLightProduct[0].specular 
                    * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess);
    Ispec = clamp(Ispec, 0.0, 1.0) * sotCutOff; 

    vec4 texColor = texture2D(u_texture, uv);  
    gl_FragColor = vec4(texColor.rgb * (Iamb + Idiff + Ispec), texColor.a);     
}
"""

Скомпилируйте и скомпонуйте программу:

from ctypes import *
sh_code_list = [(GL_VERTEX_SHADER, vert_code), (GL_FRAGMENT_SHADER, frag_code)]

sh_objs = []
for sh_code in sh_code_list:
    sh_obj = glCreateShader(sh_code[0])
    src_buffer = create_string_buffer(sh_code[1])
    buf_pointer = cast(pointer(pointer(src_buffer)), POINTER(POINTER(c_char)))
    glShaderSource(sh_obj, 1, buf_pointer, None)
    glCompileShader(sh_obj)
    temp = c_int(0)
    glGetShaderiv(sh_obj, GL_COMPILE_STATUS, byref(temp))
    if not temp:
        glGetShaderiv(sh_obj, GL_INFO_LOG_LENGTH, byref(temp))
        buffer = create_string_buffer(temp.value)
        glGetShaderInfoLog(sh_obj, temp, None, buffer)
        print( 'compile error:' )
        print(buffer.value)
    sh_objs.append(sh_obj)

program = glCreateProgram()
for shObj in sh_objs: 
    glAttachShader(program, shObj)

glLinkProgram(program)
temp = c_int(0)
glGetProgramiv(program, GL_LINK_STATUS, byref(temp))
if not temp:
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, byref(temp))
    buffer = create_string_buffer(temp.value)
    glGetProgramInfoLog(program, temp, None, buffer)
    print( 'link error:' )
    print(buffer.value)

Загрузка текстур перед основным циклом программы:

glBindTexture(GL_TEXTURE_2D, chao.id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, Dchao)

glBindTexture(GL_TEXTURE_2D, parede.id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, Dparede)

Используйте программу при рисовании сцены:

@tela.event
def on_draw():
    global pos, comando, rotX, rotY, parede, chao, Dchao, Dparede
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    if comando["w"] == 1:
        pos[2] += math.cos(math.pi*rotX/180)
        pos[0] += math.sin(math.pi*rotX/180)
    if comando["s"] == 1:
        pos[2] -= math.cos(math.pi*rotX/180)
        pos[0] -= math.sin(math.pi*rotX/180)
    if comando["d"] == 1:
        pos[2] += math.sin(math.pi*rotX/180)
        pos[0] -= math.cos(math.pi*rotX/180)
    if comando["a"] == 1:
        pos[2] -= math.sin(math.pi*rotX/180)
        pos[0] += math.cos(math.pi*rotX/180)

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45, 1, 0.1, 1000)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    if pos[0] < -188:
        pos[0] = -188
    if pos[2] < -188:
        pos[2] = -188
    if pos[0] > 188:
        pos[0] = 188
    if pos[2] > 188:
        pos[2] = 188

    glLightfv(GL_LIGHT0, GL_POSITION, (GLfloat*4)(0,0,0,1))
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, (GLfloat*3)(0, 0, -1))
    glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, (GLfloat*1)(45))

    gluLookAt(pos[0], pos[1], pos[2], pos[0]+math.sin(math.pi*rotX/180), pos[1]+math.cos(math.pi*rotY/180), pos[2]+math.cos(math.pi*rotX/180), 0, 10, 0)

    glLightfv(GL_LIGHT0, GL_AMBIENT, (GLfloat*4)(0.2,0.2,0.2,1))
    glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat*4)(0.8,0.8,0.8,1))
    glLightfv(GL_LIGHT0, GL_SPECULAR, (GLfloat*4)(1,1,1,1))
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, (GLfloat*1)(100))
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat*4)(1,1,1,1))

    glBindTexture(GL_TEXTURE_2D, chao.id)

    glUseProgram(program)

    # chão
    glBegin(GL_POLYGON)
    glNormal3f(0, 1, 0)
    glTexCoord2f(0,0)
    glVertex3f(-200,-20,200)
    glTexCoord2f(0,10)
    glVertex3f(-200,-20,-200)
    glTexCoord2f(10,10)
    glVertex3f(200,-20,-200)
    glTexCoord2f(10,0)
    glVertex3f(200,-20,200)
    glEnd()

    glBindTexture(GL_TEXTURE_2D, parede.id)

    # teto
    glBegin(GL_POLYGON)
    glNormal3f(0, -1, 0)
    glTexCoord2f(0,0)
    glVertex3f(-200,20,200)
    glTexCoord2f(0,10)
    glVertex3f(-200,20,-200)
    glTexCoord2f(10,10)
    glVertex3f(200,20,-200)
    glTexCoord2f(10,0)
    glVertex3f(200,20,200)
    glEnd()

    # parede
    glBegin(GL_POLYGON)
    glNormal3f(-1, 0, 0)
    glTexCoord2f(0,0)
    glVertex3f(-200,20,200)
    glTexCoord2f(10,0)
    glVertex3f(-200,20,-200)
    glTexCoord2f(10,1)
    glVertex3f(-200,-20,-200)
    glTexCoord2f(0,1)
    glVertex3f(-200,-20,200)
    glEnd()

    # parede
    glBegin(GL_POLYGON)
    glNormal3f(0, 0, 1)
    glTexCoord2f(0,0)
    glVertex3f(-200,-20,-200)
    glTexCoord2f(10,0)
    glVertex3f(200,-20,-200)
    glTexCoord2f(10,1)
    glVertex3f(200,20,-200)
    glTexCoord2f(0,1)
    glVertex3f(-200,20,-200)
    glEnd()

    # parede
    glBegin(GL_POLYGON)
    glNormal3f(-1, 0, 0)
    glTexCoord2f(0,0)
    glVertex3f(200,-20,-200)
    glTexCoord2f(10,0)
    glVertex3f(200,-20,200)
    glTexCoord2f(10,1)
    glVertex3f(200,20,200)
    glTexCoord2f(0,1)
    glVertex3f(200,20,-200)
    glEnd()

    # parede
    glBegin(GL_POLYGON)
    glNormal3f(0, 0, 1)
    glTexCoord2f(0,0)
    glVertex3f(-200,-20,200)
    glTexCoord2f(10,0)
    glVertex3f(200,-20,200)
    glTexCoord2f(10,1)
    glVertex3f(200,20,200)
    glTexCoord2f(0,1)
    glVertex3f(-200,20,200)
    glEnd()

...