The Little Body
07-24-2011, 07:51 AM
Hi,
I have make a little sample that display something like your picture and where we can resize the inner and outer radius with the top/bottom/right/left keys
It have use DevIL for to have the possibity to load .jpg files
The shader.h file :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
// Handlers for our vertex shader, fragment shader and program
extern GLuint vsid, fsid, psid;
// Textures
extern GLint tex0, tex1;
// Fog
extern GLint indist, outdist;
extern GLfloat innersize, outersize;
extern GLint centerxLoc, centeryLoc;
extern GLfloat centerx, centery;
// Read in a textfile (GLSL program)
// we need to pass it as a string to the GLSL driver
char *ReadGLSL(char *fn);
// Read in a textfile (GLSL program)
// we can use this to write to a text file
int WriteGLSL(char *fn, char *s);
// Setup shaders
void SetupShaders(char *vsrc, char *fsrc);
The shader.c file:
#include "shader.h"
//Handlers for our vertex, geometry, and fragment shaders
GLuint vsid, fsid, psid;
// variables on your fragment shader
GLint tex0;
GLint tex1;
GLint indist;
GLint outdist;
GLfloat innersize = 0.2f;
GLfloat outersize = 0.4f;
GLint centerxLoc;
GLint centeryLoc;
GLfloat centerx = 0.5f;
GLfloat centery = 0.5f;
//Function from: http://www.evl.uic.edu/aej/594/code/ogl.cpp
//Read in a textfile (GLSL program)
// we need to pass it as a string to the GLSL driver
char *ReadGLSL(char *fn)
{
FILE *fp;
char *content = NULL;
int count=0;
if (fn != NULL) {
fp = fopen(fn,"rt");
if (fp != NULL) {
fseek(fp, 0, SEEK_END);
count = ftell(fp);
rewind(fp);
if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '\0';
}
fclose(fp);
}
}
printf("%s\n", content);
return content;
}
//Function from: http://www.evl.uic.edu/aej/594/code/ogl.cpp
//Read in a textfile (GLSL program)
// we can use this to write to a text file
int WriteGLSL(char *fn, char *s)
{
FILE *fp;
int status = 0;
if (fn != NULL) {
fp = fopen(fn,"w");
if (fp != NULL) {
if (fwrite(s,sizeof(char),strlen(s),fp) == strlen(s))
status = 1;
fclose(fp);
}
}
return(status);
}
//Got this from http://www.lighthouse3d.com/opengl/glsl/index.php?oglinfo
// it prints out shader info (debugging!)
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);
if( charsWritten > 0)
printf("printShaderInfoLog %d :\n%s\n", obj, infoLog);
free(infoLog);
}else{
printf("Shader Info Log: OK\n");
}
}
//Got this from http://www.lighthouse3d.com/opengl/glsl/index.php?oglinfo
// it prints out shader info (debugging!)
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);
if( charsWritten > 0 )
printf("printProgramInfoLog %d :\n%s\n", obj, infoLog);
free(infoLog);
}else{
printf("Program Info Log: OK\n");
}
}
//Setup shaders
void SetupShaders(char *vsrc, char *fsrc)
{
//Setup a few constant pointers for below
char *vs = NULL, *fs = NULL;
glewInit();
if (glewIsSupported("GL_VERSION_2_1"))
{
// printf("Ready for OpenGL 2.1\n");
}
else {
printf("OpenGL 2.1 not supported\n");
exit(1);
}
if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader )
{
// printf("Ready for GLSL vertex and fragment shaders \n");
}
else {
printf("Not ready fot GLSL vertex and fragment shaders \n");
exit(1);
}
vsid = glCreateShader(GL_VERTEX_SHADER);
if( vsid == 0)
{
printf("can't create a GL_VERTEX_SHADER :( \n");
exit(0);
}else{
printf("VERTEX SHADER(%s) : id=%d \n", vsrc, vsid);
vs = ReadGLSL(vsrc);
const char * vv = vs;
glShaderSource(vsid, 1, &vv, NULL);
// free(vs);
glCompileShader(vsid);
// printShaderInfoLog(vsid);
}
fsid = glCreateShader(GL_FRAGMENT_SHADER);
if( fsid == 0)
{
printf("can't create a GL_FRAGMENT_SHADER :( \n");
exit(0);
}else{
printf("FRAGMENT SHADER(%s) : id=%d\n", fsrc, fsid);
fs = ReadGLSL(fsrc);
const char * ff = fs;
glShaderSource(fsid, 1, &ff, NULL);
// free(fs);
glCompileShader(fsid);
// printShaderInfoLog(fsid);
}
psid = glCreateProgram();
glAttachShader(psid,fsid);
glAttachShader(psid,vsid);
glLinkProgram(psid);
glUseProgram(psid);
tex0 = glGetUniformLocation(psid, "tex0");
tex1 = glGetUniformLocation(psid, "tex1");
indist = glGetUniformLocation(psid, "indist");
outdist = glGetUniformLocation(psid, "outdist");
centerxLoc = glGetUniformLocation(psid, "centerx");
centeryLoc = glGetUniformLocation(psid, "centery");
glUniform1f(indist, 0.2f);
glUniform1f(outdist, 0.4f);
glUniform1f(centerxLoc, 0.5f);
glUniform1f(centeryLoc, 0.5f);
printf("PROGRAM SHADER : vertexshader=%d fragmentshader=%d program=%d tex0=%d tex1=%d indist=%d outdist=%d \n",
vsid, fsid, psid, tex0, tex1, indist, outdist );
printProgramInfoLog(psid);
}
The fog.c file :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
/* use devIL for texture loading */
#include <IL/il.h>
/* use OpenGL shaders */
#include "shader.h"
/* ascii code for the escape key */
#define ESCAPE 27
#define FALSE 0
#define TRUE 1
/* The number of our GLUT window */
int window;
// todo : handle/mix multiples windows
// int windows[];
// int nWindows;
/* The texture used */
GLuint Textures[1];
ILuint ilTextures[1];
char *dataTexture;
int twidth = 0, theight = 0, tformat = 0, tbpp = 0;
int wwidth = 320, wheight=200;
void DrawQuadZoom( int v0, int v1, float zoom)
{
float x0, y0, x1, y1;
x0 = y0 = v0 * zoom;
x1 = y1 = v1 * zoom;
glBegin(GL_QUADS);
//glColor3f(0,1,0);
//glTexCoord2i(1,0);
glTexCoord2i(1,1);
glVertex3f(x0,y0,v0);
//glColor3f(0,0,1);
//glTexCoord2i(0,0);
glTexCoord2i(0,1);
glVertex3f(x1,y0,v0);
//glColor3f(1,0,0);
//glTexCoord2i(0,1);
glTexCoord2i(0,0);
glVertex3f(x1,y1,v0);
//glColor3f(1,0,0);
//glTexCoord2i(1,1);
glTexCoord2i(1,0);
glVertex3f(x0,y1,v0);
glEnd();
}
void DrawQuad()
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, Textures[0]);
glLoadIdentity ();
DrawQuadZoom(-1, 1, 1.0f);
glutSwapBuffers();
}
void InitDevIL(char *filename1, char *filename2)
{
ilInit();
ilGenImages(2, ilTextures);
ilBindImage(ilTextures[0]);
if( ilLoadImage(filename1) == 0)
{
printf("ilLoadImage %s KO \n", filename1);
exit(0);
}
dataTexture = ilGetData();
twidth = ilGetInteger(IL_IMAGE_WIDTH);
theight = ilGetInteger(IL_IMAGE_HEIGHT);
tformat = ilGetInteger(IL_IMAGE_FORMAT);
tbpp = ilGetInteger(IL_IMAGE_BPP);
printf("ilLoad(%s) : data=%x width=%d, height=%d bpp=%d \n\n", filename1, dataTexture,twidth,theight,tbpp);
glBindTexture(GL_TEXTURE_2D, Textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, twidth, theight, 0, GL_RGB, GL_UNSIGNED_BYTE, dataTexture);
/*
ilBindImage(ilTextures[1]);
if( ilLoadImage(filename2?filename2:filename1) == 0)
{
printf("ilLoadImage %s KO \n", filename2?filename2:filename1);
exit(0);
}
dataTexture = ilGetData();
twidth = ilGetInteger(IL_IMAGE_WIDTH);
theight = ilGetInteger(IL_IMAGE_HEIGHT);
tformat = ilGetInteger(IL_IMAGE_FORMAT);
tbpp = ilGetInteger(IL_IMAGE_BPP);
printf("ilLoad(%s) : data=%x width=%d, height=%d bpp=%d \n\n", filename2, dataTexture,twidth,theight,tbpp);
glBindTexture(GL_TEXTURE_2D, Textures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, twidth, theight, 0, GL_RGB, GL_UNSIGNED_BYTE, dataTexture);
*/
}
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.
{
// Start Of User Initialization
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Realy Nice perspective calculations
glClearColor (0.7f, 0.7f, 0.7f, 0.0f); // Light Grey Background
glClearDepth (1.0f); // Depth Buffer Setup
glEnable(GL_TEXTURE_2D);
glGenTextures(2,Textures);
glBindTexture(GL_TEXTURE_2D, Textures[0]);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
/*
glBindTexture(GL_TEXTURE_2D, Textures[1]);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
*/
}
/* The function called when our window is resized */
void ReSizeGLScene(int Width, int Height)
{
// Prevent A Divide By Zero If The Window Is Too Small
if (Height==0) Height=1;
// Reset The Current Viewport And Perspective Transformation
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat) Width / (GLfloat) Height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
wwidth = Width;
wheight = Height;
// printf("ReSizeGLScene(%d,%d) \n", wwidth, wheight);
}
// Delete The Shader Texture
void Deinitialize (void)
{
glDeleteTextures (2, Textures);
}
/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y)
{
/* avoid thrashing this procedure */
usleep(100);
/* If escape is pressed, kill everything. */
switch (key) {
case ESCAPE: // kill everything.
/* shut down our window */
Deinitialize();
glutDestroyWindow(window);
/* exit the program...normal termination. */
exit(1);
break; // redundant.
default:
printf ("Key %d pressed. No action there yet.\n", key);
break;
}
glutPostRedisplay();
}
void specialKeyPressed(int key, int x, int y)
{
/* avoid thrashing this procedure */
usleep(100);
switch (key) {
case GLUT_KEY_UP:
printf("(%d) innersize++ \n",key);
innersize += 0.01f;
if( innersize >= outersize) innersize = outersize - 0.1f;
glUniform1f(indist, innersize);
break;
case GLUT_KEY_DOWN:
printf("(%d) innersize-- \n",key);
innersize -= 0.01f;
if( innersize < 0.0f) innersize= 0.0f;
glUniform1f(indist, innersize);
break;
case GLUT_KEY_LEFT :
printf("(%d) outersize-- \n",key);
outersize -= 0.01f;
if( outersize <= innersize) outersize = innersize + 0.1f;
glUniform1f(outdist, outersize);
break;
case GLUT_KEY_RIGHT :
printf("(%d) outersize++ \n",key);
outersize += 0.01f;
if( outersize > 1.0f) outersize= 1.0f;
glUniform1f(outdist, outersize);
break;
default:
printf ("Key %d pressed. No action there yet.\n", key);
break;
}
glutPostRedisplay();
}
void MouseMoved(int x, int y)
{
printf("MouseMove(%d/%d,%d/%d) \n", x, wwidth, y, wheight);
centerx = ((x-(wwidth /2.0f))/(-wwidth*2.0f)) + 0.5f;
centery = (((wheight/2.0f)-y)/(-wheight*2.0f)) + 0.5f;
printf("Center : %f %f\n", centerx, centery);
glUniform1f(centerxLoc, centerx);
glUniform1f(centeryLoc, centery);
glutPostRedisplay();
}
int main(int argc, char **argv)
{
/* Initialize GLUT state - glut will take any command line arguments that pertain to it or
X Windows - look at its documentation at http://reality.sgi.com/mjk/spec3/spec3.html */
glutInit(&argc, argv);
/* Select type of Display mode */
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
/* get a width x height (640*480) window size */
glutInitWindowSize(wwidth, wheight);
/* the window starts at the upper left corner of the screen */
glutInitWindowPosition(0, 0);
/* Open a window */
window = glutCreateWindow("Quad Shader v0.1");
/* Register the function to do all our OpenGL drawing. */
glutDisplayFunc(&DrawQuad);
/* Register the function called when our window is resized. */
glutReshapeFunc(&ReSizeGLScene);
/* Register the function called when the keyboard is pressed. */
glutKeyboardFunc(&keyPressed);
glutSpecialFunc(&specialKeyPressed);
/* Register the function to do all our OpenGL drawing. */
glutMotionFunc(&MouseMoved);
/* Initialize our window. */
InitGL(wwidth, wheight);
InitDevIL(argv[1], argv[2]);
SetupShaders("shader.vert","shader.frag");
// glUniformlui(tex0, Textures[0]);
// glUniformlui(tex1, Textures[1]);
/* Start Event Processing Engine */
glutMainLoop();
return 1;
}
The shader.frag file :
// uniform sampler2D tex;
uniform sampler2D tex0;
uniform sampler2D tex1;
//float indist = 0.3;
//float outdist = 0.7;
uniform float indist;
uniform float outdist;
uniform float centerx;
uniform float centery;
void main()
{
// vec2 vdif = (gl_TexCoord[0].st - vec2(0.5,0.5)) * 4.0;
vec2 vdif = (gl_TexCoord[0].st - vec2(centerx, centery)) * 4.0;
float f = sqrt( vdif.x*vdif.x + vdif.y*vdif.y );
vec4 fade;
if( f < indist )
{
fade = texture2D(tex0, gl_TexCoord[0].st) * vec4(0.3,0.3,0.3,1.0);
}else{
if( f > outdist)
{
fade = texture2D(tex0, gl_TexCoord[0].st) * vec4(0.3,0.3,0.3,1.0);
}else{
fade = texture2D(tex0, gl_TexCoord[0].st);
}
}
gl_FragColor = fade;
}
The shader.vert file :
void main()
{
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_Position = ftransform();
}
And finaly the Makefile :
all: fog shader.o
shader.o : shader.c shader.h
gcc -c shader.c -o shader.o -L/usr/X11R6/lib -lGL -lGLU -lglut -lIL -lGLEW
fog : fog.c shader.o
gcc fog.c shader.o -o fog -L/usr/X11R6/lib -lGL -lGLU -lglut -lIL -lGLEW
clean :
rm shader.o fog
You can compile this with the commande 'make' and run with './fog myfilename.jpg'
LukeJ
07-25-2011, 03:27 PM
Maybe if i post the whole file up it mite give some idea sorry if this could of help earlier :)
//////////////////////////////////////////////////////////////////////////////
//
// Global constants are defined in global_constants.hlsl
//
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Textures/Samplers used by this shader
//////////////////////////////////////////////////////////////////////////////
// Vertex input/output definitions
struct RangeVS_INPUT
{
// Stream 0 static vertex data
float2 Vertex : POSITION0;
float3 AlphaScalar : TEXCOORD0;
// Stream 1 instance data
float2 Position : POSITION1;
float2 Radius : TEXCOORD1;
};
struct RangeVS_OUTPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
};
#ifdef XBOX
//////////////////////////////////////////////////////////////////////////////
// Vertex fetching for Xbox 360 instancing
float4 FetchRangeVertex( int index )
{
float4 vert;
asm {
vfetch vert, index, position0;
};
return vert;
}
float4 FetchAlphaScalar( int index )
{
float4 scalar;
asm {
vfetch scalar, index, texcoord0;
};
return scalar;
}
float4 FetchRangePosition( int index )
{
float4 pos;
asm {
vfetch pos, index, position1;
};
return pos;
}
float4 FetchRangeRadius( int index )
{
float4 radius;
asm {
vfetch radius, index, texcoord1;
};
return radius;
}
RangeVS_INPUT CreateRangeVertexInput( int index )
{
// Compute the instance index
int nNumVertsPerInstance = VertsPerInstance;
int nInstIndex = ( index + 0.5 ) / nNumVertsPerInstance;
int nMeshIndex = index - nInstIndex * nNumVertsPerInstance;
// Fetch the mesh vertex data
RangeVS_INPUT vertexInput = (RangeVS_INPUT)0;
// Per vertex data
vertexInput.Vertex = FetchRangeVertex( nMeshIndex );
vertexInput.AlphaScalar = FetchAlphaScalar( nMeshIndex );
// Per instance data
vertexInput.Position = FetchRangePosition( nInstIndex );
vertexInput.Radius = FetchRangeRadius( nInstIndex );
return vertexInput;
}
#endif
//////////////////////////////////////////////////////////////////////////////
// Vertex shader
RangeVS_OUTPUT RangeVS(
#ifndef XBOX
RangeVS_INPUT In
#else
int index : INDEX
#endif
)
{
#ifdef XBOX
RangeVS_INPUT In = CreateRangeVertexInput( index );
#endif
// Output from vertex shader
RangeVS_OUTPUT Out = (RangeVS_OUTPUT)0;
// Scale the vertex based on requested range, and add in the instanced position
#if FEATHER_OUT
In.Vertex.xy *= dot( In.AlphaScalar.yz, float2( In.Radius.y, In.Radius.y + FogIntel.z ) );
#endif
#if FEATHER_IN
In.Vertex.xy *= dot( In.AlphaScalar.yz, float2( max( 0.0f, In.Radius.y - FogIntel.z ), In.Radius.y ) );
#endif
In.Vertex.xy += In.Position.xy - 1;
// Scale the values by the map dimensions and then map to [-1,1]
In.Vertex.xy *= FogIntel.xy;
In.Vertex.xy = In.Vertex.xy * 2 - 1;
// Transform vertex to homogenous clip space
Out.Position = float4( In.Vertex.x, -In.Vertex.y, 1.0f, 1.0f );
#if FEATHER_OUT
Out.Color = In.AlphaScalar.xxxx;
#endif
#if FEATHER_IN
Out.Color = float4( 1.0f, 1.0f, 1.0f, 1.0f ) - In.AlphaScalar.xxxx;
#endif
// Return our finished product
return Out;
}
//////////////////////////////////////////////////////////////////////////////
// Pixel shader
float4 RangePS( RangeVS_OUTPUT In ) : COLOR
{
return( GlobalColor * In.Color );
}
//////////////////////////////////////////////////////////////////////////////
// Vertex input/output definitions
struct VisionVS_INPUT
{
// Stream 0 static vertex data
float2 Vertex : POSITION0;
float2 AlphaRad : TEXCOORD0;
// Stream 1 instance data
float2 Position : POSITION1;
float Radius : TEXCOORD1;
};
struct VisionVS_OUTPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
};
#ifdef XBOX
//////////////////////////////////////////////////////////////////////////////
// Vertex fetching for Xbox 360 instancing
float2 FetchVisionVertex( int index )
{
float4 vert;
asm {
vfetch vert, index, position0;
};
return vert.xy;
}
float2 FetchVisionAlphaRad( int index )
{
float4 alpharad;
asm {
vfetch alpharad, index, texcoord0;
};
return alpharad.xy;
}
float4 FetchVisionPosition( int index )
{
float4 pos;
asm {
vfetch pos, index, position1;
};
return pos;
}
float4 FetchVisionRadius( int index )
{
float4 radius;
asm {
vfetch radius, index, texcoord1;
};
return radius;
}
VisionVS_INPUT CreateVisionVertexInput( int index )
{
// Compute the instance index
int nNumVertsPerInstance = VertsPerInstance;
int nInstIndex = ( index + 0.5 ) / nNumVertsPerInstance;
int nMeshIndex = index - nInstIndex * nNumVertsPerInstance;
// Fetch the mesh vertex data
VisionVS_INPUT vertexInput = (VisionVS_INPUT)0;
// Per vertex data
vertexInput.Vertex = FetchVisionVertex( nMeshIndex );
vertexInput.AlphaRad = FetchVisionAlphaRad( nMeshIndex );
// Per instance data
vertexInput.Position = FetchVisionPosition( nInstIndex );
vertexInput.Radius = FetchVisionRadius( nInstIndex );
return vertexInput;
}
#endif
//////////////////////////////////////////////////////////////////////////////
// Vertex shader
VisionVS_OUTPUT VisionVS(
#ifndef XBOX
VisionVS_INPUT In
#else
int index : INDEX
#endif
)
{
#ifdef XBOX
VisionVS_INPUT In = CreateVisionVertexInput( index );
#endif
// Output from vertex shader
VisionVS_OUTPUT Out = (VisionVS_OUTPUT)0;
// Scale the vertex based on requested range, and add in the instanced position
In.Vertex.xy *= In.Radius + (In.AlphaRad.y * FogIntel.z);
In.Vertex.xy += In.Position.xy - 1;
// Scale the values by the map dimensions and then map to [-1,1]
In.Vertex.xy *= FogIntel.xy;
In.Vertex.xy = In.Vertex.xy * 2 - 1;
// Transform vertex to homogenous clip space
Out.Position = float4( In.Vertex.x, -In.Vertex.y, 1.0f, 1.0f );
Out.Color = float4( 0.0f, 0.0f, 0.0f, In.AlphaRad.x );
// Return our finished product
return Out;
}
//////////////////////////////////////////////////////////////////////////////
// Pixel shader
float4 VisionPS( VisionVS_OUTPUT In ) : COLOR
{
return( In.Color );
}
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.