Compare commits
5 Commits
a79dfe064c
...
48e78fedda
Author | SHA1 | Date |
---|---|---|
ktyl | 48e78fedda | |
ktyl | 7367a2abaf | |
ktyl | 0f21b16ed7 | |
ktyl | b3c5440736 | |
ktyl | 2fd7797e7d |
7
launch
7
launch
|
@ -1,12 +1,13 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
executable="$1"
|
executable="$1"
|
||||||
|
options="$2"
|
||||||
prime="prime-run"
|
prime="prime-run"
|
||||||
|
|
||||||
if command -v $prime &> /dev/null
|
if command -v $prime &> /dev/null
|
||||||
then
|
then
|
||||||
echo "launching $executable with nvidia prime offloading"
|
echo "launching $executable $options with nvidia prime offloading"
|
||||||
$prime $executable
|
$prime $executable $options
|
||||||
else
|
else
|
||||||
$executable
|
$executable $options
|
||||||
fi
|
fi
|
||||||
|
|
6
makefile
6
makefile
|
@ -46,7 +46,11 @@ clean:
|
||||||
-rm -r $(BIN_DIR)
|
-rm -r $(BIN_DIR)
|
||||||
-rm */*.o
|
-rm */*.o
|
||||||
|
|
||||||
|
# TODO: extract run-* out to like, python scripts? arguments can be implemented with argparse to
|
||||||
|
# manage simple interface with C binary
|
||||||
run: $(TARGET)
|
run: $(TARGET)
|
||||||
$(LAUNCH) $(TARGET)
|
$(LAUNCH) $(TARGET) 1.0
|
||||||
|
run-converge: $(TARGET)
|
||||||
|
$(LAUNCH) $(TARGET) 0.0
|
||||||
|
|
||||||
.PHONY: run clean
|
.PHONY: run clean
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const float INF = 50.0;
|
const float INF = 30.0;
|
||||||
const float PI = 3.14159;
|
const float PI = 3.14159;
|
||||||
const float E = 2.71828;
|
const float E = 2.71828;
|
||||||
const int BOUNCES = 4;
|
const int BOUNCES = 5;
|
||||||
|
|
||||||
// materials
|
// materials
|
||||||
const int MAT_SKY = -1;
|
const int MAT_SKY = -1;
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
float getLinearDepth(float distance)
|
||||||
|
{
|
||||||
|
return distance/INF;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getLogarithmicDepth(float distance)
|
||||||
|
{
|
||||||
|
// n roughly correlates to steepness of log curve
|
||||||
|
// TODO: what does this mean in mathematical terms??
|
||||||
|
float n = 4;
|
||||||
|
float f = INF;
|
||||||
|
float z = distance;
|
||||||
|
|
||||||
|
// logarithmic depth
|
||||||
|
return max(0,log(z*pow(E,n)/f)/n);
|
||||||
|
}
|
|
@ -33,7 +33,7 @@ void intersectPlane(Ray ray, inout RayHit bestHit, vec3 p, vec3 normal)
|
||||||
bestHit.distance = t;
|
bestHit.distance = t;
|
||||||
bestHit.position = ray.origin + t*ray.direction;
|
bestHit.position = ray.origin + t*ray.direction;
|
||||||
bestHit.normal = normal;
|
bestHit.normal = normal;
|
||||||
bestHit.albedo = vec3(1.0,1.0,1.0);
|
bestHit.albedo = vec3(1.0,.4,.4);
|
||||||
bestHit.material = MAT_LAMBERT;
|
bestHit.material = MAT_LAMBERT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ struct Ray
|
||||||
vec3 origin;
|
vec3 origin;
|
||||||
vec3 direction;
|
vec3 direction;
|
||||||
vec3 energy;
|
vec3 energy;
|
||||||
|
float distance;
|
||||||
};
|
};
|
||||||
Ray createRay(vec3 origin, vec3 direction)
|
Ray createRay(vec3 origin, vec3 direction)
|
||||||
{
|
{
|
||||||
|
@ -11,6 +12,7 @@ Ray createRay(vec3 origin, vec3 direction)
|
||||||
ray.origin = origin;
|
ray.origin = origin;
|
||||||
ray.direction = direction;
|
ray.direction = direction;
|
||||||
ray.energy = vec3(1.0,1.0,1.0);
|
ray.energy = vec3(1.0,1.0,1.0);
|
||||||
|
ray.distance = 0;
|
||||||
|
|
||||||
return ray;
|
return ray;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
RayHit trace(Ray ray)
|
RayHit trace(inout Ray ray)
|
||||||
{
|
{
|
||||||
RayHit hit = createRayHit();
|
RayHit hit = createRayHit();
|
||||||
|
|
||||||
Sphere s;
|
// floor
|
||||||
s.cr = vec4(0.0,0.0,0.0,5.0);
|
|
||||||
s.albedo = vec3(1.0,0.0,0.0);
|
|
||||||
s.material = MAT_CHROME;
|
|
||||||
intersectSphere(ray, hit, s);
|
|
||||||
|
|
||||||
intersectPlane(ray, hit, vec3(0.0,-1.5,0.0),vec3(0.0,1.0,0.0));
|
intersectPlane(ray, hit, vec3(0.0,-1.5,0.0),vec3(0.0,1.0,0.0));
|
||||||
|
|
||||||
|
// spheres
|
||||||
for (int i = 0; i < _activeSpheres; i++)
|
for (int i = 0; i < _activeSpheres; i++)
|
||||||
{
|
{
|
||||||
intersectSphere(ray, hit, _spheres[i]);
|
intersectSphere(ray, hit, _spheres[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ray.distance += hit.distance * float(hit.distance < INF);
|
||||||
|
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ uniform vec3 _skyColor = vec3(0.68,0.85,0.9);
|
||||||
// scene.glsl includes scene trace function
|
// scene.glsl includes scene trace function
|
||||||
#include scene.glsl
|
#include scene.glsl
|
||||||
#include lighting.glsl
|
#include lighting.glsl
|
||||||
|
#include depth.glsl
|
||||||
|
|
||||||
vec3 shade(inout Ray ray, RayHit hit)
|
vec3 shade(inout Ray ray, RayHit hit)
|
||||||
{
|
{
|
||||||
|
@ -77,14 +78,25 @@ void main()
|
||||||
int bounces = (1-sky) * BOUNCES;
|
int bounces = (1-sky) * BOUNCES;
|
||||||
pixel.xyz = mix(pixel.xyz, _skyColor, sky);
|
pixel.xyz = mix(pixel.xyz, _skyColor, sky);
|
||||||
|
|
||||||
// trace the rays path around the scene
|
// sample
|
||||||
for (int j = 0; j < bounces; j++)
|
int samples = 2;
|
||||||
|
for (int i = 0; i < samples; i++)
|
||||||
{
|
{
|
||||||
RayHit hit = trace(ray);
|
float sampleDepth = 0;
|
||||||
|
|
||||||
pixel.xyz += ray.energy * shade(ray, hit);
|
// trace the ray's path around the scene
|
||||||
|
for (int j = 0; j < bounces; j++)
|
||||||
|
{
|
||||||
|
RayHit hit = trace(ray);
|
||||||
|
|
||||||
if (length(ray.energy) < 0.001) break;
|
depth = getLogarithmicDepth(ray.distance);
|
||||||
|
|
||||||
|
pixel.xyz += ray.energy * shade(ray, hit);
|
||||||
|
|
||||||
|
if (length(ray.energy) < 0.001) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
depth += sampleDepth / float(samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
pixel.xyz = mix(pixel.xyz, vec3(1.0), depth);
|
pixel.xyz = mix(pixel.xyz, vec3(1.0), depth);
|
||||||
|
|
|
@ -18,6 +18,7 @@ layout (rgba32f, binding = 3) writeonly uniform image2D g1_output;
|
||||||
#include camera.glsl
|
#include camera.glsl
|
||||||
#include image.glsl
|
#include image.glsl
|
||||||
#include scene.glsl
|
#include scene.glsl
|
||||||
|
#include depth.glsl
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
@ -34,18 +35,7 @@ void main()
|
||||||
Ray ray = createCameraRay(uv);
|
Ray ray = createCameraRay(uv);
|
||||||
RayHit hit = trace(ray);
|
RayHit hit = trace(ray);
|
||||||
|
|
||||||
// n roughly correlates to steepness of log curve
|
float depth = getLogarithmicDepth(hit.distance);
|
||||||
// TODO: what does this mean in mathematical terms??
|
|
||||||
float n = 4;
|
|
||||||
float f = INF;
|
|
||||||
float z = hit.distance;
|
|
||||||
|
|
||||||
float depth;
|
|
||||||
// linear depth
|
|
||||||
//depth = z/f;
|
|
||||||
|
|
||||||
// logarithmic depth
|
|
||||||
depth = max(0,log(z*pow(E,n)/f)/n);
|
|
||||||
|
|
||||||
// pack normal into texture
|
// pack normal into texture
|
||||||
pixel.xyz = hit.normal*0.5+0.5;
|
pixel.xyz = hit.normal*0.5+0.5;
|
||||||
|
|
|
@ -2,10 +2,8 @@
|
||||||
|
|
||||||
const float FOVY = 90.0;
|
const float FOVY = 90.0;
|
||||||
|
|
||||||
void updateCameraUniforms(GLuint shaderProgram, float aspect)
|
void updateCameraUniforms(GLuint shaderProgram, float aspect, float t)
|
||||||
{
|
{
|
||||||
float t = now();
|
|
||||||
|
|
||||||
// wobble up dir
|
// wobble up dir
|
||||||
vec3 cdir, cright, cup;
|
vec3 cdir, cright, cup;
|
||||||
vec3 up = {0.1*sin(t),1.0,0.05*cos(0.5*t)};
|
vec3 up = {0.1*sin(t),1.0,0.05*cos(0.5*t)};
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
|
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
|
|
||||||
void updateCameraUniforms(GLuint shaderProgram, float aspect);
|
void updateCameraUniforms(GLuint shaderProgram, float aspect, float t);
|
||||||
|
|
|
@ -4,3 +4,8 @@ float now()
|
||||||
{
|
{
|
||||||
return (float)SDL_GetTicks() / 1000.0;
|
return (float)SDL_GetTicks() / 1000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float nowScaled(struct Epoch t)
|
||||||
|
{
|
||||||
|
return t.scale * now();
|
||||||
|
}
|
||||||
|
|
|
@ -2,5 +2,12 @@
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
// seconds since program start
|
struct Epoch
|
||||||
|
{
|
||||||
|
float scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
// real seconds since program start
|
||||||
float now();
|
float now();
|
||||||
|
// simulation seconds since program start
|
||||||
|
float nowScaled(struct Epoch e);
|
||||||
|
|
10
src/gfx.c
10
src/gfx.c
|
@ -174,16 +174,6 @@ void setVertexAttributes()
|
||||||
// color
|
// color
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, stride, (void*)(3*sizeof(float)));
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, stride, (void*)(3*sizeof(float)));
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// uv
|
// uv
|
||||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, stride, (void*)(6*sizeof(float)));
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, stride, (void*)(6*sizeof(float)));
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
|
|
46
src/main.c
46
src/main.c
|
@ -10,12 +10,13 @@
|
||||||
const int WIDTH = 420;
|
const int WIDTH = 420;
|
||||||
const int HEIGHT = 420;
|
const int HEIGHT = 420;
|
||||||
|
|
||||||
void updateUniforms(GLuint shaderProgram);
|
void updateUniforms(GLuint shaderProgram, float t);
|
||||||
|
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
|
|
||||||
struct Shaders shaders;
|
struct Shaders shaders;
|
||||||
struct Textures textures;
|
struct Textures textures;
|
||||||
|
struct Epoch epoch;
|
||||||
|
|
||||||
void initialise()
|
void initialise()
|
||||||
{
|
{
|
||||||
|
@ -32,8 +33,21 @@ void initialise()
|
||||||
createTextures(WIDTH, HEIGHT, shaders, &textures);
|
createTextures(WIDTH, HEIGHT, shaders, &textures);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
void parseArgs(int argc, char* argv[], struct Epoch* e)
|
||||||
{
|
{
|
||||||
|
// check we have the right number of arguments
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: oglc TIMESPEED\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sscanf(argv[1], "%f", &(e->scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
parseArgs(argc, argv, &epoch);
|
||||||
|
|
||||||
initialise();
|
initialise();
|
||||||
|
|
||||||
float start = now();
|
float start = now();
|
||||||
|
@ -41,6 +55,7 @@ int main()
|
||||||
for (frames = 0; !checkQuit(); frames++)
|
for (frames = 0; !checkQuit(); frames++)
|
||||||
{
|
{
|
||||||
GLuint shader;
|
GLuint shader;
|
||||||
|
float t = nowScaled(epoch);
|
||||||
|
|
||||||
// prepass
|
// prepass
|
||||||
// TODO: write output to different texture than main output
|
// TODO: write output to different texture than main output
|
||||||
|
@ -48,18 +63,17 @@ int main()
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, textures.g0);
|
glBindTexture(GL_TEXTURE_2D, textures.g0);
|
||||||
glUseProgram(shader);
|
glUseProgram(shader);
|
||||||
updateUniforms(shader);
|
updateUniforms(shader, t);
|
||||||
glDispatchCompute((GLuint)WIDTH, (GLuint)HEIGHT, 1);
|
glDispatchCompute((GLuint)WIDTH, (GLuint)HEIGHT, 1);
|
||||||
|
|
||||||
// make sure we're finished writing to the texture before trying to read it
|
// make sure we're finished writing to the texture before trying to read it
|
||||||
glMemoryBarrier(GL_ALL_BARRIER_BITS);
|
glMemoryBarrier(GL_ALL_BARRIER_BITS);
|
||||||
|
|
||||||
// dispatch compute shaders
|
|
||||||
shader = shaders.lighting;
|
shader = shaders.lighting;
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, textures.target);
|
glBindTexture(GL_TEXTURE_2D, textures.target);
|
||||||
glUseProgram(shader);
|
glUseProgram(shader);
|
||||||
updateUniforms(shader);
|
updateUniforms(shader, t);
|
||||||
//int loc = glGetUniformLocation(shader, "_g0");
|
//int loc = glGetUniformLocation(shader, "_g0");
|
||||||
//glUniform1i(loc, textures.g0);
|
//glUniform1i(loc, textures.g0);
|
||||||
glDispatchCompute((GLuint)WIDTH, (GLuint)HEIGHT, 1);
|
glDispatchCompute((GLuint)WIDTH, (GLuint)HEIGHT, 1);
|
||||||
|
@ -67,6 +81,18 @@ int main()
|
||||||
// make sure we're finished writing to the texture before trying to read it
|
// make sure we're finished writing to the texture before trying to read it
|
||||||
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
|
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
|
||||||
|
|
||||||
|
// TODO: frame blending
|
||||||
|
//
|
||||||
|
// before we get to our normal rendering pass we need to blend our samples
|
||||||
|
// across multiple frames. to do this, we should maintain an accumulation
|
||||||
|
// buffer where we can store pixel data while a new frame is being generated.
|
||||||
|
// this can be a collection of two buffers, where one is written to and the
|
||||||
|
// other is read from. to render a new frame, the newly sampled raw frame can
|
||||||
|
// be combined with data from the previous frame. by repeatedly taking the
|
||||||
|
// average over a large number of frames a cleaner image can be generated.
|
||||||
|
// this is most effective for static images, and will produce motion blur on
|
||||||
|
// a moving image.
|
||||||
|
|
||||||
// normal drawing pass
|
// normal drawing pass
|
||||||
shader = shaders.quad;
|
shader = shaders.quad;
|
||||||
glUseProgram(shader);
|
glUseProgram(shader);
|
||||||
|
@ -87,7 +113,7 @@ int main()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateUniforms(GLuint shaderProgram)
|
void updateUniforms(GLuint shaderProgram, float t)
|
||||||
{
|
{
|
||||||
// update random values
|
// update random values
|
||||||
vec4 seed =
|
vec4 seed =
|
||||||
|
@ -100,19 +126,17 @@ void updateUniforms(GLuint shaderProgram)
|
||||||
int loc = glGetUniformLocation(shaderProgram, "_seed");
|
int loc = glGetUniformLocation(shaderProgram, "_seed");
|
||||||
glUniform4fv(loc, 1, seed);
|
glUniform4fv(loc, 1, seed);
|
||||||
|
|
||||||
// update time
|
|
||||||
float t = now();
|
|
||||||
float sin_t = sin(t);
|
float sin_t = sin(t);
|
||||||
loc = glGetUniformLocation(shaderProgram, "_t");
|
loc = glGetUniformLocation(shaderProgram, "_t");
|
||||||
glUniform4f(loc, t, sin_t, (1.0 + sin_t)*0.5, 0.0f);
|
glUniform4f(loc, t, sin_t, (1.0 + sin_t)*0.5, 0.0f);
|
||||||
|
|
||||||
// update camera
|
// update camera
|
||||||
float aspect = (float)WIDTH/(float)HEIGHT;
|
float aspect = (float)WIDTH/(float)HEIGHT;
|
||||||
updateCameraUniforms(shaderProgram, aspect);
|
updateCameraUniforms(shaderProgram, aspect, t);
|
||||||
|
|
||||||
// make and update spheres
|
// make and update spheres
|
||||||
const int sphereCount = 42;
|
const int sphereCount = 41;
|
||||||
struct Sphere spheres[sphereCount];
|
struct Sphere spheres[sphereCount];
|
||||||
makeSpheres(spheres, sphereCount);
|
makeSpheres(spheres, sphereCount, t);
|
||||||
updateSphereUniforms(shaderProgram, spheres, sphereCount);
|
updateSphereUniforms(shaderProgram, spheres, sphereCount);
|
||||||
}
|
}
|
||||||
|
|
36
src/sphere.c
36
src/sphere.c
|
@ -1,9 +1,7 @@
|
||||||
#include "sphere.h"
|
#include "sphere.h"
|
||||||
|
|
||||||
void makeSpheres(struct Sphere *spheres, int count)
|
void makeSpheres(struct Sphere *spheres, int count, float t)
|
||||||
{
|
{
|
||||||
//float t = time();
|
|
||||||
|
|
||||||
vec3 albedos[] =
|
vec3 albedos[] =
|
||||||
{
|
{
|
||||||
{0.0,0.0,1.0},
|
{0.0,0.0,1.0},
|
||||||
|
@ -15,21 +13,33 @@ void makeSpheres(struct Sphere *spheres, int count)
|
||||||
{1.0,1.0,1.0}
|
{1.0,1.0,1.0}
|
||||||
};
|
};
|
||||||
|
|
||||||
// distance from center
|
|
||||||
float d = 6.0;
|
|
||||||
float radius = 0.5;
|
|
||||||
float x;
|
|
||||||
vec3 sc = {0.0,0.0,1.0};
|
vec3 sc = {0.0,0.0,1.0};
|
||||||
|
|
||||||
float t = now();
|
int sphereIdx = 0;
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
|
// a shiny sphere in the middle which bobs around
|
||||||
|
int middleSpheres = 1;
|
||||||
|
sc[0] = 2.5*sin(t*2.67);
|
||||||
|
sc[1] = 1.5+sin(t*1.09);
|
||||||
|
sc[2] = 2.5*cos(-t*2.13);
|
||||||
|
float radius = 1.7;
|
||||||
|
vec3 col = {0.0,0.0,0.0};
|
||||||
|
spheres[sphereIdx++] = makeSphere(sc,radius,col,1);
|
||||||
|
|
||||||
|
// rainbow spheres
|
||||||
|
int rainbowSpheres = count - middleSpheres;
|
||||||
|
// distance from center
|
||||||
|
float d = 6.0;
|
||||||
|
radius = 0.5;
|
||||||
|
float x;
|
||||||
|
for (int i = 0; i < rainbowSpheres; i++)
|
||||||
{
|
{
|
||||||
x = 2.0*CGLM_PI * (float)i/(float)count;
|
x = 2.0*CGLM_PI * (float)i/(float)rainbowSpheres;
|
||||||
sc[0] = sin(x)*d;
|
sc[0] = sin(x)*d;
|
||||||
sc[1] = sin(x*3.0-5.0*sin(t));
|
sc[1] = sin(x*3.0-5.0*sin(t));
|
||||||
sc[2] = cos(x)*d;
|
sc[2] = cos(x)*d;
|
||||||
|
|
||||||
float ic = i/(float)count*CGLM_PI*2.0;
|
float ic = i/(float)rainbowSpheres*CGLM_PI*2.0;
|
||||||
float r = sin(ic);
|
float r = sin(ic);
|
||||||
float g = sin(ic+CGLM_PI/1.5);
|
float g = sin(ic+CGLM_PI/1.5);
|
||||||
float b = sin(ic+2.0*CGLM_PI/1.5);
|
float b = sin(ic+2.0*CGLM_PI/1.5);
|
||||||
|
@ -38,8 +48,8 @@ void makeSpheres(struct Sphere *spheres, int count)
|
||||||
glm_vec3_scale(col, 0.5, col);
|
glm_vec3_scale(col, 0.5, col);
|
||||||
glm_vec3_adds(col, 0.5, col);
|
glm_vec3_adds(col, 0.5, col);
|
||||||
|
|
||||||
int material = i % 2 == 0;
|
int material = i % 2;
|
||||||
spheres[i] = makeSphere(sc,radius,col,material);
|
spheres[sphereIdx++] = makeSphere(sc,radius,col,material);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct Sphere
|
||||||
int material;
|
int material;
|
||||||
};
|
};
|
||||||
|
|
||||||
void makeSpheres(struct Sphere *spheres, int count);
|
void makeSpheres(struct Sphere *spheres, int count, float t);
|
||||||
struct Sphere makeSphere(vec3 center, float radius, vec3 albedo, int material);
|
struct Sphere makeSphere(vec3 center, float radius, vec3 albedo, int material);
|
||||||
//void updateSphereUniform(GLuint shaderProgram, struct Sphere sphere);
|
//void updateSphereUniform(GLuint shaderProgram, struct Sphere sphere);
|
||||||
void updateSphereUniforms(GLuint shaderProgram, struct Sphere *spheres, int count);
|
void updateSphereUniforms(GLuint shaderProgram, struct Sphere *spheres, int count);
|
||||||
|
|
Loading…
Reference in New Issue