#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glfw.h>
//Declare vectors for gcc.
typedef float v4f __attribute__ ((vector_size (16)));
typedef float rgba __attribute__ ((vector_size (16)));
typedef float v2f __attribute__ ((vector_size (8)));
//Used by the report function defined below.
#define REPORT_TIMESTAMP
#define DEBUG
#define FAIL 1
#define WARN 2
#define INFO 4
#define PASS 8
#define REPORT_SHOW (FAIL|WARN|INFO|PASS)
void report(unsigned char level, const char* format, ...){//A "fancy-smancy printf replacer" for debugging purposes.
if(REPORT_SHOW & level){
va_list args;
va_start (args, format);
#ifdef REPORT_TIMESTAMP
fprintf(stderr, "\033[1;37m[%7.4f]",glfwGetTime());
#endif
if(level & FAIL)//critical failure
fputs("\033[1;31m[FAIL]\033[0m", stderr);
else if(level & PASS)//something went right
fputs("\033[1;32m[PASS]\033[0m", stderr);
else if(level &WARN)//Watch out for this.
fputs("\033[0;31m[WARN]\033[0m", stderr);
else if(level & INFO) //Information.
fputs("\033[1;34m[INFO]\033[0m", stderr);
vfprintf(stderr, format, args);
fputs("\n",stderr);
va_end(args);
}
}
GLuint shaderFromFilename(char *File,GLenum shaderType){
GLenum glError;
GLuint shader = glCreateShader(shaderType);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Failed to create shader.");
return -1;
}
FILE * fp;
unsigned long fileSize;
GLchar* source;
fp = fopen(File, "r");
if(fp == NULL){
report(FAIL, "Couldn't open shader file!");
return 0;
}
fseek(fp, 0, SEEK_END);
fileSize = ftell(fp);
rewind(fp); //be kind, rewind.
source = malloc((fileSize+1)*sizeof(char));
if(source == NULL){
report(FAIL, "Couldn't allocate earth for shader!");
return 0;
}
if(fread(source,1,fileSize,fp) != fileSize){
report(FAIL, "Couldn't read the opend shader file!");
return 0;
}
source[fileSize] = '\0';
glShaderSource(shader,1,(const GLchar**)&source,NULL);
glCompileShader(shader);
return shader;
}
void reportShaderLog(GLuint shader){
GLsizei logLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
if(logLength != 1){
GLchar *shaderLog = malloc(logLength);
glGetShaderInfoLog(shader,logLength,NULL,shaderLog);
report(WARN, "Shader log:\n %s",shaderLog);
free(shaderLog);
}
}
GLuint createProgramFromFilenames(char *vertexShader, char *fragmentShader){//simple wrapper for vertex+frag shader program creation.
GLenum glError;
GLuint vs = shaderFromFilename(vertexShader,GL_VERTEX_SHADER);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Failed everything!" ,vertexShader, fragmentShader,glError);
return -1;
}
GLint isCompiled;
glGetShaderiv(vs,GL_COMPILE_STATUS,&isCompiled);
isCompiled == GL_TRUE? report(PASS,"Compiled %s", vertexShader) : report(FAIL, "Couldn't compile %s",vertexShader);
reportShaderLog(vs);
GLuint fs = shaderFromFilename(fragmentShader,GL_FRAGMENT_SHADER);
glGetShaderiv(fs,GL_COMPILE_STATUS,&isCompiled);
isCompiled == GL_TRUE? report(PASS,"Compiled %s", fragmentShader) : report(FAIL, "Couldn't compile %s",fragmentShader);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Failed to compile everything!" ,vertexShader, fragmentShader,glError);
return -1;
}
reportShaderLog(fs);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "what!" ,vertexShader, fragmentShader,glError);
return -1;
}
GLuint shaderProgram = glCreateProgram();
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Couldn't create program!" ,vertexShader, fragmentShader,glError);
return -1;
}
glAttachShader(shaderProgram, fs);
glAttachShader(shaderProgram,vs);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Couldn't prepare linking %s and %s, error:" ,vertexShader, fragmentShader,glError);
return -1;
}
glLinkProgram(shaderProgram);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Couldn't link %s and %s, error:" ,vertexShader, fragmentShader,glError);
return -1;
}
report(PASS, "Linked %s and %s", vertexShader, fragmentShader);
return shaderProgram;
}
void GLFWCALL My_Key_Callback(int key, int action){
if(key == GLFW_KEY_SPACE && action == GLFW_PRESS)
exit(EXIT_SUCCESS);
}
int initialize(){
glewExperimental = GL_TRUE;
GLenum err;
if( glfwInit() != GL_TRUE){
report(FAIL, "Couldn't Initialize GLFW!");
return -1;
}
//Start by initializing OpenGL,
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR,3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR,0);
//glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
{ //Scope block because we don't need this anywhere else and it's to little to warrant a function.
int major,minor,rev;
glfwGetVersion(&major,&minor,&rev);
report(INFO, "Using GLFW version %d.%d, revision %d.", major,minor,rev);
}
if( glfwOpenWindow( 600,600, 0,0,0,0,0,0, GLFW_WINDOW ) != GL_TRUE){
report(FAIL, "Couldn't create window!");
glfwTerminate();
return -2;
}
err = glGetError();
if(err != GL_NO_ERROR){
report(FAIL, "Error on opening window!");
}
//Initialize GLEW so we can use our extensions.
err = glewInit();
if(err !=GLEW_OK){
report(FAIL,"Couldn't initialze GLEW: %s", glewGetErrorString(err));
return -3;
}
report(INFO, "Using GLEW %s", glewGetString(GLEW_VERSION));
err = glGetError();
if(err != GL_NO_ERROR){
report(WARN, "Glew set GL_ERROR, should be fine though!");
}
//glfwSwapInterval(0); //vsync off
//Report some information about the window if wanted./*
report(INFO,"Using OpenGL Version %d.%d.",glfwGetWindowParam(GLFW_OPENGL_VERSION_MAJOR), glfwGetWindowParam(GLFW_OPENGL_VERSION_MINOR));
report(INFO,"Using (%d,%d,%d)RGB bit-depth.",glfwGetWindowParam(GLFW_RED_BITS),glfwGetWindowParam(GLFW_GREEN_BITS),glfwGetWindowParam(GLFW_BLUE_BITS));
report(INFO,"Hardware acceleration: %s.", glfwGetWindowParam(GLFW_ACCELERATED) == GL_TRUE? "Supported": "Unsupported");
report(INFO,"Refresh Rate: %dHz.", glfwGetWindowParam(GLFW_REFRESH_RATE));
report(PASS, "Intialized.");
glfwSetKeyCallback(My_Key_Callback);
return 0;
}
int main(int argc, char **argv)
{
GLenum glError;
if(initialize()) //basic initialisation
exit(EXIT_FAILURE);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Failed to init!");
return -1;
}
//create the shaders
GLuint shaderProgram = createProgramFromFilenames("./shaders/pointPath.vert", "./shaders/spritePoint.frag");
glUseProgram (shaderProgram);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "An error occured while building the shader program!");
else
report(PASS, "Succesfully using shaders");
//Create and set first texture.
v2f path[] = {{-0.5,0.5},//A path "t -> (x,y)" along which we will place our sprites
{-0.5,-0.5},
{0.5,-0.5},
{0.5,0.5}};
glActiveTexture(GL_TEXTURE0);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Couldn't activate texture!");
GLuint pathTex;
glGenTextures(1, &pathTex); //create a new texture
glBindTexture(GL_TEXTURE_1D, pathTex); //start using it as a 1D texture
glTexImage1D(GL_TEXTURE_1D,0,GL_RG32F, sizeof(path)/sizeof(v2f),0,GL_RG,GL_FLOAT,path); //store the coordinates of path in the texture so that we can interpolate our path in the shader.
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_BASE_LEVEL, 0);//We need these two lines
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL, 0);//because we don't have mipmaps.
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//We want the path to be linearly filtered
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//Set the min filter just to be safe.
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Something went wrong setting up pathTex");
GLint uniformLoc = glGetUniformLocation(shaderProgram, "pathTexture"); //locate the uniform
uniformLoc >= 0?glUniform1i(uniformLoc, 0):report(FAIL, "found uniform spriteTexture at %d", uniformLoc); //and set it to "0" because we're using GL_TEXTURE0
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Couldn't set uniform!");
report(PASS, "Setup texture for path");
//create and set second texture
rgba sprite[] = {{1.0,0,0,1},{0,1.0,0,1},{0,0,1.0,1},{1,1,0,1}}; //our sprite, a simple "red,green,blue,yellow" square.
glActiveTexture(GL_TEXTURE0+1); //use texUnit 1 now.
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Couldn't activate texture!");
GLuint spriteTex;
glGenTextures(1, &spriteTex); //create a new texture
glBindTexture(GL_TEXTURE_2D, spriteTex); //start using it as a 2D texture
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, 2,2,0,GL_RGBA,GL_FLOAT,sprite); //load the data again. 2x2 sprite.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);//We need these two lines
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);//because we don't have mipmaps.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//We want our sprites to be filtered to
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//the nearest pixel, not interpolated.
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Something went wrong setting up pathTex");
uniformLoc = glGetUniformLocation(shaderProgram, "spriteTexture"); //locates and set the second sampler.
uniformLoc >= 0?glUniform1i(uniformLoc, 1):report(FAIL, "found uniform spriteTexture at %d", uniformLoc);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Couldn't set uniform!");
report(PASS, "Setup texture for sprite");
//Create our sprite locations
#define Npoints 1024 //any number > the number of path points will do.
GLfloat points[Npoints]; //the location in "t-space" of our sprites, i.e. the texture coordinate for our path texture.
for(size_t i = 0; i < Npoints;i++)
points[i] = (float)i/(float)Npoints; //fill it from 0 to 1.
report(PASS, "generated points array.");
//set-up a our buffers.
unsigned int vaSprites;
glGenVertexArrays(1,&vaSprites);
report(PASS, "Generated vertex array");
unsigned int vbSprites;
glGenBuffers(1, &vbSprites);
glBindBuffer(GL_ARRAY_BUFFER, vbSprites);
glBufferData (GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Something went wrong generating the vbSprites!");
glBindVertexArray(vaSprites);
GLint inputAttrib = glGetAttribLocation(shaderProgram, "t");
glEnableVertexAttribArray(inputAttrib);
glVertexAttribPointer (inputAttrib, 1, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Something went wrong generating the vaSprites!");
else
report(PASS, "Set-up vaSprites.");
glEnable(GL_POINT_SPRITE); //We need this (on Nvidia atleast) for obvious reasons.
glPointSize(64);
while(1){ //our main loop,it's broken by hitting space.
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_POINTS,0, Npoints);
glfwSwapBuffers();
}
return 0;
}
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glfw.h>
//Declare vectors for gcc.
typedef float v4f __attribute__ ((vector_size (16)));
typedef float rgba __attribute__ ((vector_size (16)));
typedef float v2f __attribute__ ((vector_size (8)));
//Used by the report function defined below.
#define REPORT_TIMESTAMP
#define DEBUG
#define FAIL 1
#define WARN 2
#define INFO 4
#define PASS 8
#define REPORT_SHOW (FAIL|WARN|INFO|PASS)
void report(unsigned char level, const char* format, ...){//A "fancy-smancy printf replacer" for debugging purposes.
if(REPORT_SHOW & level){
va_list args;
va_start (args, format);
#ifdef REPORT_TIMESTAMP
fprintf(stderr, "\033[1;37m[%7.4f]",glfwGetTime());
#endif
if(level & FAIL)//critical failure
fputs("\033[1;31m[FAIL]\033[0m", stderr);
else if(level & PASS)//something went right
fputs("\033[1;32m[PASS]\033[0m", stderr);
else if(level &WARN)//Watch out for this.
fputs("\033[0;31m[WARN]\033[0m", stderr);
else if(level & INFO) //Information.
fputs("\033[1;34m[INFO]\033[0m", stderr);
vfprintf(stderr, format, args);
fputs("\n",stderr);
va_end(args);
}
}
GLuint shaderFromFilename(char *File,GLenum shaderType){
GLenum glError;
GLuint shader = glCreateShader(shaderType);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Failed to create shader.");
return -1;
}
FILE * fp;
unsigned long fileSize;
GLchar* source;
fp = fopen(File, "r");
if(fp == NULL){
report(FAIL, "Couldn't open shader file!");
return 0;
}
fseek(fp, 0, SEEK_END);
fileSize = ftell(fp);
rewind(fp); //be kind, rewind.
source = malloc((fileSize+1)*sizeof(char));
if(source == NULL){
report(FAIL, "Couldn't allocate earth for shader!");
return 0;
}
if(fread(source,1,fileSize,fp) != fileSize){
report(FAIL, "Couldn't read the opend shader file!");
return 0;
}
source[fileSize] = '\0';
glShaderSource(shader,1,(const GLchar**)&source,NULL);
glCompileShader(shader);
return shader;
}
void reportShaderLog(GLuint shader){
GLsizei logLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
if(logLength != 1){
GLchar *shaderLog = malloc(logLength);
glGetShaderInfoLog(shader,logLength,NULL,shaderLog);
report(WARN, "Shader log:\n %s",shaderLog);
free(shaderLog);
}
}
GLuint createProgramFromFilenames(char *vertexShader, char *fragmentShader){//simple wrapper for vertex+frag shader program creation.
GLenum glError;
GLuint vs = shaderFromFilename(vertexShader,GL_VERTEX_SHADER);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Failed everything!" ,vertexShader, fragmentShader,glError);
return -1;
}
GLint isCompiled;
glGetShaderiv(vs,GL_COMPILE_STATUS,&isCompiled);
isCompiled == GL_TRUE? report(PASS,"Compiled %s", vertexShader) : report(FAIL, "Couldn't compile %s",vertexShader);
reportShaderLog(vs);
GLuint fs = shaderFromFilename(fragmentShader,GL_FRAGMENT_SHADER);
glGetShaderiv(fs,GL_COMPILE_STATUS,&isCompiled);
isCompiled == GL_TRUE? report(PASS,"Compiled %s", fragmentShader) : report(FAIL, "Couldn't compile %s",fragmentShader);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Failed to compile everything!" ,vertexShader, fragmentShader,glError);
return -1;
}
reportShaderLog(fs);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "what!" ,vertexShader, fragmentShader,glError);
return -1;
}
GLuint shaderProgram = glCreateProgram();
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Couldn't create program!" ,vertexShader, fragmentShader,glError);
return -1;
}
glAttachShader(shaderProgram, fs);
glAttachShader(shaderProgram,vs);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Couldn't prepare linking %s and %s, error:" ,vertexShader, fragmentShader,glError);
return -1;
}
glLinkProgram(shaderProgram);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Couldn't link %s and %s, error:" ,vertexShader, fragmentShader,glError);
return -1;
}
report(PASS, "Linked %s and %s", vertexShader, fragmentShader);
return shaderProgram;
}
void GLFWCALL My_Key_Callback(int key, int action){
if(key == GLFW_KEY_SPACE && action == GLFW_PRESS)
exit(EXIT_SUCCESS);
}
int initialize(){
glewExperimental = GL_TRUE;
GLenum err;
if( glfwInit() != GL_TRUE){
report(FAIL, "Couldn't Initialize GLFW!");
return -1;
}
//Start by initializing OpenGL,
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR,3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR,0);
//glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
{ //Scope block because we don't need this anywhere else and it's to little to warrant a function.
int major,minor,rev;
glfwGetVersion(&major,&minor,&rev);
report(INFO, "Using GLFW version %d.%d, revision %d.", major,minor,rev);
}
if( glfwOpenWindow( 600,600, 0,0,0,0,0,0, GLFW_WINDOW ) != GL_TRUE){
report(FAIL, "Couldn't create window!");
glfwTerminate();
return -2;
}
err = glGetError();
if(err != GL_NO_ERROR){
report(FAIL, "Error on opening window!");
}
//Initialize GLEW so we can use our extensions.
err = glewInit();
if(err !=GLEW_OK){
report(FAIL,"Couldn't initialze GLEW: %s", glewGetErrorString(err));
return -3;
}
report(INFO, "Using GLEW %s", glewGetString(GLEW_VERSION));
err = glGetError();
if(err != GL_NO_ERROR){
report(WARN, "Glew set GL_ERROR, should be fine though!");
}
//glfwSwapInterval(0); //vsync off
//Report some information about the window if wanted./*
report(INFO,"Using OpenGL Version %d.%d.",glfwGetWindowParam(GLFW_OPENGL_VERSION_MAJOR), glfwGetWindowParam(GLFW_OPENGL_VERSION_MINOR));
report(INFO,"Using (%d,%d,%d)RGB bit-depth.",glfwGetWindowParam(GLFW_RED_BITS),glfwGetWindowParam(GLFW_GREEN_BITS),glfwGetWindowParam(GLFW_BLUE_BITS));
report(INFO,"Hardware acceleration: %s.", glfwGetWindowParam(GLFW_ACCELERATED) == GL_TRUE? "Supported": "Unsupported");
report(INFO,"Refresh Rate: %dHz.", glfwGetWindowParam(GLFW_REFRESH_RATE));
report(PASS, "Intialized.");
glfwSetKeyCallback(My_Key_Callback);
return 0;
}
int main(int argc, char **argv)
{
GLenum glError;
if(initialize()) //basic initialisation
exit(EXIT_FAILURE);
glError = glGetError();
if(glError != GL_NO_ERROR){
report(FAIL, "Failed to init!");
return -1;
}
//create the shaders
GLuint shaderProgram = createProgramFromFilenames("./shaders/pointPath.vert", "./shaders/spritePoint.frag");
glUseProgram (shaderProgram);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "An error occured while building the shader program!");
else
report(PASS, "Succesfully using shaders");
//Create and set first texture.
v2f path[] = {{-0.5,0.5},//A path "t -> (x,y)" along which we will place our sprites
{-0.5,-0.5},
{0.5,-0.5},
{0.5,0.5}};
glActiveTexture(GL_TEXTURE0);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Couldn't activate texture!");
GLuint pathTex;
glGenTextures(1, &pathTex); //create a new texture
glBindTexture(GL_TEXTURE_1D, pathTex); //start using it as a 1D texture
glTexImage1D(GL_TEXTURE_1D,0,GL_RG32F, sizeof(path)/sizeof(v2f),0,GL_RG,GL_FLOAT,path); //store the coordinates of path in the texture so that we can interpolate our path in the shader.
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_BASE_LEVEL, 0);//We need these two lines
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL, 0);//because we don't have mipmaps.
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//We want the path to be linearly filtered
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//Set the min filter just to be safe.
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Something went wrong setting up pathTex");
GLint uniformLoc = glGetUniformLocation(shaderProgram, "pathTexture"); //locate the uniform
uniformLoc >= 0?glUniform1i(uniformLoc, 0):report(FAIL, "found uniform spriteTexture at %d", uniformLoc); //and set it to "0" because we're using GL_TEXTURE0
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Couldn't set uniform!");
report(PASS, "Setup texture for path");
//create and set second texture
rgba sprite[] = {{1.0,0,0,1},{0,1.0,0,1},{0,0,1.0,1},{1,1,0,1}}; //our sprite, a simple "red,green,blue,yellow" square.
glActiveTexture(GL_TEXTURE0+1); //use texUnit 1 now.
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Couldn't activate texture!");
GLuint spriteTex;
glGenTextures(1, &spriteTex); //create a new texture
glBindTexture(GL_TEXTURE_2D, spriteTex); //start using it as a 2D texture
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, 2,2,0,GL_RGBA,GL_FLOAT,sprite); //load the data again. 2x2 sprite.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);//We need these two lines
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);//because we don't have mipmaps.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//We want our sprites to be filtered to
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//the nearest pixel, not interpolated.
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Something went wrong setting up pathTex");
uniformLoc = glGetUniformLocation(shaderProgram, "spriteTexture"); //locates and set the second sampler.
uniformLoc >= 0?glUniform1i(uniformLoc, 1):report(FAIL, "found uniform spriteTexture at %d", uniformLoc);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Couldn't set uniform!");
report(PASS, "Setup texture for sprite");
//Create our sprite locations
#define Npoints 1024 //any number > the number of path points will do.
GLfloat points[Npoints]; //the location in "t-space" of our sprites, i.e. the texture coordinate for our path texture.
for(size_t i = 0; i < Npoints;i++)
points[i] = (float)i/(float)Npoints; //fill it from 0 to 1.
report(PASS, "generated points array.");
//set-up a our buffers.
unsigned int vaSprites;
glGenVertexArrays(1,&vaSprites);
report(PASS, "Generated vertex array");
unsigned int vbSprites;
glGenBuffers(1, &vbSprites);
glBindBuffer(GL_ARRAY_BUFFER, vbSprites);
glBufferData (GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Something went wrong generating the vbSprites!");
glBindVertexArray(vaSprites);
GLint inputAttrib = glGetAttribLocation(shaderProgram, "t");
glEnableVertexAttribArray(inputAttrib);
glVertexAttribPointer (inputAttrib, 1, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL);
if(glGetError() != GL_NO_ERROR)
report(FAIL, "Something went wrong generating the vaSprites!");
else
report(PASS, "Set-up vaSprites.");
glEnable(GL_POINT_SPRITE); //We need this (on Nvidia atleast) for obvious reasons.
glPointSize(64);
while(1){ //our main loop,it's broken by hitting space.
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_POINTS,0, Npoints);
glfwSwapBuffers();
}
return 0;
}