OpenGL – normales de vértice en OBJ

16 minutos de lectura

OpenGL normales de vertice en OBJ
zyneragetro

Quiero saber cómo puedo usar las normales de vértice para el efecto de relámpago. Actualmente, lo que tengo es que puedo enviar coordenadas de vértice y textura al sombreador y usarlas, pero con las normales, no sé cómo usarlas en el programa de sombreado. A continuación se muestra 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 shaders 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);
    }

Sombreador de fragmentos.

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

Actualmente obteniendo un cubo negro sin sombreado. Probablemente hice algo mal aquí en el sombreado que no tengo 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 🙂

ACTUALIZAR : A continuación se muestran los sombreadores que funcionan 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));
    }

  • Debe volver a escribir la pregunta, diciéndonos qué quiere hacer con las normales. Sospecho que hay algún tipo de iluminación, pero su pregunta no lo menciona. Ya sabe cómo obtener normales en su sombreador (de la misma manera que obtiene posición, color y texcoord).

    –Robinson

    6 de agosto de 2015 a las 8:31

  • @Robinson: he editado la pregunta. Lo siento por no preguntarlo de la manera correcta. Solo quiero saber cómo puedo usar las normales en el sombreador para crear un efecto de relámpago, dijiste que sé cómo obtener las normales en mi sombreador de la misma manera que el texcoord pero no sé cómo puedo hacerlo con el normales Solo soy un principiante en opengl.

    – zyneragetro

    6 de agosto de 2015 a las 8:42

  • Bueno, esa es una pregunta diferente. Hay distintos modelos de iluminación: Blinn, Phong, etc. Yo empezaría por Gourad por ser la más sencilla. Básicamente, esos son los términos de búsqueda que necesita usar en Google. El único consejo que le daría es que se asegure de transformar las normales mediante la transposición inversa de la matriz de vista, de lo contrario, no se orientarán correctamente.

    –Robinson

    6 de agosto de 2015 a las 8:58


  • @Robinson: Gracias por la información. Leeré sobre los modelos de rayos. A partir de ahora, investigaré y espero poder tener una idea sobre cómo usar las normales de la manera más básica. Ja ja

    – zyneragetro

    6 de agosto de 2015 a las 9:12

  • @zyneragetro mira: normales y mapeo normal para algunos conceptos básicos

    – Espectro

    08/08/2015 a las 18:38

1647585848 490 OpenGL normales de vertice en OBJ
espectro

mapas normales/de relieve

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

sombreado normal (sombreador de fragmentos)

Normal es un vector perpendicular al fragmento/cara/primitivo, tiene 2 usos:

  1. iluminación superficial opaca

tengamos:

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

entonces la salida es fácil:

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

se llama sombreado normal

dot devuelve el cos(angle between light and normal) si desea tener geometrías de los lados de la cabina, use fabs(dot(...)). Los vectores de intensidad y color de la luz sumados no deben exceder 1,0 por canal; de lo contrario, la sujeción podría causar artefactos de color. Utilice por ejemplo:

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

como lt_direct_dir puedes usar (fragment_xyz-Sun.xyz) y normalice al vector unitario o use la dirección de vista de la cámara. Debe tener un vector unitario para el producto de puntos; de lo contrario, no funcionará correctamente

  1. reflexión

si tienes algún mapa de entorno (cubo_mapa), entonces puede agregar reflejos. tienes el fragmento (x,y,z) coordenadas y normal para que pueda calcular la dirección de la dirección de visualización reflejada y agregar el elemento de textura al que apunta al resultado fragment_color.

Hay más cosas como reflejos especulares y diferentes ecuaciones de luz, pero creo que primero deberías comenzar con el sombreado normal. Cuando tienes los conceptos básicos, entonces no hay problema para entender las cosas más avanzadas, solo recuerda siempre lo que hay detrás…

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

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

sombreado normal

Esa cruz es la posición de mi punto de luz para verificar visualmente la corrección y esa flecha (dibujada a mano) muestra la dirección promedio de la luz.

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

sombreado_normal.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 <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, //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[]=
    {
//  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,
    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);
    }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

Fuente del formulario 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 olvide cambiar los diseños a los suyos, agregue texturas y otras cosas solo si esto ya está funcionando y siempre verifique GLSL.txt (registro de compilación/enlace) para ver si todo está como debería estar.

también necesitas GLEW para esto así que vea

Aquí está este mismo ejemplo con textura atlas:

  • Texturizando un cubo con diferentes imágenes usando OpenGL

  • Gracias por una explicación detallada sobre esto. Anteriormente estaba siguiendo este tutorial gamedev.net/page/resources/_/technical/opengl/… que he editado arriba y publico mis sombreadores actuales, por ahora lo actualizaré según lo que tengas. Con la esperanza de obtener mejores resultados 🙂

    – zyneragetro

    10 de agosto de 2015 a las 8:20

  • @zyneragetro 1. tu normal matrix y eyeCoord parezca sospechoso, deberían estar en el mismo sistema de coordenadas, no importa cuál. 2. a qué valores estás pasando Ld,Kd? 3. no acepte la respuesta si aún no tiene los resultados deseados (significa que su problema está resuelto).

    – Espectro

    10 de agosto de 2015 a las 10:08

  • gl_Position = m_proj * m_view * m_model * vert; transforma el vértice en espacio de pantalla para que gl_Position = m_view * m_model * vert; se transforma en el espacio de la cámara y gl_Position = m_model * vert; se transforma en espacio mundial [GCS]. lo normal es un vector, por lo que debe descartar el desplazamiento, por lo que la matriz normal debe ser la misma que m_model pero el origen de la misma debe establecerse en (0.0,0.0,0.0) ver matrices de transformación. Luego tnorm = m_normal * normal o tnorm = (m_model*normal) - m_model.origin

    – Espectro

    10 de agosto de 2015 a las 10:13


  • No puedo entender cómo puedo obtener lt_direct_dir? No sé dónde conseguir el fragment.xyz/Sun.xyz.

    – zyneragetro

    11 de agosto de 2015 a las 3:06

  • Perdón por no entender todo esto después de la respuesta detallada que diste. Soy muy nuevo en OpenGL y todo esto del 3D. A partir de ahora, solo puedo obtener ideas basadas en sus respuestas, pero no puedo traducir nada en código.

    – zyneragetro

    11 de agosto de 2015 a las 3:09

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad