GLSL Variables Uniform
Las variables de tipo uniform permiten la comunicación entre la CPU y la GPU, estas variables mantienen su valor durante la ejecución del shader, las variables son declaradas usando la palabra reservada uniform, el shader no puede cambiar el valor de estas variables, sin embargo si es posible asignarle un valor inicial.
En el tutorial anterior vimos como podíamos establecer un color diferente para cada vértice del triángulo que desplegamos en pantalla, esta vez veremos cómo podemos establecer un color sólido para la figura desde el código C/C++ de OpenGL, aprenderemos a usar las variables uniform.
solid_color es una variable tipo uniform, su valor inicial es vec4(1.0, 1.0, 1.0, 1.0), en lugar de pintar el triángulo con el color de cada vértice lo haremos con este color, ahora veamos cómo podemos cambiar este color desde código C/C++.
Para obtener la ubicación de la variable llamada solid_color usaremos la función glGetUniformLocation(), indicamos el shader program y el nombre de la variable que deseamos, esta función devuelve la ubicación, si no encuentra la variable retorna -1.
Una vez tenemos la ubicación usamos la función glUniform4fv() para establecer el nuevo valor de esta variable, indicamos la ubicación, la cantidad de datos, y finalmente indicamos el nuevo color.
Para cambiar el valor de una variable tipo uniform contamos con la función glUniform{1,2,3,4}{f,i,ui}( ) que tiene diversas variantes, el número indica la cantidad de componentes { 1, 2, 3, 4 } y la letra el tipo de datos { f, i, ui } para flotante, entero y entero sin signo.
Obtener la ubicación de cada una de estas variables, si este fragmento de código fuese un shader válido:
Las variables booleanas las establecemos como valores enteros con valor de 0 para false y valor mayor que cero para true.
Usando la función glUniform{1,2,3,4}{f,i,ui}v( ), termina con la letra v a deferencia de la anterior, esta función nos permite indicar un puntero que contiene los datos a establecer, como primer parámetro indicamos la ubicación de la variable uniform, luego el parámetro que indica el tamaño del arreglo, al final pasamos el puntero al arreglo.
Establecemos matrices de un modo parecido a los arreglos, el nombre de la función lleva la palabra Matrix y el número indica el tamaño en columnas y filas de la matriz, ejemplo: glUniformMatrix2fv(GLint location, GLuint count, GLboolean transpose, const GLfloat *m) para una matriz 2x2, glUniformMatrix2x4fv() para una de 2x4.
Los parámetros tienen el mismo propósito que indicamos para los arreglos, salvo transpose que si lo establecemos a true convierte la matriz en su traspuesta.
En el tutorial anterior vimos como podíamos establecer un color diferente para cada vértice del triángulo que desplegamos en pantalla, esta vez veremos cómo podemos establecer un color sólido para la figura desde el código C/C++ de OpenGL, aprenderemos a usar las variables uniform.
const GLchar* fragment_shader_source = { "out vec4 frag_color; \n" " \n" "uniform vec4 solid_color = vec4(1.0); \n" " \n" "void main(void) \n" "{ \n" " frag_color = solid_color; \n" "} \n" };
solid_color es una variable tipo uniform, su valor inicial es vec4(1.0, 1.0, 1.0, 1.0), en lugar de pintar el triángulo con el color de cada vértice lo haremos con este color, ahora veamos cómo podemos cambiar este color desde código C/C++.
GLint solid_color_loc = glGetUniformLocation(program, "solid_color"); if (solid_color_loc != -1) { const GLfloat color[] = { 1.0, 1.0, 0.0, 1.0 }; glUniform4fv(solid_color_loc, 1, color); }
Para obtener la ubicación de la variable llamada solid_color usaremos la función glGetUniformLocation(), indicamos el shader program y el nombre de la variable que deseamos, esta función devuelve la ubicación, si no encuentra la variable retorna -1.
Una vez tenemos la ubicación usamos la función glUniform4fv() para establecer el nuevo valor de esta variable, indicamos la ubicación, la cantidad de datos, y finalmente indicamos el nuevo color.
Establecer Variables Uniform
Para cambiar el valor de una variable tipo uniform contamos con la función glUniform{1,2,3,4}{f,i,ui}( ) que tiene diversas variantes, el número indica la cantidad de componentes { 1, 2, 3, 4 } y la letra el tipo de datos { f, i, ui } para flotante, entero y entero sin signo.
uniform float fTime; uniform int iIndex; uniform vec4 vColorValue; uniform bool bSomeFlag;
Obtener la ubicación de cada una de estas variables, si este fragmento de código fuese un shader válido:
GLint locTime, locIndex, locColor, locFlag; locTime = glGetUniformLocation(myShader, "fTime"); locIndex = glGetUniformLocation(myShader, "iIndex"); locColor = glGetUniformLocation(myShader, "vColorValue"); locFlag = glGetUniformLocation(myShader, "bSomeFlag"); ... ... glUseProgram(myShader); glUniform1f(locTime, 45.2f); glUniform1i(locIndex, 42); glUniform4f(locColor, 1.0f, 0.0f, 0.0f, 1.0f); glUniform1i(locFlag, GL_FALSE);
Las variables booleanas las establecemos como valores enteros con valor de 0 para false y valor mayor que cero para true.
Establecer Arreglos Uniform
Usando la función glUniform{1,2,3,4}{f,i,ui}v( ), termina con la letra v a deferencia de la anterior, esta función nos permite indicar un puntero que contiene los datos a establecer, como primer parámetro indicamos la ubicación de la variable uniform, luego el parámetro que indica el tamaño del arreglo, al final pasamos el puntero al arreglo.
// GLSL Shader Code uniform vec4 vColor; uniform vec4 vColors[2]; // C/C++ OpenGL Code GLfloat vColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; glUniform4fv(color_loc, 1, vColor); GLfloat vColors[4][2] = { { 1.0f, 1.0f, 1.0f, 1.0f } , { 1.0f, 0.0f, 0.0f, 1.0f } }; glUniform4fv(colors_loc, 2, vColors);
Establecer Matrices Uniform
Establecemos matrices de un modo parecido a los arreglos, el nombre de la función lleva la palabra Matrix y el número indica el tamaño en columnas y filas de la matriz, ejemplo: glUniformMatrix2fv(GLint location, GLuint count, GLboolean transpose, const GLfloat *m) para una matriz 2x2, glUniformMatrix2x4fv() para una de 2x4.
Los parámetros tienen el mismo propósito que indicamos para los arreglos, salvo transpose que si lo establecemos a true convierte la matriz en su traspuesta.
glUniformMatrix2fv(GLint location, GLuint count, GLboolean transpose, const GLfloat *m); glUniformMatrix3fv(GLint location, GLuint count, GLboolean transpose, const GLfloat *m); glUniformMatrix4fv(GLint location, GLuint count, GLboolean transpose, const GLfloat *m);
Comentarios
Publicar un comentario