tutorial obj modelos index con como cargar archivos archivo abrir c++ opengl opengl-es shader wavefront

c++ - obj - opengl vertex index



OpenGL-normales de vértices en OBJ (1)

mapas normales / de relieve

Brinde detalles finos sin aumentar la complejidad de la geometría, lo que significa más detalles con un costo de rendimiento muy bajo. Los mapas normales / de relieve son opcionales o bastos.

sombreado normal (sombreador de fragmentos)

Normal es el vector perpendicular al fragmento / cara / primitivo, hay dos usos para él:

  1. iluminación superficial opaca

    tengamos:

    • color - por fragmento / cara / color primitivo (modulado con textura)
    • normal - por fragmento / cara / primitiva 3D vector normal (apuntando fuera de malla)
    • lt_ambient,lt_direct - el color y la fuerza de las luces
    • lt_direct_dir - dirección direccional de la luz

    entonces la salida es fácil:

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

    esto se llama sombreado normal

    dot devuelve el cos(angle between light and normal) si quiere tener geometrías en los lados de la cabina y luego usa fabs(dot(...)) . Los vectores de color y fuerza de la luz sumados no deberían exceder 1.0 por canal; de lo contrario, la sujeción podría causar artefactos de color. Use por ejemplo:

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

    como lt_direct_dir puede usar (fragment_xyz-Sun.xyz) y normalizar en vector unitario o usar la dirección de visualización de la cámara. Debe tener un vector unitario para el producto escalado, de lo contrario no funcionará correctamente

  2. reflexión

    si tiene un mapa de entorno ( cube_map ), puede agregar reflejos. Obtienes las coordenadas del fragmento (x,y,z) y normal para que puedas calcular la dirección de la dirección de visualización reflejada y agregar el texel al que apunta al resultado fragment_color.

    Hay más cosas como reflejos especulares y diferentes ecuaciones de luz, pero creo que primero debes comenzar con sombreado normal. Cuando tienes lo básico, entonces no hay problema para entender las cosas más avanzadas, solo recuerda lo que hay detrás ...

[edit1] así como eres novato, obviamente necesitas un ejemplo completo para comenzar:

Así que aquí completa el ejemplo GL + VAO / VBO + GLSL + shaders en C ++. Como uso el entorno de Borland, está en la aplicación de formulario VCL, así que simplemente ignore las cosas de VCL y extraiga solo lo que necesita. Así es como esto luce:

Esa cruz es mi posición de punto de luz para verificar visualmente la corrección y esa flecha (dibujada a mano) muestra la dirección promedio de la 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

//--------------------------------------------------------------------------- #define GLEW_STATIC #include "glew.c" #include <gl/gl.h> #include <gl/glu.h> //--------------------------------------------------------------------------- //--- 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[]= { // x y z //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, //0 +1.0,-1.0,-1.0, //1 +1.0,-1.0,+1.0, //5 -1.0,-1.0,+1.0, //4 +1.0,-1.0,-1.0, //1 +1.0,+1.0,-1.0, //2 +1.0,+1.0,+1.0, //6 +1.0,-1.0,+1.0, //5 +1.0,+1.0,-1.0, //2 -1.0,+1.0,-1.0, //3 -1.0,+1.0,+1.0, //7 +1.0,+1.0,+1.0, //6 -1.0,+1.0,-1.0, //3 -1.0,-1.0,-1.0, //0 -1.0,-1.0,+1.0, //4 -1.0,+1.0,+1.0, //7 #endif }; const GLfloat vao_col[]= { // r g b //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, 0,1,5,4, 1,2,6,5, 2,3,7,6, 3,0,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++; } glGetShaderInfoLog(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); glVertexAttribPointer(i,4,GL_UNSIGNED_INT,GL_FALSE,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(GLfloat)); // QUADS ... no indices #endif #ifdef vao_indices glDrawElements(GL_QUADS,sizeof(vao_idx)/sizeof(GLuint),GL_UNSIGNED_INT,0); // indices (choose just one line not both !!!) #endif glBindVertexArray(0); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------

Fuente de forma principal de la aplicación VCL:

//--------------------------------------------------------------------------- #include <vcl.h> #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(x-d,y,z); glVertex3f(x+d,y,z); glVertex3f(x,y-d,z); glVertex3f(x,y+d,z); glVertex3f(x,y,z-d); 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(); } //---------------------------------------------------------------------------

No se olvide de cambiar los diseños a los suyos, agregue texturas y cosas solo si esto ya está funcionando y siempre verifique el GLSL.txt (compilación / registro de enlaces) para ver si todo es como debe ser.

También necesitas GLEW para esto, así que mira

Quiero saber cómo puedo usar las normales de los vértices para el efecto del rayo. Actualmente, lo que tengo es que puedo enviar coords de vértice y de textura al sombreador y usarlos, pero con las normales, no sé cómo usarlas en el programa de sombreado. Debajo está lo que tengo hasta ahora.

// 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); }

EDITAR Aquí están mis sombreadores por ahora.

sombreador de vértices

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); }

Fragmento sombreador.

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

Actualmente obtiene un cubo negro sin sombreado. Probablemente hice algo mal aquí en el sombreado, que no tengo ni idea de cuál :(

ACTUALIZAR:

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; }

fragmento

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; }

No sé qué poner para lt_direct_dir por eso tiene valores como ese :)

ACTUALIZACIÓN: A continuación están los sombreadores de trabajo para mí

// 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)); }