Grid of rotating cubes (how to convert?)
Posted: Sat Jun 23, 2018 11:34 am
Would someone know how to convert this little OpenGL demo (by Peter Scarfe) to PB?
I'm not sure what to do with the meshgrid and linspace functions...
And if you have spare time, make each cube a different (random) color
See the result at: http://peterscarfe.com/rotatingcubesdemo.html
I'm not sure what to do with the meshgrid and linspace functions...
And if you have spare time, make each cube a different (random) color
See the result at: http://peterscarfe.com/rotatingcubesdemo.html
Code: Select all
% Clear the workspace
close all;
clearvars;
sca;
% Here we call some default settings for setting up Psychtoolbox
PsychDefaultSetup(2);
% Skip sync tests for this demo in case people are using a defective
% system. This is for demo purposes only.
Screen('Preference', 'SkipSyncTests', 2);
% Find the screen to use for display
screenid = max(Screen('Screens'));
% Initialise OpenGL
InitializeMatlabOpenGL;
% Open the main window with multi-sampling for anti-aliasing
[window, windowRect] = PsychImaging('OpenWindow', screenid, 0, [],...
32, 2, [], 6, []);
% Query the frame duration
ifi = Screen('GetFlipInterval', window);
% Start the OpenGL context (you have to do this before you issue OpenGL
% commands such as we are using here)
Screen('BeginOpenGL', window);
% For this demo we will assume our screen is 30cm in height. The units are
% essentially arbitary with OpenGL as it is all about ratios. But it is
% nice to define things in normal scale numbers
ar = windowRect(3) / windowRect(4);
screenHeight = 30;
screenWidth = screenHeight * ar;
% Enable lighting
glEnable(GL.LIGHTING);
% Define a local light source
glEnable(GL.LIGHT0);
% Enable proper occlusion handling via depth tests
glEnable(GL.DEPTH_TEST);
% Lets set up a projection matrix, the projection matrix defines how images
% in our 3D simulated scene are projected to the images on our 2D monitor
glMatrixMode(GL.PROJECTION);
glLoadIdentity;
% Calculate the field of view in the y direction assuming a distance to the
% objects of 100cm
dist = 100;
angle = 2 * atand(screenHeight / dist);
% Set up our perspective projection. This is defined by our field of view
% (here given by the variable "angle") and the aspect ratio of our frustum
% (our screen) and two clipping planes. These define the minimum and
% maximum distances allowable here 0.1cm and 200cm.
gluPerspective(angle, ar, 0.1, 200);
% Setup modelview matrix: This defines the position, orientation and
% looking direction of the virtual camera that will be look at our scene.
glMatrixMode(GL.MODELVIEW);
glLoadIdentity;
% Our point lightsource is at position (x,y,z) == (1,2,3)
glLightfv(GL.LIGHT0, GL.POSITION, [1 2 3 0]);
% Location of the camera is at the origin
cam = [0 0 0];
% Set our camera to be looking directly down the Z axis (depth) of our
% coordinate system
fix = [0 0 -100];
% Define "up"
up = [0 1 0];
% Here we set up the attributes of our camera using the variables we have
% defined in the last three lines of code
gluLookAt(cam(1), cam(2), cam(3), fix(1), fix(2), fix(3), up(1), up(2), up(3));
% Set background color to 'black' (the 'clear' color)
glClearColor(0, 0, 0, 0);
% Clear out the backbuffer
glClear;
% Change the light reflection properties of the material to blue. We could
% force a color to the cubes or do this.
glMaterialfv(GL.FRONT_AND_BACK,GL.AMBIENT, [0.0 0.0 1.0 1]);
glMaterialfv(GL.FRONT_AND_BACK,GL.DIFFUSE, [0.0 0.0 1.0 1]);
% End the OpenGL context now that we have finished setting things up
Screen('EndOpenGL', window);
% Setup the positions of the spheres using the mexhgrid command
[cubeX, cubeY] = meshgrid(linspace(-25, 25, 10), linspace(-20, 20, 8));
[s1, s2] = size(cubeX);
cubeX = reshape(cubeX, 1, s1 * s2);
cubeY = reshape(cubeY, 1, s1 * s2);
% Define the intial rotation angles of our cubes
rotaX = rand(1, length(cubeX)) .* 360;
rotaY = rand(1, length(cubeX)) .* 360;
rotaZ = rand(1, length(cubeX)) .* 360;
% Now we define how many degrees our cubes will rotated per second and per
% frame. Note we use Degrees here (not Radians)
degPerSec = 180;
degPerFrame = degPerSec * ifi;
% Get a time stamp with a flip
vbl = Screen('Flip', window);
% Set the frames to wait to one
waitframes = 1;
while ~KbCheck
% Begin the OpenGL context now we want to issue OpenGL commands again
Screen('BeginOpenGL', window);
% To start with we clear everything
glClear;
% Draw all the cubes
for i = 1:1:length(cubeX)
% Push the matrix stack
glPushMatrix;
% Translate the cube in xyz
glTranslatef(cubeX(i), cubeY(i), -dist);
% Rotate the cube randomly in xyz
glRotatef(rotaX(i), 1, 0, 0);
glRotatef(rotaY(i), 0, 1, 0);
glRotatef(rotaZ(i), 0, 0, 1);
% Draw the solid cube
glutSolidCube(3);
% Pop the matrix stack for the next cube
glPopMatrix;
end
% End the OpenGL context now that we have finished doing OpenGL stuff.
% This hands back control to PTB
Screen('EndOpenGL', window);
% Show rendered image at next vertical retrace
vbl = Screen('Flip', window, vbl + (waitframes - 0.5) * ifi);
% Rotate the cubes for the next drawing loop
rotaX = rotaX + degPerFrame;
rotaY = rotaY + degPerFrame;
rotaZ = rotaZ + degPerFrame;
end
% Shut the screen down
sca;