mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 20:50:09 +01:00
Added toyball and bumpmap tests using shaders from the OpenGL Shading Language (orange) book.
This commit is contained in:
parent
9b5dc1358a
commit
f44ba11815
8 changed files with 854 additions and 4 deletions
41
progs/glsl/CH11-bumpmap.frag.txt
Normal file
41
progs/glsl/CH11-bumpmap.frag.txt
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Fragment shader for procedural bumps
|
||||
//
|
||||
// Authors: John Kessenich, Randi Rost
|
||||
//
|
||||
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
|
||||
//
|
||||
// See 3Dlabs-License.txt for license information
|
||||
//
|
||||
|
||||
varying vec3 LightDir;
|
||||
varying vec3 EyeDir;
|
||||
|
||||
uniform vec3 SurfaceColor; // = (0.7, 0.6, 0.18)
|
||||
uniform float BumpDensity; // = 16.0
|
||||
uniform float BumpSize; // = 0.15
|
||||
uniform float SpecularFactor; // = 0.5
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 litColor;
|
||||
vec2 c = BumpDensity * gl_TexCoord[0].st;
|
||||
vec2 p = fract(c) - vec2(0.5);
|
||||
|
||||
float d, f;
|
||||
d = p.x * p.x + p.y * p.y;
|
||||
f = 1.0 / sqrt(d + 1.0);
|
||||
|
||||
if (d >= BumpSize)
|
||||
{ p = vec2(0.0); f = 1.0; }
|
||||
|
||||
vec3 normDelta = vec3(p.x, p.y, 1.0) * f;
|
||||
litColor = SurfaceColor * max(dot(normDelta, LightDir), 0.0);
|
||||
vec3 reflectDir = reflect(LightDir, normDelta);
|
||||
|
||||
float spec = max(dot(EyeDir, reflectDir), 0.0);
|
||||
spec *= SpecularFactor;
|
||||
litColor = min(litColor + spec, vec3(1.0));
|
||||
|
||||
gl_FragColor = vec4(litColor, 1.0);
|
||||
}
|
||||
38
progs/glsl/CH11-bumpmap.vert.txt
Normal file
38
progs/glsl/CH11-bumpmap.vert.txt
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// Vertex shader for procedural bumps
|
||||
//
|
||||
// Authors: Randi Rost, John Kessenich
|
||||
//
|
||||
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
|
||||
//
|
||||
// See 3Dlabs-License.txt for license information
|
||||
//
|
||||
|
||||
varying vec3 LightDir;
|
||||
varying vec3 EyeDir;
|
||||
|
||||
uniform vec3 LightPosition;
|
||||
|
||||
attribute vec3 Tangent;
|
||||
|
||||
void main()
|
||||
{
|
||||
EyeDir = vec3(gl_ModelViewMatrix * gl_Vertex);
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
|
||||
vec3 t = normalize(gl_NormalMatrix * Tangent);
|
||||
vec3 b = cross(n, t);
|
||||
|
||||
vec3 v;
|
||||
v.x = dot(LightPosition, t);
|
||||
v.y = dot(LightPosition, b);
|
||||
v.z = dot(LightPosition, n);
|
||||
LightDir = normalize(v);
|
||||
|
||||
v.x = dot(EyeDir, t);
|
||||
v.y = dot(EyeDir, b);
|
||||
v.z = dot(EyeDir, n);
|
||||
EyeDir = normalize(v);
|
||||
}
|
||||
79
progs/glsl/CH11-toyball.frag.txt
Normal file
79
progs/glsl/CH11-toyball.frag.txt
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
//
|
||||
// Fragment shader for procedurally generated toy ball
|
||||
//
|
||||
// Author: Bill Licea-Kane
|
||||
//
|
||||
// Copyright (c) 2002-2003 ATI Research
|
||||
//
|
||||
// See ATI-License.txt for license information
|
||||
//
|
||||
|
||||
varying vec4 ECposition; // surface position in eye coordinates
|
||||
varying vec4 ECballCenter; // ball center in eye coordinates
|
||||
|
||||
uniform vec4 LightDir; // light direction, should be normalized
|
||||
uniform vec4 HVector; // reflection vector for infinite light source
|
||||
uniform vec4 SpecularColor;
|
||||
uniform vec4 Red, Yellow, Blue;
|
||||
|
||||
uniform vec4 HalfSpace0; // half-spaces used to define star pattern
|
||||
uniform vec4 HalfSpace1;
|
||||
uniform vec4 HalfSpace2;
|
||||
uniform vec4 HalfSpace3;
|
||||
uniform vec4 HalfSpace4;
|
||||
|
||||
uniform float InOrOutInit; // = -3
|
||||
uniform float StripeWidth; // = 0.3
|
||||
uniform float FWidth; // = 0.005
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 normal; // Analytically computed normal
|
||||
vec4 p; // Point in shader space
|
||||
vec4 surfColor; // Computed color of the surface
|
||||
float intensity; // Computed light intensity
|
||||
vec4 distance; // Computed distance values
|
||||
float inorout; // Counter for computing star pattern
|
||||
|
||||
p.xyz = normalize(ECposition.xyz - ECballCenter.xyz); // Calculate p
|
||||
p.w = 1.0;
|
||||
|
||||
inorout = InOrOutInit; // initialize inorout to -3
|
||||
|
||||
distance[0] = dot(p, HalfSpace0);
|
||||
distance[1] = dot(p, HalfSpace1);
|
||||
distance[2] = dot(p, HalfSpace2);
|
||||
distance[3] = dot(p, HalfSpace3);
|
||||
|
||||
#if 1
|
||||
distance = smoothstep(-FWidth, FWidth, distance);
|
||||
inorout += dot(distance, vec4(1.0));
|
||||
|
||||
distance.x = dot(p, HalfSpace4);
|
||||
distance.y = StripeWidth - abs(p.z);
|
||||
distance = smoothstep(-FWidth, FWidth, distance);
|
||||
inorout += distance.x;
|
||||
|
||||
inorout = clamp(inorout, 0.0, 1.0);
|
||||
|
||||
surfColor = mix(Yellow, Red, inorout);
|
||||
surfColor = mix(surfColor, Blue, distance.y);
|
||||
|
||||
// normal = point on surface for sphere at (0,0,0)
|
||||
normal = p;
|
||||
|
||||
// Per fragment diffuse lighting
|
||||
intensity = 0.2; // ambient
|
||||
intensity += 0.8 * clamp(dot(LightDir, normal), 0.0, 1.0);
|
||||
surfColor *= intensity;
|
||||
|
||||
// Per fragment specular lighting
|
||||
intensity = clamp(dot(HVector, normal), 0.0, 1.0);
|
||||
intensity = pow(intensity, SpecularColor.a);
|
||||
surfColor += SpecularColor * intensity;
|
||||
|
||||
gl_FragColor = surfColor;
|
||||
#else
|
||||
gl_FragColor = distance;
|
||||
#endif
|
||||
}
|
||||
20
progs/glsl/CH11-toyball.vert.txt
Normal file
20
progs/glsl/CH11-toyball.vert.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// Fragment shader for procedurally generated toy ball
|
||||
//
|
||||
// Author: Bill Licea-Kane
|
||||
//
|
||||
// Copyright (c) 2002-2003 ATI Research
|
||||
//
|
||||
// See ATI-License.txt for license information
|
||||
//
|
||||
|
||||
varying vec4 ECposition; // surface position in eye coordinates
|
||||
varying vec4 ECballCenter; // ball center in eye coordinates
|
||||
uniform vec4 BallCenter; // ball center in modelling coordinates
|
||||
|
||||
void main()
|
||||
{
|
||||
ECposition = gl_ModelViewMatrix * gl_Vertex;
|
||||
ECballCenter = gl_ModelViewMatrix * BallCenter;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
|
@ -30,8 +30,8 @@ void main()
|
|||
float r2 = 0.0;
|
||||
float iter;
|
||||
|
||||
for (iter = 0.0; iter < MaxIterations && r2 < 4.0; ++iter)
|
||||
//nv: for (iter = 0.0; iter < 12 && r2 < 4.0; ++iter)
|
||||
// for (iter = 0.0; iter < MaxIterations && r2 < 4.0; ++iter)
|
||||
for (iter = 0.0; iter < 12 && r2 < 4.0; ++iter)
|
||||
{
|
||||
float tempreal = real;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(T
|
|||
|
||||
PROGS = \
|
||||
brick \
|
||||
mandelbrot
|
||||
bump \
|
||||
mandelbrot \
|
||||
toyball
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
|
@ -33,7 +35,9 @@ PROGS = \
|
|||
|
||||
default: $(PROGS)
|
||||
|
||||
$(PROGS):
|
||||
|
||||
|
||||
##### Extra dependencies
|
||||
|
||||
extfuncs.h: $(TOP)/progs/util/extfuncs.h
|
||||
cp $< .
|
||||
|
|
@ -41,8 +45,12 @@ extfuncs.h: $(TOP)/progs/util/extfuncs.h
|
|||
|
||||
brick.c: extfuncs.h
|
||||
|
||||
bump.c: extfuncs.h
|
||||
|
||||
mandelbrot.c: extfuncs.h
|
||||
|
||||
toyball.c: extfuncs.h
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f $(PROGS)
|
||||
|
|
|
|||
348
progs/glsl/bump.c
Normal file
348
progs/glsl/bump.c
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
/**
|
||||
* Procedural Bump Mapping demo. Uses the example shaders from
|
||||
* chapter 11 of the OpenGL Shading Language "orange" book.
|
||||
* 16 Jan 2007
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glext.h>
|
||||
#include "extfuncs.h"
|
||||
|
||||
|
||||
static char *FragProgFile = "CH11-bumpmap.frag.txt";
|
||||
static char *VertProgFile = "CH11-bumpmap.vert.txt";
|
||||
|
||||
/* program/shader objects */
|
||||
static GLuint fragShader;
|
||||
static GLuint vertShader;
|
||||
static GLuint program;
|
||||
|
||||
|
||||
struct uniform_info {
|
||||
const char *name;
|
||||
GLuint size;
|
||||
GLint location;
|
||||
GLfloat value[4];
|
||||
};
|
||||
|
||||
static struct uniform_info Uniforms[] = {
|
||||
{ "LightPosition", 3, -1, { 0.57737, 0.57735, 0.57735, 0.0 } },
|
||||
{ "SurfaceColor", 3, -1, { 0.8, 0.8, 0.2, 0 } },
|
||||
{ "BumpDensity", 1, -1, { 16.0, 0, 0, 0 } },
|
||||
{ "BumpSize", 1, -1, { 0.15, 0, 0, 0 } },
|
||||
{ "SpecularFactor", 1, -1, { 0.5, 0, 0, 0 } },
|
||||
{ NULL, 0, 0, { 0, 0, 0, 0 } }
|
||||
};
|
||||
|
||||
static GLint win = 0;
|
||||
|
||||
static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
|
||||
|
||||
static GLuint tangentAttrib;
|
||||
|
||||
|
||||
static void
|
||||
CheckError(int line)
|
||||
{
|
||||
GLenum err = glGetError();
|
||||
if (err) {
|
||||
printf("GL Error %s (0x%x) at line %d\n",
|
||||
gluErrorString(err), (int) err, line);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw a square, specifying normal and tangent vectors.
|
||||
*/
|
||||
static void
|
||||
Square(GLfloat size)
|
||||
{
|
||||
glNormal3f(0, 0, 1);
|
||||
glVertexAttrib3f_func(tangentAttrib, 1, 0, 0);
|
||||
glBegin(GL_POLYGON);
|
||||
glTexCoord2f(0, 0); glVertex2f(-size, -size);
|
||||
glTexCoord2f(1, 0); glVertex2f( size, -size);
|
||||
glTexCoord2f(1, 1); glVertex2f( size, size);
|
||||
glTexCoord2f(0, 1); glVertex2f(-size, size);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Redisplay(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
|
||||
glRotatef(zRot, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
Square(2.0);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glFinish();
|
||||
glFlush();
|
||||
|
||||
CheckError(__LINE__);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Reshape(int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -15.0f);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CleanUp(void)
|
||||
{
|
||||
glDeleteShader_func(fragShader);
|
||||
glDeleteShader_func(vertShader);
|
||||
glDeleteProgram_func(program);
|
||||
glutDestroyWindow(win);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Key(unsigned char key, int x, int y)
|
||||
{
|
||||
const GLfloat step = 2.0;
|
||||
(void) x;
|
||||
(void) y;
|
||||
|
||||
switch(key) {
|
||||
case 'z':
|
||||
zRot += step;
|
||||
break;
|
||||
case 'Z':
|
||||
zRot -= step;
|
||||
break;
|
||||
case 27:
|
||||
CleanUp();
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
SpecialKey(int key, int x, int y)
|
||||
{
|
||||
const GLfloat step = 2.0;
|
||||
|
||||
(void) x;
|
||||
(void) y;
|
||||
|
||||
switch(key) {
|
||||
case GLUT_KEY_UP:
|
||||
xRot += step;
|
||||
break;
|
||||
case GLUT_KEY_DOWN:
|
||||
xRot -= step;
|
||||
break;
|
||||
case GLUT_KEY_LEFT:
|
||||
yRot -= step;
|
||||
break;
|
||||
case GLUT_KEY_RIGHT:
|
||||
yRot += step;
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
LoadAndCompileShader(GLuint shader, const char *text)
|
||||
{
|
||||
GLint stat;
|
||||
|
||||
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
|
||||
|
||||
glCompileShader_func(shader);
|
||||
|
||||
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetShaderInfoLog_func(shader, 1000, &len, log);
|
||||
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
printf("Shader compiled OK\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a shader from a file.
|
||||
*/
|
||||
static void
|
||||
ReadShader(GLuint shader, const char *filename)
|
||||
{
|
||||
const int max = 100*1000;
|
||||
int n;
|
||||
char *buffer = (char*) malloc(max);
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
n = fread(buffer, 1, max, f);
|
||||
printf("brick: read %d bytes from shader file %s\n", n, filename);
|
||||
if (n > 0) {
|
||||
buffer[n] = 0;
|
||||
LoadAndCompileShader(shader, buffer);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CheckLink(GLuint prog)
|
||||
{
|
||||
GLint stat;
|
||||
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetProgramInfoLog_func(prog, 1000, &len, log);
|
||||
fprintf(stderr, "Linker error:\n%s\n", log);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Link success!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Init(void)
|
||||
{
|
||||
const char *version;
|
||||
GLint i;
|
||||
|
||||
version = (const char *) glGetString(GL_VERSION);
|
||||
if (version[0] != '2' || version[1] != '.') {
|
||||
printf("Warning: this program expects OpenGL 2.0\n");
|
||||
/*exit(1);*/
|
||||
}
|
||||
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
|
||||
|
||||
GetExtensionFuncs();
|
||||
|
||||
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
|
||||
ReadShader(vertShader, VertProgFile);
|
||||
|
||||
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
|
||||
ReadShader(fragShader, FragProgFile);
|
||||
|
||||
program = glCreateProgram_func();
|
||||
glAttachShader_func(program, fragShader);
|
||||
glAttachShader_func(program, vertShader);
|
||||
glLinkProgram_func(program);
|
||||
CheckLink(program);
|
||||
glUseProgram_func(program);
|
||||
|
||||
assert(glIsProgram_func(program));
|
||||
assert(glIsShader_func(fragShader));
|
||||
assert(glIsShader_func(vertShader));
|
||||
|
||||
assert(glGetError() == 0);
|
||||
|
||||
CheckError(__LINE__);
|
||||
|
||||
for (i = 0; Uniforms[i].name; i++) {
|
||||
Uniforms[i].location
|
||||
= glGetUniformLocation_func(program, Uniforms[i].name);
|
||||
printf("Uniform %s location: %d\n", Uniforms[i].name,
|
||||
Uniforms[i].location);
|
||||
switch (Uniforms[i].size) {
|
||||
case 1:
|
||||
glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
|
||||
break;
|
||||
case 2:
|
||||
glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
|
||||
break;
|
||||
case 3:
|
||||
glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
|
||||
break;
|
||||
case 4:
|
||||
glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
CheckError(__LINE__);
|
||||
|
||||
tangentAttrib = glGetAttribLocation_func(program, "Tangent");
|
||||
printf("Tangent Attrib: %d\n", tangentAttrib);
|
||||
|
||||
assert(tangentAttrib >= 0);
|
||||
|
||||
CheckError(__LINE__);
|
||||
|
||||
glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glColor3f(1, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ParseOptions(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-fs") == 0) {
|
||||
FragProgFile = argv[i+1];
|
||||
}
|
||||
else if (strcmp(argv[i], "-vs") == 0) {
|
||||
VertProgFile = argv[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
glutInit(&argc, argv);
|
||||
glutInitWindowPosition( 0, 0);
|
||||
glutInitWindowSize(400, 400);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
||||
win = glutCreateWindow(argv[0]);
|
||||
glutReshapeFunc(Reshape);
|
||||
glutKeyboardFunc(Key);
|
||||
glutSpecialFunc(SpecialKey);
|
||||
glutDisplayFunc(Redisplay);
|
||||
ParseOptions(argc, argv);
|
||||
Init();
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
316
progs/glsl/toyball.c
Normal file
316
progs/glsl/toyball.c
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
/**
|
||||
* "Toy Ball" shader demo. Uses the example shaders from
|
||||
* chapter 11 of the OpenGL Shading Language "orange" book.
|
||||
* 16 Jan 2007
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/glext.h>
|
||||
#include "extfuncs.h"
|
||||
|
||||
|
||||
static char *FragProgFile = "CH11-toyball.frag.txt";
|
||||
static char *VertProgFile = "CH11-toyball.vert.txt";
|
||||
|
||||
/* program/shader objects */
|
||||
static GLuint fragShader;
|
||||
static GLuint vertShader;
|
||||
static GLuint program;
|
||||
|
||||
|
||||
struct uniform_info {
|
||||
const char *name;
|
||||
GLuint size;
|
||||
GLint location;
|
||||
GLfloat value[4];
|
||||
};
|
||||
|
||||
static struct uniform_info Uniforms[] = {
|
||||
{ "LightDir", 4, -1, { 0.57737, 0.57735, 0.57735, 0.0 } },
|
||||
{ "HVector", 4, -1, { 0.32506, 0.32506, 0.88808, 0.0 } },
|
||||
{ "BallCenter", 4, -1, { 0.0, 0.0, 0.0, 1.0 } },
|
||||
{ "SpecularColor", 4, -1, { 0.4, 0.4, 0.4, 60.0 } },
|
||||
{ "Red", 4, -1, { 0.6, 0.0, 0.0, 1.0 } },
|
||||
{ "Blue", 4, -1, { 0.0, 0.3, 0.6, 1.0 } },
|
||||
{ "Yellow", 4, -1, { 0.6, 0.5, 0.0, 1.0 } },
|
||||
{ "HalfSpace0", 4, -1, { 1.0, 0.0, 0.0, 0.2 } },
|
||||
{ "HalfSpace1", 4, -1, { 0.309016994, 0.951056516, 0.0, 0.2 } },
|
||||
{ "HalfSpace2", 4, -1, { -0.809016994, 0.587785252, 0.0, 0.2 } },
|
||||
{ "HalfSpace3", 4, -1, { -0.809016994, -0.587785252, 0.0, 0.2 } },
|
||||
{ "HalfSpace4", 4, -1, { 0.309116994, -0.951056516, 0.0, 0.2 } },
|
||||
{ "InOrOutInit", 1, -1, { -3.0, 0, 0, 0 } },
|
||||
{ "StripeWidth", 1, -1, { 0.3, 0, 0, 0 } },
|
||||
{ "FWidth", 1, -1, { 0.005, 0, 0, 0 } },
|
||||
{ NULL, 0, 0, { 0, 0, 0, 0 } }
|
||||
};
|
||||
|
||||
static GLint win = 0;
|
||||
|
||||
static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
|
||||
|
||||
|
||||
static void
|
||||
Redisplay(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
|
||||
glRotatef(zRot, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
glutSolidSphere(2.0, 20, 10);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glFinish();
|
||||
glFlush();
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Reshape(int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -15.0f);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CleanUp(void)
|
||||
{
|
||||
glDeleteShader_func(fragShader);
|
||||
glDeleteShader_func(vertShader);
|
||||
glDeleteProgram_func(program);
|
||||
glutDestroyWindow(win);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Key(unsigned char key, int x, int y)
|
||||
{
|
||||
const GLfloat step = 2.0;
|
||||
(void) x;
|
||||
(void) y;
|
||||
|
||||
switch(key) {
|
||||
case 'z':
|
||||
zRot += step;
|
||||
break;
|
||||
case 'Z':
|
||||
zRot -= step;
|
||||
break;
|
||||
case 27:
|
||||
CleanUp();
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
SpecialKey(int key, int x, int y)
|
||||
{
|
||||
const GLfloat step = 2.0;
|
||||
|
||||
(void) x;
|
||||
(void) y;
|
||||
|
||||
switch(key) {
|
||||
case GLUT_KEY_UP:
|
||||
xRot += step;
|
||||
break;
|
||||
case GLUT_KEY_DOWN:
|
||||
xRot -= step;
|
||||
break;
|
||||
case GLUT_KEY_LEFT:
|
||||
yRot -= step;
|
||||
break;
|
||||
case GLUT_KEY_RIGHT:
|
||||
yRot += step;
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
LoadAndCompileShader(GLuint shader, const char *text)
|
||||
{
|
||||
GLint stat;
|
||||
|
||||
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
|
||||
|
||||
glCompileShader_func(shader);
|
||||
|
||||
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetShaderInfoLog_func(shader, 1000, &len, log);
|
||||
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
printf("Shader compiled OK\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a shader from a file.
|
||||
*/
|
||||
static void
|
||||
ReadShader(GLuint shader, const char *filename)
|
||||
{
|
||||
const int max = 100*1000;
|
||||
int n;
|
||||
char *buffer = (char*) malloc(max);
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
n = fread(buffer, 1, max, f);
|
||||
printf("brick: read %d bytes from shader file %s\n", n, filename);
|
||||
if (n > 0) {
|
||||
buffer[n] = 0;
|
||||
LoadAndCompileShader(shader, buffer);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CheckLink(GLuint prog)
|
||||
{
|
||||
GLint stat;
|
||||
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetProgramInfoLog_func(prog, 1000, &len, log);
|
||||
fprintf(stderr, "Linker error:\n%s\n", log);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Link success!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Init(void)
|
||||
{
|
||||
const char *version;
|
||||
GLint i;
|
||||
|
||||
version = (const char *) glGetString(GL_VERSION);
|
||||
if (version[0] != '2' || version[1] != '.') {
|
||||
printf("Warning: this program expects OpenGL 2.0\n");
|
||||
/*exit(1);*/
|
||||
}
|
||||
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
|
||||
|
||||
GetExtensionFuncs();
|
||||
|
||||
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
|
||||
ReadShader(vertShader, VertProgFile);
|
||||
|
||||
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
|
||||
ReadShader(fragShader, FragProgFile);
|
||||
|
||||
program = glCreateProgram_func();
|
||||
glAttachShader_func(program, fragShader);
|
||||
glAttachShader_func(program, vertShader);
|
||||
glLinkProgram_func(program);
|
||||
CheckLink(program);
|
||||
glUseProgram_func(program);
|
||||
|
||||
assert(glIsProgram_func(program));
|
||||
assert(glIsShader_func(fragShader));
|
||||
assert(glIsShader_func(vertShader));
|
||||
|
||||
|
||||
for (i = 0; Uniforms[i].name; i++) {
|
||||
Uniforms[i].location
|
||||
= glGetUniformLocation_func(program, Uniforms[i].name);
|
||||
printf("Uniform %s location: %d\n", Uniforms[i].name,
|
||||
Uniforms[i].location);
|
||||
switch (Uniforms[i].size) {
|
||||
case 1:
|
||||
glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
|
||||
break;
|
||||
case 2:
|
||||
glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
|
||||
break;
|
||||
case 3:
|
||||
glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
|
||||
break;
|
||||
case 4:
|
||||
glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
assert(glGetError() == 0);
|
||||
|
||||
glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glColor3f(1, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ParseOptions(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-fs") == 0) {
|
||||
FragProgFile = argv[i+1];
|
||||
}
|
||||
else if (strcmp(argv[i], "-vs") == 0) {
|
||||
VertProgFile = argv[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
glutInit(&argc, argv);
|
||||
glutInitWindowPosition( 0, 0);
|
||||
glutInitWindowSize(400, 400);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
||||
win = glutCreateWindow(argv[0]);
|
||||
glutReshapeFunc(Reshape);
|
||||
glutKeyboardFunc(Key);
|
||||
glutSpecialFunc(SpecialKey);
|
||||
glutDisplayFunc(Redisplay);
|
||||
ParseOptions(argc, argv);
|
||||
Init();
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Add table
Reference in a new issue