Help end child hunger

OpenGL 3.3 + GLSL 1.5 Sample

 

This is a simple, yet complete, sample of code to draw two triangles using OpenGL 3.3 and GLSL 1.5. As far as I know the sample does not use any deprecated functions.

The sample covers Vertex Objects, Vertex Array Objects, Uniform and Attribute variables, shader setting, and definition of the camera and perspective matrices.

It uses GLUT to keep things simple (check out the GLUT tutorial if you’re not familiar with GLUT).

GLEW is also being used to provide access to the new OpenGL functions.

To load the shader text files we’re using simple C routines available in here.

First the shaders. These are an updated version of the color shader available in the GLSL 1.2 tutorial.

Vertex Shader

#version 150

uniform mat4 viewMatrix, projMatrix;

in vec4 position;
in vec3 color;

out vec3 Color;

void main()
{
	Color = color;
	gl_Position = projMatrix * viewMatrix * position ;
}

Fragment Shader

#version 150

in vec3 Color;
out vec4 outputF;

void main()
{
	outputF = vec4(Color,1.0);
}

And now the OpenGL 3.3 code:

/*

  Simple GLSL 1.5 Demo 

  www.lighthouse3d.com

*/

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/glut.h>

#include "textfile.h"

#define M_PI       3.14159265358979323846

// Data for drawing Axis
float verticesAxis[] = {-20.0f, 0.0f, 0.0f, 1.0f,
			20.0f, 0.0f, 0.0f, 1.0f,

			0.0f, -20.0f, 0.0f, 1.0f,
			0.0f,  20.0f, 0.0f, 1.0f,

			0.0f, 0.0f, -20.0f, 1.0f,
			0.0f, 0.0f,  20.0f, 1.0f};

float colorAxis[] = {	0.0f, 0.0f, 0.0f, 0.0f,
			0.0f, 0.0f, 0.0f, 0.0f,
			0.0f, 0.0f, 0.0f, 0.0f,
			0.0f, 0.0f, 0.0f, 0.0f,
			0.0f, 0.0f, 0.0f, 0.0f,
			0.0f, 0.0f, 0.0f, 0.0f};

// Data for triangle 1
float vertices1[] = {	-3.0f, 0.0f, -5.0f, 1.0f,
			-1.0f, 0.0f, -5.0f, 1.0f,
			-2.0f, 2.0f, -5.0f, 1.0f};

float colors1[] = {	0.0f, 0.0f, 1.0f, 1.0f,
			0.0f, 0.0f, 1.0f, 1.0f,
			0.0f,0.0f, 1.0f, 1.0f};

// Data for triangle 2
float vertices2[] = {	1.0f, 0.0f, -5.0f, 1.0f,
			3.0f, 0.0f, -5.0f, 1.0f,
			2.0f, 2.0f, -5.0f, 1.0f};

float colors2[] = {	1.0f, 0.0f, 0.0f, 1.0f,
			1.0f, 0.0f, 0.0f, 1.0f,
			1.0f,0.0f, 0.0f, 1.0f};

// Shader Names
char *vertexFileName = "color.vert";
char *fragmentFileName = "color.frag";

// Program and Shader Identifiers
GLuint p,v,f;

// Vertex Attribute Locations
GLuint vertexLoc, colorLoc;

// Uniform variable Locations
GLuint projMatrixLoc, viewMatrixLoc;

// Vertex Array Objects Identifiers
GLuint vao[3];

// storage for Matrices
float projMatrix[16];
float viewMatrix[16];

// ----------------------------------------------------
// VECTOR STUFF
//

// res = a cross b;
void crossProduct( float *a, float *b, float *res) {

	res[0] = a[1] * b[2]  -  b[1] * a[2];
	res[1] = a[2] * b[0]  -  b[2] * a[0];
	res[2] = a[0] * b[1]  -  b[0] * a[1];
}

// Normalize a vec3
void normalize(float *a) {

	float mag = sqrt(a[0] * a[0]  +  a[1] * a[1]  +  a[2] * a[2]);

	a[0] /= mag;
	a[1] /= mag;
	a[2] /= mag;
}

// ----------------------------------------------------
// MATRIX STUFF
//

// sets the square matrix mat to the identity matrix,
// size refers to the number of rows (or columns)
void setIdentityMatrix( float *mat, int size) {

	// fill matrix with 0s
	for (int i = 0; i < size * size; ++i)
			mat[i] = 0.0f;

	// fill diagonal with 1s
	for (int i = 0; i < size; ++i)
		mat[i + i * size] = 1.0f;
}

//
// a = a * b;
//
void multMatrix(float *a, float *b) {

	float res[16];

	for (int i = 0; i < 4; ++i) {
		for (int j = 0; j < 4; ++j) {
			res[j*4 + i] = 0.0f;
			for (int k = 0; k < 4; ++k) {
				res[j*4 + i] += a[k*4 + i] * b[j*4 + k];
			}
		}
	}
	memcpy(a, res, 16 * sizeof(float));

}

// Defines a transformation matrix mat with a translation
void setTranslationMatrix(float *mat, float x, float y, float z) {

	setIdentityMatrix(mat,4);
	mat[12] = x;
	mat[13] = y;
	mat[14] = z;
}

// ----------------------------------------------------
// Projection Matrix
//

void buildProjectionMatrix(float fov, float ratio, float nearP, float farP) {

	float f = 1.0f / tan (fov * (M_PI / 360.0));

	setIdentityMatrix(projMatrix,4);

	projMatrix[0] = f / ratio;
	projMatrix[1 * 4 + 1] = f;
	projMatrix[2 * 4 + 2] = (farP + nearP) / (nearP - farP);
	projMatrix[3 * 4 + 2] = (2.0f * farP * nearP) / (nearP - farP);
	projMatrix[2 * 4 + 3] = -1.0f;
	projMatrix[3 * 4 + 3] = 0.0f;
}

// ----------------------------------------------------
// View Matrix
//
// note: it assumes the camera is not tilted,
// i.e. a vertical up vector (remmeber gluLookAt?)
//

void setCamera(float posX, float posY, float posZ,
			   float lookAtX, float lookAtY, float lookAtZ) {

	float dir[3], right[3], up[3];

	up[0] = 0.0f;	up[1] = 1.0f;	up[2] = 0.0f;

	dir[0] =  (lookAtX - posX);
	dir[1] =  (lookAtY - posY);
	dir[2] =  (lookAtZ - posZ);
	normalize(dir);

	crossProduct(dir,up,right);
	normalize(right);

	crossProduct(right,dir,up);
	normalize(up);

	float aux[16];

	viewMatrix[0]  = right[0];
	viewMatrix[4]  = right[1];
	viewMatrix[8]  = right[2];
	viewMatrix[12] = 0.0f;

	viewMatrix[1]  = up[0];
	viewMatrix[5]  = up[1];
	viewMatrix[9]  = up[2];
	viewMatrix[13] = 0.0f;

	viewMatrix[2]  = -dir[0];
	viewMatrix[6]  = -dir[1];
	viewMatrix[10] = -dir[2];
	viewMatrix[14] =  0.0f;

	viewMatrix[3]  = 0.0f;
	viewMatrix[7]  = 0.0f;
	viewMatrix[11] = 0.0f;
	viewMatrix[15] = 1.0f;

	setTranslationMatrix(aux, -posX, -posY, -posZ);

	multMatrix(viewMatrix, aux);
}

// ----------------------------------------------------

void changeSize(int w, int h) {

	float ratio;
	// Prevent a divide by zero, when window is too short
	// (you cant make a window of zero width).
	if(h == 0)
		h = 1;

	// Set the viewport to be the entire window
    glViewport(0, 0, w, h);

	ratio = (1.0f * w) / h;
	buildProjectionMatrix(53.13f, ratio, 1.0f, 30.0f);
}

void setupBuffers() {

	GLuint buffers[2];

	glGenVertexArrays(3, vao);
	//
	// VAO for first triangle
	//
	glBindVertexArray(vao[0]);
	// Generate two slots for the vertex and color buffers
	glGenBuffers(2, buffers);
	// bind buffer for vertices and copy data into buffer
	glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
	glEnableVertexAttribArray(vertexLoc);
	glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, 0, 0, 0);

	// bind buffer for colors and copy data into buffer
	glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(colors1), colors1, GL_STATIC_DRAW);
	glEnableVertexAttribArray(colorLoc);
	glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);

	//
	// VAO for second triangle
	//
	glBindVertexArray(vao[1]);
	// Generate two slots for the vertex and color buffers
	glGenBuffers(2, buffers);

	// bind buffer for vertices and copy data into buffer
	glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
	glEnableVertexAttribArray(vertexLoc);
	glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, 0, 0, 0);

	// bind buffer for colors and copy data into buffer
	glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(colors2), colors2, GL_STATIC_DRAW);
	glEnableVertexAttribArray(colorLoc);
	glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);

	//
	// This VAO is for the Axis
	//
	glBindVertexArray(vao[2]);
	// Generate two slots for the vertex and color buffers
	glGenBuffers(2, buffers);
	// bind buffer for vertices and copy data into buffer
	glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(verticesAxis), verticesAxis, GL_STATIC_DRAW);
	glEnableVertexAttribArray(vertexLoc);
	glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, 0, 0, 0);

	// bind buffer for colors and copy data into buffer
	glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(colorAxis), colorAxis, GL_STATIC_DRAW);
	glEnableVertexAttribArray(colorLoc);
	glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);

}

void setUniforms() {

	// must be called after glUseProgram
	glUniformMatrix4fv(projMatrixLoc,  1, false, projMatrix);
	glUniformMatrix4fv(viewMatrixLoc,  1, false, viewMatrix);
}

void renderScene(void) {

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	setCamera(10,2,10,0,2,-5);

	glUseProgram(p);
	setUniforms();

	glBindVertexArray(vao[0]);
	glDrawArrays(GL_TRIANGLES, 0, 3);

	glBindVertexArray(vao[1]);
	glDrawArrays(GL_TRIANGLES, 0, 3);

	glBindVertexArray(vao[2]);
	glDrawArrays(GL_LINES, 0, 6);

	glutSwapBuffers();
}

void processNormalKeys(unsigned char key, int x, int y) {

	if (key == 27) {
		glDeleteVertexArrays(3,vao);
		glDeleteProgram(p);
		glDeleteShader(v);
		glDeleteShader(f);
		exit(0);
	}
}

#define printOpenGLError() printOglError(__FILE__, __LINE__)

int printOglError(char *file, int line)
{
    //
    // Returns 1 if an OpenGL error occurred, 0 otherwise.
    //
    GLenum glErr;
    int    retCode = 0;

    glErr = glGetError();
    while (glErr != GL_NO_ERROR)
    {
        printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
        retCode = 1;
        glErr = glGetError();
    }
    return retCode;
}

void printShaderInfoLog(GLuint obj)
{
    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;

	glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);

    if (infologLength > 0)
    {
        infoLog = (char *)malloc(infologLength);
        glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
		printf("%s\n",infoLog);
        free(infoLog);
    }
}

void printProgramInfoLog(GLuint obj)
{
    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;

	glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);

    if (infologLength > 0)
    {
        infoLog = (char *)malloc(infologLength);
        glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
		printf("%s\n",infoLog);
        free(infoLog);
    }
}

GLuint setupShaders() {

	char *vs = NULL,*fs = NULL,*fs2 = NULL;

	GLuint p,v,f;

	v = glCreateShader(GL_VERTEX_SHADER);
	f = glCreateShader(GL_FRAGMENT_SHADER);

	vs = textFileRead(vertexFileName);
	fs = textFileRead(fragmentFileName);

	const char * vv = vs;
	const char * ff = fs;

	glShaderSource(v, 1, &vv,NULL);
	glShaderSource(f, 1, &ff,NULL);

	free(vs);free(fs);

	glCompileShader(v);
	glCompileShader(f);

	printShaderInfoLog(v);
	printShaderInfoLog(f);

	p = glCreateProgram();
	glAttachShader(p,v);
	glAttachShader(p,f);

	glBindFragDataLocation(p, 0, "outputF");
	glLinkProgram(p);
	printProgramInfoLog(p);

	vertexLoc = glGetAttribLocation(p,"position");
	colorLoc = glGetAttribLocation(p, "color"); 

	projMatrixLoc = glGetUniformLocation(p, "projMatrix");
	viewMatrixLoc = glGetUniformLocation(p, "viewMatrix");

	return(p);
}

int main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(320,320);
	glutCreateWindow("Lighthouse 3D");

	glutDisplayFunc(renderScene);
	glutIdleFunc(renderScene);
	glutReshapeFunc(changeSize);
	glutKeyboardFunc(processNormalKeys);

	glewInit();
	if (glewIsSupported("GL_VERSION_3_3"))
		printf("Ready for OpenGL 3.3\n");
	else {
		printf("OpenGL 3.3 not supported\n");
		exit(1);
	}

	glEnable(GL_DEPTH_TEST);
	glClearColor(1.0,1.0,1.0,1.0);

	p = setupShaders(); 
	setupBuffers(); 

	glutMainLoop();

	return(0); 
}

  16 Responses to “OpenGL 3.3 + GLSL 1.5 Sample”

  1. Thanks for this great Tutorial and also thanks to @swilson for the port – its not really often that you paste a code and it works immediately. Very helpful!!! Since there isnt much on the net for jogl and OpenGL 3 upwards.

    So keep up the good work!
    Greets from Austria

  2. Quick java port using Jogl2.0rc11 for anyone interested:

    import static javax.media.opengl.GL.*;

    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;

    import javax.media.opengl.*;
    import javax.media.opengl.awt.*;

    import com.jogamp.common.nio.*;

    /**
    * This is a port of some sample code from:
    * http://www.lighthouse3d.com/cg-topics/code-samples/opengl-3-3-glsl-1-5-sample/
    */
    public class Gl3Sample implements GLEventListener {
    // Data for drawing Axis
    float verticesAxis[] = { -20.0f, 0.0f, 0.0f, 1.0f, 20.0f, 0.0f, 0.0f, 1.0f,

    0.0f, -20.0f, 0.0f, 1.0f, 0.0f, 20.0f, 0.0f, 1.0f,

    0.0f, 0.0f, -20.0f, 1.0f, 0.0f, 0.0f, 20.0f, 1.0f };

    float colorAxis[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 0.0f };

    // Data for triangle 1
    float vertices1[] = { -3.0f, 0.0f, -5.0f, 1.0f, -1.0f, 0.0f, -5.0f, 1.0f,
    -2.0f, 2.0f, -5.0f, 1.0f };

    float colors1[] = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 1.0f };

    // Data for triangle 2
    float vertices2[] = { 1.0f, 0.0f, -5.0f, 1.0f, 3.0f, 0.0f, -5.0f, 1.0f,
    2.0f, 2.0f, -5.0f, 1.0f };

    float colors2[] = { 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
    0.0f, 0.0f, 1.0f };

    // Shader Names
    String vertexFileName = “color.vert”;
    String fragmentFileName = “color.frag”;

    // Program and Shader Identifiers
    int p, v, f;

    // Vertex Attribute Locations
    int vertexLoc, colorLoc;

    // Uniform variable Locations
    int projMatrixLoc, viewMatrixLoc;

    // Vertex Array Objects Identifiers
    int vao[] = new int[3];

    // storage for Matrices
    float projMatrix[] = new float[16];
    float viewMatrix[] = new float[16];

    // —————————————————-
    // VECTOR STUFF
    //

    // res = a cross b;
    void crossProduct(float a[], float b[], float res[]) {

    res[0] = a[1] * b[2] – b[1] * a[2];
    res[1] = a[2] * b[0] – b[2] * a[0];
    res[2] = a[0] * b[1] – b[0] * a[1];
    }

    // Normalize a vec3
    void normalize(float a[]) {

    float mag = (float) Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);

    a[0] /= mag;
    a[1] /= mag;
    a[2] /= mag;
    }

    // —————————————————-
    // MATRIX STUFF
    //

    // sets the square matrix mat to the identity matrix,
    // size refers to the number of rows (or columns)
    void setIdentityMatrix(float[] mat, int size) {

    // fill matrix with 0s
    for (int i = 0; i < size * size; ++i)
    mat[i] = 0.0f;

    // fill diagonal with 1s
    for (int i = 0; i < size; ++i)
    mat[i + i * size] = 1.0f;
    }

    //
    // a = a * b;
    //
    void multMatrix(float[] a, float[] b) {

    float[] res = new float[16];

    for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 4; ++j) {
    res[j * 4 + i] = 0.0f;
    for (int k = 0; k < 4; ++k) {
    res[j * 4 + i] += a[k * 4 + i] * b[j * 4 + k];
    }
    }
    }

    System.arraycopy(res, 0, a, 0, 16);
    }

    // Defines a transformation matrix mat with a translation
    void setTranslationMatrix(float[] mat, float x, float y, float z) {

    setIdentityMatrix(mat, 4);
    mat[12] = x;
    mat[13] = y;
    mat[14] = z;
    }

    // —————————————————-
    // Projection Matrix
    //

    void buildProjectionMatrix(float fov, float ratio, float nearP, float farP) {

    float f = 1.0f / (float) Math.tan(fov * (Math.PI / 360.0));

    setIdentityMatrix(projMatrix, 4);

    projMatrix[0] = f / ratio;
    projMatrix[1 * 4 + 1] = f;
    projMatrix[2 * 4 + 2] = (farP + nearP) / (nearP – farP);
    projMatrix[3 * 4 + 2] = (2.0f * farP * nearP) / (nearP – farP);
    projMatrix[2 * 4 + 3] = -1.0f;
    projMatrix[3 * 4 + 3] = 0.0f;
    }

    // —————————————————-
    // View Matrix
    //
    // note: it assumes the camera is not tilted,
    // i.e. a vertical up vector (remmeber gluLookAt?)
    //

    void setCamera(float posX, float posY, float posZ, float lookAtX,
    float lookAtY, float lookAtZ) {

    float[] dir = new float[3];
    float[] right = new float[3];
    float[] up = new float[3];

    up[0] = 0.0f;
    up[1] = 1.0f;
    up[2] = 0.0f;

    dir[0] = (lookAtX – posX);
    dir[1] = (lookAtY – posY);
    dir[2] = (lookAtZ – posZ);
    normalize(dir);

    crossProduct(dir, up, right);
    normalize(right);

    crossProduct(right, dir, up);
    normalize(up);

    float[] aux = new float[16];

    viewMatrix[0] = right[0];
    viewMatrix[4] = right[1];
    viewMatrix[8] = right[2];
    viewMatrix[12] = 0.0f;

    viewMatrix[1] = up[0];
    viewMatrix[5] = up[1];
    viewMatrix[9] = up[2];
    viewMatrix[13] = 0.0f;

    viewMatrix[2] = -dir[0];
    viewMatrix[6] = -dir[1];
    viewMatrix[10] = -dir[2];
    viewMatrix[14] = 0.0f;

    viewMatrix[3] = 0.0f;
    viewMatrix[7] = 0.0f;
    viewMatrix[11] = 0.0f;
    viewMatrix[15] = 1.0f;

    setTranslationMatrix(aux, -posX, -posY, -posZ);

    multMatrix(viewMatrix, aux);
    }

    // —————————————————-

    void changeSize(GL3 gl, int w, int h) {

    float ratio;
    // Prevent a divide by zero, when window is too short
    // (you cant make a window of zero width).
    if (h == 0)
    h = 1;

    // Set the viewport to be the entire window
    gl.glViewport(0, 0, w, h);

    ratio = (1.0f * w) / h;
    buildProjectionMatrix(53.13f, ratio, 1.0f, 30.0f);
    }

    void setupBuffers(GL3 gl) {

    int buffers[] = new int[2];
    gl.glGenVertexArrays(3, vao, 0);
    //
    // VAO for first triangle
    //
    gl.glBindVertexArray(vao[0]);
    // Generate two slots for the vertex and color buffers
    gl.glGenBuffers(2, buffers, 0);
    // bind buffer for vertices and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    gl.glBufferData(GL_ARRAY_BUFFER, vertices1.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(vertices1), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(vertexLoc);
    gl.glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, false, 0, 0);

    // bind buffer for colors and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    gl.glBufferData(GL_ARRAY_BUFFER, colors1.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(colors1), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(colorLoc);
    gl.glVertexAttribPointer(colorLoc, 4, GL_FLOAT, false, 0, 0);

    //
    // VAO for second triangle
    //
    gl.glBindVertexArray(vao[1]);
    // Generate two slots for the vertex and color buffers
    gl.glGenBuffers(2, buffers, 0);

    // bind buffer for vertices and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    gl.glBufferData(GL_ARRAY_BUFFER, vertices2.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(vertices2), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(vertexLoc);
    gl.glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, false, 0, 0);

    // bind buffer for colors and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    gl.glBufferData(GL_ARRAY_BUFFER, colors2.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(colors2), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(colorLoc);
    gl.glVertexAttribPointer(colorLoc, 4, GL_FLOAT, false, 0, 0);

    //
    // This VAO is for the Axis
    //
    gl.glBindVertexArray(vao[2]);
    // Generate two slots for the vertex and color buffers
    gl.glGenBuffers(2, buffers, 0);
    // bind buffer for vertices and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    gl.glBufferData(GL_ARRAY_BUFFER, verticesAxis.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(verticesAxis), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(vertexLoc);
    gl.glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, false, 0, 0);

    // bind buffer for colors and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    gl.glBufferData(GL_ARRAY_BUFFER, colorAxis.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(colorAxis), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(colorLoc);
    gl.glVertexAttribPointer(colorLoc, 4, GL_FLOAT, false, 0, 0);

    }

    void setUniforms(GL3 gl) {

    // must be called after glUseProgram
    gl.glUniformMatrix4fv(projMatrixLoc, 1, false, projMatrix, 0);
    gl.glUniformMatrix4fv(viewMatrixLoc, 1, false, viewMatrix, 0);
    }

    void renderScene(GL3 gl) {

    gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    setCamera(10, 2, 10, 0, 2, -5);

    gl.glUseProgram(p);
    setUniforms(gl);

    gl.glBindVertexArray(vao[0]);
    gl.glDrawArrays(GL_TRIANGLES, 0, 3);

    gl.glBindVertexArray(vao[1]);
    gl.glDrawArrays(GL_TRIANGLES, 0, 3);

    gl.glBindVertexArray(vao[2]);
    gl.glDrawArrays(GL_LINES, 0, 6);
    }

    /** Retrieves the info log for the shader */
    public String printShaderInfoLog(GL3 gl, int obj) {
    // Otherwise, we'll get the GL info log
    final int logLen = getShaderParameter(gl, obj, GL3.GL_INFO_LOG_LENGTH);
    if (logLen <= 0)
    return "";

    // Get the log
    final int[] retLength = new int[1];
    final byte[] bytes = new byte[logLen + 1];
    gl.glGetShaderInfoLog(obj, logLen, retLength, 0, bytes, 0);
    final String logMessage = new String(bytes);

    return String.format("ShaderLog: %s", logMessage);
    }

    /** Get a shader parameter value. See 'glGetShaderiv' */
    private int getShaderParameter(GL3 gl, int obj, int paramName) {
    final int params[] = new int[1];
    gl.glGetShaderiv(obj, paramName, params, 0);
    return params[0];
    }

    /** Retrieves the info log for the program */
    public String printProgramInfoLog(GL3 gl, int obj) {
    // get the GL info log
    final int logLen = getProgramParameter(gl, obj, GL3.GL_INFO_LOG_LENGTH);
    if (logLen <= 0)
    return "";

    // Get the log
    final int[] retLength = new int[1];
    final byte[] bytes = new byte[logLen + 1];
    gl.glGetProgramInfoLog(obj, logLen, retLength, 0, bytes, 0);
    final String logMessage = new String(bytes);

    return logMessage;
    }

    /** Gets a program parameter value */
    public int getProgramParameter(GL3 gl, int obj, int paramName) {
    final int params[] = new int[1];
    gl.glGetProgramiv(obj, paramName, params, 0);
    return params[0];
    }

    public String textFileRead(String filePath) {
    // Read the data in
    BufferedReader reader = null;
    try {
    // Read in the source
    reader = new BufferedReader(new FileReader(filePath));
    final StringBuilder sb = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null)
    sb.append(line).append("\n");
    final String text = sb.toString();

    return text;

    } catch (final Exception ex) {
    ex.printStackTrace();

    } finally {
    try {
    reader.close();
    } catch (final Exception ex) {
    }
    }

    return "";
    }

    int setupShaders(GL3 gl) {

    String vs = null;
    String fs = null;
    String fs2 = null;

    int p, v, f;

    v = gl.glCreateShader(GL3.GL_VERTEX_SHADER);
    f = gl.glCreateShader(GL3.GL_FRAGMENT_SHADER);

    vs = textFileRead(vertexFileName);
    fs = textFileRead(fragmentFileName);

    String vv = vs;
    String ff = fs;

    gl.glShaderSource(v, 1, new String[] { vv }, null);
    gl.glShaderSource(f, 1, new String[] { ff }, null);

    gl.glCompileShader(v);
    gl.glCompileShader(f);

    printShaderInfoLog(gl, v);
    printShaderInfoLog(gl, f);

    p = gl.glCreateProgram();
    gl.glAttachShader(p, v);
    gl.glAttachShader(p, f);

    gl.glBindFragDataLocation(p, 0, "outputF");
    gl.glLinkProgram(p);
    printProgramInfoLog(gl, p);

    vertexLoc = gl.glGetAttribLocation(p, "position");
    colorLoc = gl.glGetAttribLocation(p, "color");

    projMatrixLoc = gl.glGetUniformLocation(p, "projMatrix");
    viewMatrixLoc = gl.glGetUniformLocation(p, "viewMatrix");

    return (p);
    }

    /** GL Init */
    @Override
    public void init(GLAutoDrawable drawable) {
    GL3 gl = drawable.getGL().getGL3();
    gl.glEnable(GL_DEPTH_TEST);
    gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

    p = setupShaders(gl);
    setupBuffers(gl);
    }

    /** GL Window Reshape */
    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width,
    int height) {
    GL3 gl = drawable.getGL().getGL3();
    changeSize(gl, width, height);
    }

    /** GL Render loop */
    @Override
    public void display(GLAutoDrawable drawable) {
    GL3 gl = drawable.getGL().getGL3();
    renderScene(gl);
    }

    /** GL Complete */
    @Override
    public void dispose(GLAutoDrawable drawable) {
    }

    /** Main entry point for the application */
    public static void main(String[] args) {
    Gl3Sample sample = new Gl3Sample();

    GLProfile glp = GLProfile.get(GLProfile.GL3);
    GLCapabilities glCapabilities = new GLCapabilities(glp);
    final GLCanvas glCanvas = new GLCanvas(glCapabilities);
    final Frame frame = new Frame("GL3 Test");
    glCanvas.addGLEventListener(sample);

    frame.add(glCanvas);
    frame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent windowevent) {
    frame.remove(glCanvas);
    frame.dispose();
    System.exit(0);
    }
    });

    frame.setSize(320, 320);
    frame.setVisible(true);
    }
    }

  3. Now runs, but crash everytime in this line: memcpy(&faceArray[faceIndex], face->mIndices,3 * sizeof(float));

    Do you have a solution maybe?

  4. textfile.h not found, ERROR! 🙁

  5. near and far are reserved keywords, at least in VS2010

  6. Hi!
    This is super interesting suff 😀 I’m mosly new to all of this so I’m not sure how this works. When compiling and running your program I get a blank white screen, even tho it semes to succesfully load the object. Have his something to do with the output being a reserved word error (fragment sahder compilation error #133) or is it the cameras default possition or somehing? I have not edited the code in any way. Tnx 🙂

  7. ” gl_Position = projMatrix * viewMatrix * position ; ”

    ^^ the projection matrix and modelview matrices are probably in the wrong order

    • The projection matrix is the last matrix to be applied. The point (position) must be first transformed by the view matrix.

  8. I am new to open gl and trying to implement a code where i load obj ussing assimp and perform transformation on it, i am getting struck since my basic r not very clear is this the right forum to get help

    My code compile in debug it displays the model take the key input but never performs any transformation

  9. Just tried the shaders in Shader Maker and got:
    Fragment shader failed to compile with the following errors:
    ERROR: 0:5: error(#133) Reserved word: output
    ERROR: 0:5: error(#132) Syntax error: ‘output’ parse error
    ERROR: error(#273) 2 compilation errors. No code generated
    The GL info shows
    ….
    Renderer: ATI Radeon HD 4550
    Version: 3.3.11079 Compatibility Profile Context

    • Yes, you’re right. It works fine with NVIDIA, but not with ATI. Actually ATI is right, since “output” is a reserved word.

      Thanks for the comment.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: