OpenGL VRML W3D            
  Home Tutorials Books Applications Tools Docs Models Textures  

 

              Bugs

GLSL Tutorial   

  GLSL Tutorial

Index
Introduction

The Graphics Pipeline
Pipeline Overview
Vertex Processor
Fragment Processor

OpenGL Setup for GLSL
Overview
Creating a Shader
Creating a Program
Source Code
Trouble Shooting: the InfoLog
Cleaning Up

Comm. OpenGL=> GLSL
Comm. Introduction
Uniform Variables
Attribute Variables

Shader Basics
Data Types and Variables
Statments and Functions
Varying Variables

Shader Examples
Shader Examples List

GLSL Hello World

Color Shader

Flatten Shader

Toon Shader
Toon Shader - Version I
Toon Shader - Version II
Toon Shader - Version III

Lighting
OpenGL Directional Light I
OpenGL Directional Light II
Directional Light per Pixel
Point Light Per Pixel
Spot Light Per Pixel

Simple Texture
Combine Texture + Fragment
Multitexturing

Notes
The gl_NormalMatrix
Normalization Issues


Google

OpenGLTutorials @ Lighthouse3d.com

Led Shader
View Frustum Culling
GLSL Tutorial
Maths Tutorial
Billboarding Tutorial
Picking Tutorial
Terrain Tutorial
Display Lists Tutorial
GLUT Tutorial



   
[Previous: Uniform Variables] [Next: Data Types and Variables]

GLSL Tutorial


OpenGL Setup for GLSL - Attribute Variables


As mentioned in subsection Uniform, uniform variables can only be set by primitive, i.e., they can't be set inside a glBegin-glEnd.

If it is required to set variables per vertex then attribute variables must be used. In fact attribute variables can be updated at any time. Attribute variables can only be read (not written) in a vertex shader. This is because they contain vertex data, hence not applicable directly in a fragment shader (see the section on varying variables). As for uniform variables, first it is necessary to get the location in memory of the variable. Note that the program must be linked previously and some drivers may require that the program is in use.

In OpenGL 2.0 use the following function:


GLint glGetAttribLocation(GLuint program,char *name);

Parameters:

program - the handle to the program.
name - the name of the variable

And with the ARB extensions use:


GLint glGetAttribLocationARB(GLhandleARB program,char *name);

Parameters:

program - the handle to the program.
name - the name of the variable

The variable's location in memory is obtained as the return value of the above function. The next step is to specify a value for it, potentially per vertex. As in the uniform variables, there is a function for each data type.

OpenGL 2.0 syntax:


void glVertexAttrib1f(GLint location, GLfloat v0);
void glVertexAttrib2f(GLint location, GLfloat v0, GLfloat v1);
void glVertexAttrib3f(GLint location, GLfloat v0, GLfloat v1,GLfloat v2);
void glVertexAttrib4f(GLint location, GLfloat v0, GLfloat v1,,GLfloat v2, GLfloat v3);

or

GLint glVertexAttrib{1,2,3,4}fv(GLint location, GLfloat *v);

Parameters:

location - the previously queried location.
v0,v1,v2,v3 - float values.
v - an array of floats.

ARB extensions syntax:


void glVertexAttrib1fARB(GLint location, GLfloat v0);
void glVertexAttrib2fARB(GLint location, GLfloat v0, GLfloat v1);
void glVertexAttrib3fARB(GLint location, GLfloat v0, GLfloat v1,GLfloat v2);
void glVertexAttrib4fARB(GLint location, GLfloat v0, GLfloat v1,,GLfloat v2, GLfloat v3);

or

GLint glVertexAttrib{1,2,3,4}fvARB(GLint location, GLfloat *v);

Parameters:

location - the previously queried location.
v0,v1,v2,v3 - float values.
v - an array of floats.

A similar set of functions is provided for integers and some other data types. Note that the vector version is not available for arrays as is the case of uniform variables. The vector version is just an option to submit the values of a single attribute variable. This is similar to what happens in OpenGL with glColor3f and glColor3fv.

A small example is now provided. It is assumed that the vertex shader declare a float attribute named height. The setup phase, to be performed after program link is:


	loc = glGetAttribLocation(p,"height");

In the rendering function the code could be something like:


	glBegin(GL_TRIANGLE_STRIP);

		glVertexAttrib1f(loc,2.0);
		glVertex2f(-1,1);

		glVertexAttrib1f(loc,2.0);
		glVertex2f(1,1);

		glVertexAttrib1f(loc,-2.0);
		glVertex2f(-1,-1);

		glVertexAttrib1f(loc,-2.0);
		glVertex2f(1,-1);

	glEnd();

The source code for the ARB extensions is very similar, just add "ARB" to the functions.

The source code for a small working example is available: ARB extension syntax or OpenGL 2.0 syntax.

Vertex Arrays can also be used together with attribute variables. The first thing to be done is to enable the arrays. To do this for an attribute array use the following function (OpenGL 2.0 syntax):


void glEnableVertexAttribArray(GLint loc);

Parameters:

loc - the location of the variable.

And using the ARB extensions:


void glEnableVertexAttribArrayARB(GLint loc);

Parameters:

loc - the location of the variable.

Next the pointer to the array with the data is provided using the following functions.

OpenGL 2.0 syntax:


void glVertexAttribPointer(GLint loc, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);

Parameters:

loc - the location of the variable.
size - the number of components per element, for instance: 1 for float; 2 for vec2; 3 for vec3, and so on.
type - The data type associated: GL_FLOAT is an example.
normalized - if set to 1 then the array values will be normalized, converted to a range from -1 to 1 for signed data, or 0 to 1 for unsigned data.
stride - the spacing between elements. Exactly the same as in OpenGL.
pointer - pointer to the array containing the data.

ARB extensions syntax:


void glVertexAttribPointerARB(GLint loc, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);

Parameters:

loc - the location of the variable.
size - the number of components per element, for instance: 1 for float; 2 for vec2; 3 for vec3, and so on.
type - The data type associated: GL_FLOAT is an example.
normalized - if set to 1 then the array values will be normalized, converted to a range from -1 to 1 for signed data, or 0 to 1 for unsigned data.
stride - the spacing between elements. Exactly the same as in OpenGL.
pointer - pointer to the array containing the data.

And now to some source code. First the initialization step. Two arrays are considered, the vertex and attribute arrays. It is assumed that the variable heights is declared with appropriate scope, i.e. accessible both in here as well as when rendering.



	float vertices[8] = {-1,1, 1,1, -1,-1, 1,-1};
	float heights[4] = {2,2,-2,-2};
	
	...
	
	loc = glGetAttribLocation(p,"height");

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableVertexAttribArray(loc);

	glVertexPointer(2,GL_FLOAT,0,vertices);
	glVertexAttribPointer(loc,1,GL_FLOAT,0,0,heights);

Rendering is exactly the same as before (OpenGL without shaders), just call glDrawArrays for example. A small demo source code is available: ARB extensions syntax or OpenGL 2.0 syntax.

[Previous: Uniform Variables] [Next: Data Types and Variables]

       


Site designed and maintained by António Ramires Fernandes
Your comments, suggestions and references to further material are welcome!

Lighthouse 3D privacy statement