OpenGL – normais do vertex em OBJ

Eu quero saber como posso usar os vértices normais para efeito relâmpago? Atualmente, o que tenho é que posso enviar as coordenadas de vértice e textura ao sombreador e usá-las, mas com as normais, não sei como usá-las no programa de sombreador. Abaixo está o que eu tenho até agora.

// vertex shader layout(location = 0) in vec4 vert; layout(location = 1) in vec4 color; layout(location = 2) in vec2 texcoord; uniform mat4 m_model; uniform mat4 m_view; uniform mat4 m_proj; void main() { gl_Position = m_proj * m_view * m_model * vert; } // fragment shader in vec2 fragtexcoord; out vec4 color; uniform sampler2D textureunit; void main(void) { color = texture(textureunit, fragtexcoord); } 

EDIT Aqui estão os meus shaders por agora.

vertex shader

  layout(location = 0) in vec4 vert; layout(location = 1) in vec4 color; layout(location = 2) in vec2 texcoord; layout(location = 3) in vec4 normal; out vec4 LightIntensity; uniform vec4 LightPosition; uniform vec4 Kd; uniform vec4 Ld; uniform mat4 m_model; uniform mat4 m_view; uniform mat4 m_proj; void main() { gl_Position = m_proj * m_view * m_model * vert; mat4 normalmatrix = transpose(inverse(m_view)); vec4 tnorm = normalize(normalmatrix * normal); vec4 eyeCoords = m_model * vec4(vert); vec4 s = normalize(vec4(LightPosition - eyeCoords)); LightIntensity = Ld * Kd * max(dot(s, tnorm), 0.0); } 

Fragment shader.

  in vec4 LightIntensity; out vec4 color; void main(void) { color = vec4(LightIntensity); } 

Atualmente recebendo um cubo preto sem sombreamento. Provavelmente eu fiz algo errado aqui no shader que eu não tenho idéia de qual 🙁

ATUALIZAÇÃO:

vértice

  layout(location = 0) in vec4 vert; layout(location = 1) in vec4 color; layout(location = 2) in vec2 texcoord; layout(location = 3) in vec4 normal; out vec2 fragtexcoord; out vec4 fragnormal; uniform mat4 m_model; uniform mat4 m_view; uniform mat4 m_proj; void main() { gl_Position = m_proj * m_view * m_model * vert; fragtexcoord = texcoord; fragnormal = normal; } 

fragment

  in vec2 fragtexcoord; in vec4 fragnormal; out vec4 fragment_color; uniform sampler2D textureunit; void main(void) { vec4 lt_ambient = vec4(0.2, 0.2, 0.2, 1.0); vec4 lt_direct = vec4(0.8, 0.8, 0.8, 1.0); vec4 lt_direct_dir = vec4(1.5, 1.0, 1.0, 1.0); vec4 color = texture(textureunit, fragtexcoord); fragment_color = (lt_ambient + (lt_direct * dot(lt_direct_dir, -fragnormal))) * color; } 

Eu não sei o que colocar para lt_direct_dir é por isso que tem valores como esse 🙂

UPDATE: Abaixo estão os shaders de trabalho para mim

  // vertex shader layout(location = 0) in vec4 vert; layout(location = 1) in vec4 color; layout(location = 2) in vec2 texcoord; layout(location = 3) in vec4 normal; out vec4 fragposition; out vec4 fragcolor; out vec4 fragnormal; out vec2 fragtexcoord; uniform mat4 m_model; uniform mat4 m_view; uniform mat4 m_proj; uniform vec4 lightpos; void main() { gl_Position = m_proj * m_view * m_model * vert; mat4 m_normal = transpose(inverse(m_model)); fragposition = m_model * vert; fragnormal = m_normal * normal; fragtexcoord = texcoord; } // fragment shader in vec4 fragposition; in vec4 fragnormal; in vec2 fragtexcoord; out vec4 fragment_color; uniform sampler2D textureunit; void main() { vec4 lt_pnt_pos = vec4(2.5, 2.5, 2.5, 1.0); vec4 lt_pnt_col = vec4(0.8, 0.8, 0.8, 1.0); vec4 lt_amb_col = vec4(0.2, 0.2, 0.2, 1.0); vec4 lt_dir = normalize(lt_pnt_pos - fragposition); float li = dot(fragnormal, lt_dir); if(li < 0.0) { li = 0.0; } vec4 color = texture(textureunit, fragtexcoord); fragment_color = color * (lt_amb_col + (lt_pnt_col * li)); } 

mapas normais / bump

Forneça detalhes precisos sem aumentar a complexidade da geometry, o que significa mais detalhes com um custo de desempenho muito baixo. Mapas normais / bump são opcionais de grosso.

sombreamento normal (shader de fragment)

Normal é vetor perpendicular ao fragment / face / primitivo há 2 uso para ele:

  1. iluminação superficial maçante

    vamos ter:

    • color – por fragment / face / cor primitiva (modulada com textura)
    • normal – por fragment / face / vetor normal 3D primitivo (apontando para fora da malha)
    • lt_ambient,lt_direct – a cor e a intensidade das luzes
    • lt_direct_dir – direção da luz direcional

    então a saída é fácil:

    • fragment_color=(lt_ambient+(lt_direct*dot(lt_direct_dir,-normal))*color;

    isso é chamado de sombreamento normal

    dot retorna o cos(angle between light and normal) se você quiser ter geometrys nos lados do estande e usar fabs(dot(...)) . Os vetores de cor e intensidade claros sumdos não devem exceder 1,0 por canal, caso contrário a fixação pode causar artefatos de colors. Use por exemplo:

    • lt_ambient=(0.2,0.2,0.2)
    • lt_direct =(0.8,0.8,0.8)

    como lt_direct_dir você pode usar (fragment_xyz-Sun.xyz) e normalizar para vetor unitário ou usar a direção da visão da câmera. Você precisa ter um vetor unitário para o produto escalar, caso contrário, ele não funcionará corretamente

  2. reflection

    se você tiver algum mapa de ambiente ( cube_map ), poderá adicionar reflexos. Você tem as coordenadas de fragment (x,y,z) e normal para poder calcular a direção da direção de visualização refletida e adicionar o texel para o qual ela está apontando para o resultado fragment_color.

    Há mais coisas como destaques especulares e diferentes equações de luz, mas eu acho que você deve começar com o sombreamento normal primeiro. Quando você tem o básico, então não é problema para entender as coisas mais avançadas sempre lembrar o que está por trás …

[edit1] bem como você é novato, então obviamente você precisa de um exemplo completo para começar:

Então, aqui, conclua o exemplo de shaders GL + VAO / VBO + GLSL + em C ++. Como eu uso o ambiente da Borland, ele está no aplicativo de formulário da VCL, então ignore as coisas da VCL e extraia apenas o que você precisa. É assim que parece:

sombreamento normal

Essa cruz é a minha posição de luz pontual para verificar visualmente a exatidão e aquela seta (desenhada à mão) mostra a direção média da luz.

normal_shading.glsl_vert

 // Vertex #version 400 core layout(location = 0) in vec3 pos; layout(location = 2) in vec3 nor; layout(location = 3) in vec3 col; uniform mat4 m_model; // model matrix uniform mat4 m_normal; // model matrix with origin=(0,0,0) uniform mat4 m_view; // inverse of camera matrix uniform mat4 m_proj; // projection matrix out vec3 pixel_pos; // fragment position [GCS] out vec3 pixel_col; // fragment surface color out vec3 pixel_nor; // fragment surface normal [GCS] void main() { pixel_col=col; pixel_pos=(m_model*vec4(pos,1)).xyz; pixel_nor=(m_normal*vec4(nor,1)).xyz; gl_Position=m_proj*m_view*m_model*vec4(pos,1); } 

normal_shading.glsl_frag

 // Fragment #version 400 core uniform vec3 lt_pnt_pos;// point light source position [GCS] uniform vec3 lt_pnt_col;// point light source color&strength uniform vec3 lt_amb_col;// ambient light source color&strength in vec3 pixel_pos; // fragment position [GCS] in vec3 pixel_col; // fragment surface color in vec3 pixel_nor; // fragment surface normal [GCS] out vec4 col; void main() { float li; vec3 c,lt_dir; lt_dir=normalize(lt_pnt_pos-pixel_pos); // vector from fragment to point light source in [GCS] li=dot(pixel_nor,lt_dir); if (li<0.0) li=0.0; c=pixel_col*(lt_amb_col+(lt_pnt_col*li)); col=vec4(c,1.0); } 

gl_simple.h

 //--------------------------------------------------------------------------- //--- GL simple ver: 1.000 -------------------------------------------------- //--------------------------------------------------------------------------- #define GLEW_STATIC #include "glew.c" #include  #include  //--------------------------------------------------------------------------- //--- OpenGL GL example ----------------------------------------------------- //--------------------------------------------------------------------------- int xs,ys; // screen size HDC hdc=NULL; // device context HGLRC hrc=NULL; // rendering context int gl_inicialized=0; int gl_init(HWND Handle); void gl_exit(); void gl_draw(); void gl_resize(int _xs,int _ys); //--------------------------------------------------------------------------- //--- OpenGL GLSL example --------------------------------------------------- //--------------------------------------------------------------------------- GLint prog_id=0, // whole program vert_id=0, // vertex shader frag_id=0; // fragment shader char glsl_log[4096];// compile/link GLSL log int glsl_logs=0; void glsl_init(char *vert,char *frag); // create/compile/link GLSL program void glsl_exit(); //--------------------------------------------------------------------------- //--- OpenGL VAO example ---------------------------------------------------- //--------------------------------------------------------------------------- #pragma pack(1) //#define vao_indices GLuint vbo[4]={-1,-1,-1,-1}; GLuint vao[4]={-1,-1,-1,-1}; const GLfloat vao_pos[]= { // xyz //ix -1.0,+1.0,-1.0, //0 +1.0,+1.0,-1.0, //1 +1.0,-1.0,-1.0, //2 -1.0,-1.0,-1.0, //3 -1.0,-1.0,+1.0, //4 +1.0,-1.0,+1.0, //5 +1.0,+1.0,+1.0, //6 -1.0,+1.0,+1.0, //7 #ifndef vao_indices -1.0,-1.0,-1.0, //3 +1.0,-1.0,-1.0, //2 +1.0,-1.0,+1.0, //5 -1.0,-1.0,+1.0, //4 +1.0,-1.0,-1.0, //2 +1.0,+1.0,-1.0, //1 +1.0,+1.0,+1.0, //6 +1.0,-1.0,+1.0, //5 +1.0,+1.0,-1.0, //1 -1.0,+1.0,-1.0, //0 -1.0,+1.0,+1.0, //7 +1.0,+1.0,+1.0, //6 -1.0,+1.0,-1.0, //0 -1.0,-1.0,-1.0, //3 -1.0,-1.0,+1.0, //4 -1.0,+1.0,+1.0, //7 #endif }; const GLfloat vao_col[]= { // rgb //ix 0.0,0.0,0.0, //0 1.0,0.0,0.0, //1 1.0,1.0,0.0, //2 0.0,1.0,0.0, //3 0.0,0.0,1.0, //4 1.0,0.0,1.0, //5 1.0,1.0,1.0, //6 0.0,1.0,1.0, //7 #ifndef vao_indices 0.0,0.0,0.0, //0 1.0,0.0,0.0, //1 1.0,0.0,1.0, //5 0.0,0.0,1.0, //4 1.0,0.0,0.0, //1 1.0,1.0,0.0, //2 1.0,1.0,1.0, //6 1.0,0.0,1.0, //5 1.0,1.0,0.0, //2 0.0,1.0,0.0, //3 0.0,1.0,1.0, //7 1.0,1.0,1.0, //6 0.0,1.0,0.0, //3 0.0,0.0,0.0, //0 0.0,0.0,1.0, //4 0.0,1.0,1.0, //7 #endif }; #ifndef vao_indices const GLfloat vao_nor[]= { // nx ny nz //ix 0.0, 0.0,-1.0, //0 0.0, 0.0,-1.0, //1 0.0, 0.0,-1.0, //2 0.0, 0.0,-1.0, //3 0.0, 0.0,+1.0, //4 0.0, 0.0,+1.0, //5 0.0, 0.0,+1.0, //6 0.0, 0.0,+1.0, //7 0.0,-1.0, 0.0, //0 0.0,-1.0, 0.0, //1 0.0,-1.0, 0.0, //5 0.0,-1.0, 0.0, //4 +1.0, 0.0, 0.0, //1 +1.0, 0.0, 0.0, //2 +1.0, 0.0, 0.0, //6 +1.0, 0.0, 0.0, //5 0.0,+1.0, 0.0, //2 0.0,+1.0, 0.0, //3 0.0,+1.0, 0.0, //7 0.0,+1.0, 0.0, //6 -1.0, 0.0, 0.0, //3 -1.0, 0.0, 0.0, //0 -1.0, 0.0, 0.0, //4 -1.0, 0.0, 0.0, //7 }; #endif #ifdef vao_indices const GLuint vao_ix[]= { 0,1,2,3, 4,5,6,7, 3,2,5,4, 2,1,6,5, 1,0,7,6, 0,3,4,7, }; #endif #pragma pack() void vao_init(); void vao_exit(); void vao_draw(); //--------------------------------------------------------------------------- //--- bodies: --------------------------------------------------------------- //--------------------------------------------------------------------------- int gl_init(HWND Handle) { if (gl_inicialized) return 1; hdc = GetDC(Handle); // get device context 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.iLayerType = PFD_MAIN_PLANE; SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd); hrc = wglCreateContext(hdc); // create current rendering context if(hrc == NULL) { ShowMessage("Could not initialize OpenGL Rendering context !!!"); gl_inicialized=0; return 0; } if(wglMakeCurrent(hdc, hrc) == false) { ShowMessage("Could not make current OpenGL Rendering context !!!"); wglDeleteContext(hrc); // destroy rendering context gl_inicialized=0; return 0; } gl_resize(1,1); glEnable(GL_DEPTH_TEST); // Zbuf glDisable(GL_CULL_FACE); // vynechavaj odvratene steny glDisable(GL_TEXTURE_2D); // pouzivaj textury, farbu pouzivaj z textury glDisable(GL_BLEND); // priehladnost glShadeModel(GL_SMOOTH); // gourard shading glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // background color gl_inicialized=1; glewInit(); return 1; } //--------------------------------------------------------------------------- void gl_exit() { if (!gl_inicialized) return; wglMakeCurrent(NULL, NULL); // release current rendering context wglDeleteContext(hrc); // destroy rendering context gl_inicialized=0; } //--------------------------------------------------------------------------- void gl_resize(int _xs,int _ys) { xs=_xs; ys=_ys; if (xs< =0) xs = 1; // Prevent a divide by zero if (ys<=0) ys = 1; if (!gl_inicialized) return; glViewport(0,0,xs,ys); // Set Viewport to window dimensions glMatrixMode(GL_PROJECTION); // operacie s projekcnou maticou glLoadIdentity(); // jednotkova matica projekcie gluPerspective(30,float(xs)/float(ys),0.1,100.0); // matica=perspektiva,120 stupnov premieta z viewsize do 0.1 glMatrixMode(GL_TEXTURE); // operacie s texturovou maticou glLoadIdentity(); // jednotkova matica textury glMatrixMode(GL_MODELVIEW); // operacie s modelovou maticou glLoadIdentity(); // jednotkova matica modelu (objektu) } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void glsl_init(char *vert,char *frag) { const int _size=1024; GLint status,siz=0,i; const char * VS = vert; const char * FS = frag; glsl_logs=0; if (prog_id<=0) prog_id=glCreateProgram(); if (vert_id<=0) vert_id=glCreateShader(GL_VERTEX_SHADER); else glDetachShader(prog_id,vert_id); if (vert) { glShaderSource(vert_id, 1, &VS,NULL); glCompileShader(vert_id); glAttachShader(prog_id,vert_id); glGetShaderiv(vert_id,GL_COMPILE_STATUS,&status); const char t[]="[Vertex]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; } glGetShaderInfoLog(vert_id,_size,&siz,glsl_log+glsl_logs); glsl_logs+=siz; } if (frag_id<=0) frag_id=glCreateShader(GL_FRAGMENT_SHADER); else glDetachShader(prog_id,frag_id); if (frag) { glShaderSource(frag_id, 1, &FS,NULL); glCompileShader(frag_id); glAttachShader(prog_id,frag_id); glGetShaderiv(frag_id,GL_COMPILE_STATUS,&status); const char t[]="[Fragment]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; } glGetShaderInfoLog(frag_id,_size,&siz,glsl_log+glsl_logs); glsl_logs+=siz; } glLinkProgram(prog_id); glGetProgramiv(prog_id,GL_LINK_STATUS,&status); const char t[]="[Program]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; } glGetProgramInfoLog(prog_id,_size,&siz,glsl_log+glsl_logs); glsl_logs+=siz; glReleaseShaderCompiler(); glsl_log[glsl_logs]=0; } //------------------------------------------------------------------------------ void glsl_exit() { glUseProgram(0); if (vert_id>0) { glDetachShader(prog_id,vert_id); glDeleteShader(vert_id); } if (frag_id>0) { glDetachShader(prog_id,frag_id); glDeleteShader(frag_id); } if (prog_id>0) { glDeleteShader(prog_id); } glsl_log[0]=0; } //--------------------------------------------------------------------------- //------------------------------------------------------------------------------ void vao_init() { GLuint i; glGenVertexArrays(4,vao); glGenBuffers(4,vbo); glBindVertexArray(vao[0]); i=0; // vertex glBindBuffer(GL_ARRAY_BUFFER,vbo[i]); glBufferData(GL_ARRAY_BUFFER,sizeof(vao_pos),vao_pos,GL_STATIC_DRAW); glEnableVertexAttribArray(i); glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0); i=1; // indices #ifdef vao_indices glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo[i]); glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(vao_ix),vao_ix,GL_STATIC_DRAW); glEnableVertexAttribArray(i); glVertexAttribIPointer(i,4,GL_UNSIGNED_INT,0,0); #endif i=2; // normal #ifndef vao_indices glBindBuffer(GL_ARRAY_BUFFER,vbo[i]); glBufferData(GL_ARRAY_BUFFER,sizeof(vao_nor),vao_nor,GL_STATIC_DRAW); glEnableVertexAttribArray(i); glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0); #endif i=3; // color glBindBuffer(GL_ARRAY_BUFFER,vbo[i]); glBufferData(GL_ARRAY_BUFFER,sizeof(vao_col),vao_col,GL_STATIC_DRAW); glEnableVertexAttribArray(i); glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER,0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); glDisableVertexAttribArray(3); } //--------------------------------------------------------------------------- void vao_exit() { glDeleteVertexArrays(4,vao); glDeleteBuffers(4,vbo); } //--------------------------------------------------------------------------- void vao_draw() { glBindVertexArray(vao[0]); #ifndef vao_indices glDrawArrays(GL_QUADS,0,sizeof(vao_pos)/sizeof(vao_pos[0])); // QUADS ... no indices #endif #ifdef vao_indices glDrawElements(GL_QUADS,sizeof(vao_ix)/sizeof(vao_ix[0]),GL_UNSIGNED_INT,0); // indices (choose just one line not both !!!) #endif glBindVertexArray(0); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ 

Fonte de formulário principal do aplicativo VCL:

 //--------------------------------------------------------------------------- #include  #pragma hdrstop #include "Unit1.h" #include "gl_simple.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- GLfloat lt_pnt_pos[3]={+2.5,+2.5,+2.5}; GLfloat lt_pnt_col[3]={0.8,0.8,0.8}; GLfloat lt_amb_col[3]={0.2,0.2,0.2}; //--------------------------------------------------------------------------- void gl_draw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // load values into shader GLint i,id; GLfloat m[16]; glUseProgram(prog_id); id=glGetUniformLocation(prog_id,"lt_pnt_pos"); glUniform3fv(id,1,lt_pnt_pos); id=glGetUniformLocation(prog_id,"lt_pnt_col"); glUniform3fv(id,1,lt_pnt_col); id=glGetUniformLocation(prog_id,"lt_amb_col"); glUniform3fv(id,1,lt_amb_col); glGetFloatv(GL_MODELVIEW_MATRIX,m); id=glGetUniformLocation(prog_id,"m_model" ); glUniformMatrix4fv(id,1,GL_FALSE,m); m[12]=0.0; m[13]=0.0; m[14]=0.0; id=glGetUniformLocation(prog_id,"m_normal" ); glUniformMatrix4fv(id,1,GL_FALSE,m); for (i=0;i<16;i++) m[i]=0.0; m[0]=1.0; m[5]=1.0; m[10]=1.0; m[15]=1.0; id=glGetUniformLocation(prog_id,"m_view" ); glUniformMatrix4fv(id,1,GL_FALSE,m); glGetFloatv(GL_PROJECTION_MATRIX,m); id=glGetUniformLocation(prog_id,"m_proj" ); glUniformMatrix4fv(id,1,GL_FALSE,m); // draw VAO cube vao_draw(); // turn of shader glUseProgram(0); // rotate the cube to see animation glMatrixMode(GL_MODELVIEW); glRotatef(1.0,0.0,1.0,0.0); glRotatef(1.0,1.0,0.0,0.0); // render point light source in [GCS] glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); GLfloat x,y,z,d=0.25; x=lt_pnt_pos[0]; y=lt_pnt_pos[1]; z=lt_pnt_pos[2]; glBegin(GL_LINES); glColor3fv(lt_pnt_col); glVertex3f(xd,y,z); glVertex3f(x+d,y,z); glVertex3f(x,yd,z); glVertex3f(x,y+d,z); glVertex3f(x,y,zd); glVertex3f(x,y,z+d); glEnd(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glFlush(); SwapBuffers(hdc); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner) { gl_init(Handle); int hnd,siz; char vertex[4096],fragment[4096]; hnd=FileOpen("normal_shading.glsl_vert",fmOpenRead); siz=FileSeek(hnd,0,2); FileSeek(hnd,0,0); FileRead(hnd,vertex ,siz); vertex [siz]=0; FileClose(hnd); hnd=FileOpen("normal_shading.glsl_frag",fmOpenRead); siz=FileSeek(hnd,0,2); FileSeek(hnd,0,0); FileRead(hnd,fragment,siz); fragment[siz]=0; FileClose(hnd); glsl_init(vertex,fragment); hnd=FileCreate("GLSL.txt"); FileWrite(hnd,glsl_log,glsl_logs); FileClose(hnd); vao_init(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { gl_exit(); glsl_exit(); vao_exit(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormResize(TObject *Sender) { gl_resize(ClientWidth,ClientHeight); glMatrixMode(GL_PROJECTION); glTranslatef(0,0,-15.0); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { gl_draw(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { gl_draw(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled) { GLfloat dz=2.0; if (WheelDelta<0) dz=-dz; glMatrixMode(GL_PROJECTION); glTranslatef(0,0,dz); gl_draw(); } //--------------------------------------------------------------------------- 

Não se esqueça de alterar os layouts para o seu, adicionar texturas e outras coisas somente se isso já estiver funcionando e sempre verificar o GLSL.txt (compilar / link log) para ver se tudo está como deveria estar.

Você também precisa do GLEW para isso, então veja

  • Fonte do GLEW
  • Construção glew no windows com mingw32