Code covered by the BSD License  

Highlights from
OpenGL .NET Examples

image thumbnail
from OpenGL .NET Examples by Dirk-Jan Kroon
Matlab OpenGL .NET code and examples for R2009a and above

OpenGL_Matlab_Figure(varargin)
function varargout = OpenGL_Matlab_Figure(varargin)
% OPENGL_MATLAB_FIGURE M-file for OpenGL_Matlab_Figure.fig
%
% Function is written by D.Kroon University of Twente (April 2009)


% Edit the above text to modify the response to help OpenGL_Matlab_Figure

% Last Modified by GUIDE v2.5 11-Apr-2009 09:23:35

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @OpenGL_Matlab_Figure_OpeningFcn, ...
                   'gui_OutputFcn',  @OpenGL_Matlab_Figure_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before OpenGL_Matlab_Figure is made visible.
function OpenGL_Matlab_Figure_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to OpenGL_Matlab_Figure (see VARARGIN)

% Choose default command line output for OpenGL_Matlab_Figure
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes OpenGL_Matlab_Figure wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% Set the default options
defaultoptions=struct( ...
    'Width', 512, ...
    'Height', 512);

% Check the input options
if(~exist('options','var')), 
    options=defaultoptions; 
else
    tags = fieldnames(defaultoptions);
    for i=1:length(tags)
         if(~isfield(options,tags{i})),  options.(tags{i})=defaultoptions.(tags{i}); end
    end
    if(length(tags)~=length(fieldnames(options))), 
        warning('Render:unknownoption','unknown options found');
    end
end

% Set the Paint function
data.paint_function_name=varargin{1};

% The initial (Identity) viewmatrix 
viewmatrix=[1 0 0 0;0 1 0 0; 0 0 1 0;0 0 0 1];
    
% Use a struct as data container
data.viewmatrix=viewmatrix;
data.Width=options.Width;
data.Height=options.Height;
data.LastXY=[0 0];
data.zoom=2;
data.FirstRender=true;
data.mouse_button='';
data.handles=handles;
% Initialize render2texture objects
[data]=initializeRender2Texture(data);

% Store all data for this OpenGL window
setappdata(gcf,'data',data);
    
% Initialize window view matrix
setOpenGLViewingMatrix(data.viewmatrix,data.zoom,data.Width,data.Height);
% Render to framebuffer
render2framebuffer;
% Draw Polygons
eval([data.paint_function_name]);
% Swap buffers
refresh_screen;
    


function data=initializeRender2Texture(data)

% Add the needed Windows  Assemblies
NET.addAssembly('System');
NET.addAssembly('System.Windows.Forms');

% Make A new Form (.NET window)
Form1=System.Windows.Forms.Form;
Form1.Width=data.Width;
Form1.Height=data.Height;    
Form1.Visible=false;

% Make an simple Opengl Control for the .NET window
simpleOpenGlControl1 = Tao.Platform.Windows.SimpleOpenGlControl;

% Set all OpenGL Control parameters
simpleOpenGlControl1.AccumBits = 0; 
simpleOpenGlControl1.AutoCheckErrors = false;
simpleOpenGlControl1.AutoFinish = false;
simpleOpenGlControl1.AutoMakeCurrent = false;
simpleOpenGlControl1.AutoSwapBuffers = false;
simpleOpenGlControl1.BackColor = System.Drawing.Color.Black;
simpleOpenGlControl1.ColorBits = 32;
simpleOpenGlControl1.DepthBits = 24;
simpleOpenGlControl1.Location = System.Drawing.Point(1, 1);
simpleOpenGlControl1.Name = 'simpleOpenGlControl1';
simpleOpenGlControl1.Size = System.Drawing.Size(Form1.Width-17, Form1.Height-38);
simpleOpenGlControl1.StencilBits = 0;
simpleOpenGlControl1.TabIndex = 0;

% Initialize the Control
simpleOpenGlControl1.InitializeContexts();

% Add the control to the figure,
Form1.Controls.Add(simpleOpenGlControl1);

% Wait to initialize
pause(1)

% Allow to use GL functions without prefixing with Tao.Opengl.
import Tao.OpenGl.*

% Set texture sizes
TextureWidth = simpleOpenGlControl1.Size.Width;
TextureHeight = simpleOpenGlControl1.Size.Height;

% First Flus the openGL pipeline
Gl.glFlush();

% Generate Extern frame buffer id
FB_fbo=Gl.glGenFramebuffersEXT(1);

% Bind frame buffer id to extern
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, FB_fbo);

% Create the render buffer for the depth
FB_depthBuffer = Gl.glGenRenderbuffersEXT(1);
Gl.glBindRenderbufferEXT(Gl.GL_RENDERBUFFER_EXT, FB_depthBuffer);

% Reserve memory to store the buffer
Gl.glRenderbufferStorageEXT(Gl.GL_RENDERBUFFER_EXT, Gl.GL_DEPTH_COMPONENT, TextureWidth, TextureHeight);

% Now setup a texture to render to
TextureID = Gl.glGenTextures(1);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, TextureID);

% Set texture parameters 
Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);
Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);

% Set type of texture data
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, TextureWidth, TextureHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, []);

% And attach it to the FBO so we can render to it
Gl.glFramebufferTexture2DEXT(Gl.GL_FRAMEBUFFER_EXT, Gl.GL_COLOR_ATTACHMENT0_EXT, Gl.GL_TEXTURE_2D, TextureID, 0);

% Attach the depth render buffer to the FBO as it's depth attachment
Gl.glFramebufferRenderbufferEXT(Gl.GL_FRAMEBUFFER_EXT, Gl.GL_DEPTH_ATTACHMENT_EXT, Gl.GL_RENDERBUFFER_EXT, FB_depthBuffer);

status = Gl.glCheckFramebufferStatusEXT(Gl.GL_FRAMEBUFFER_EXT);
if (status ~= Gl.GL_FRAMEBUFFER_COMPLETE_EXT)
  error('The card may not be compatible with Framebuffers. Try another bit depth.');
end

% Unbind the FBO for now
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, 0); 

% (Store also OpenGL control object, otherwise listeners are disposed)
setappdata(gcf,'Control',simpleOpenGlControl1);
setappdata(gcf,'Form',Form1);

% Set data
data.TextureWidth=TextureWidth;
data.TextureHeight=TextureHeight;
data.FB_fbo=FB_fbo;
data.TextureID=TextureID;

function refresh_screen
import Tao.OpenGl.*
    data=getappdata(gcf,'data');

    % Swap buffer to the new rendered image
    simpleOpenGlControl1=getappdata(gcf,'Control');
    simpleOpenGlControl1.SwapBuffers(); 
    
    % Get the texture data
    texturedata = NET.createArray('System.Byte',data.TextureWidth * data.TextureHeight* 4);
    Gl.glEnable(Gl.GL_TEXTURE_2D);
    Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID);
    Gl.glGetTexImage(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, texturedata );
    Gl.glDisable(Gl.GL_TEXTURE_2D);

    % Convert texture data to Matlab image
    I=reshape(double(texturedata),[4 data.TextureWidth data.TextureHeight]);
    I=permute(I,[3 2 1]);
    I=I(:,:,1:3)/255;
    
    
    % Show the image
    if(data.FirstRender)
        data.imshow_handle=imshow(I);
        set(get(data.handles.axes1,'Children'),'ButtonDownFcn','OpenGL_Matlab_Figure(''axes1_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
        setappdata(gcf,'data',data);
    else
        set(data.imshow_handle,'Cdata',I);
        drawnow('expose')
    end



function setOpenGLViewingMatrix(viewmatrix,zoom,Width,Height)
% Allow to use GL functions without prefixing with Tao.Opengl.
import Tao.OpenGl.*

    % Set projection matrix
    Gl.glMatrixMode(Gl.GL_PROJECTION);
    Gl.glLoadIdentity();
   
    % Screen coordinates are set from 0,0 to 1,1
    tx=0.5*(2^zoom);
    ty=0.5*(2^zoom)*(Height/Width);
    Gl.glOrtho(0.5-tx, 0.5+tx, 0.5-ty, 0.5+ty, 0.001,5);
    
    % Align viewmatrix before the viewer screen
    viewmatrix=TranslateMatrix([0.5 0.5 -2.5])*viewmatrix;
    viewarray=NET.convertArray(viewmatrix(:), 'System.Double',16);
    Gl.glMultMatrixd(viewarray);
    
    % The Model matrix (no changes)
    Gl.glMatrixMode(Gl.GL_MODELVIEW);
    Gl.glLoadIdentity();

    % Initial Depth buffer value of all pixels
    Gl.glClearDepth(1);

    % Set to default Depth Testing
    Gl.glDepthFunc(Gl.GL_LEQUAL);  
    
    % Set viewport to fit opengl window
    Gl.glViewport(0, 0, Width, Height);

% --- Outputs from this function are returned to the command line.
function varargout = OpenGL_Matlab_Figure_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on mouse press over axes background.
function axes1_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to axes1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getappdata(gcf,'data');
data.mouse_button=get(handles.figure1,'SelectionType');
data.LastXY=data.XY;
setappdata(gcf,'data',data);

% --- Executes when user attempts to close figure1.
function figure1_CloseRequestFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Delete OpenGL Control
simpleOpenGlControl1=getappdata(gcf,'Control');
simpleOpenGlControl1.Dispose();

% Remove Form and Window data
rmappdata(gcf,'Control');
rmappdata(gcf,'Form');
rmappdata(gcf,'data');

% Hint: delete(hObject) closes the figure
delete(hObject);

        
        

% --- Executes on mouse motion over figure - except title and menu.
function figure1_WindowButtonMotionFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getappdata(gcf,'data');
data.XY=get(0, 'PointerLocation');
diffXY=data.XY-data.LastXY;        
switch(data.mouse_button)
    case 'open'
    case 'normal'
        R=RotationMatrix([diffXY(2) diffXY(1) 0]);
        data.viewmatrix(1:3,1:3)=R(1:3,1:3)*data.viewmatrix(1:3,1:3);
    case 'extend'
        t=[data.zoom*diffXY(1)/data.Width -data.zoom*diffXY(2)/data.Width 0];
        T=[0 0 0 t(1);
           0 0 0 t(2);
           0 0 0 t(3);
           0 0 0 0];
         data.viewmatrix=data.viewmatrix+T;
    case 'alt'
        data.zoom=data.zoom+8*diffXY(2)/data.Width;
    otherwise
        setappdata(gcf,'data',data);
        return;
end
data.FirstRender=false;
setappdata(gcf,'data',data);

% Initialize window view matrix
setOpenGLViewingMatrix(data.viewmatrix,data.zoom,data.Width,data.Height);

% Render to framebuffer
render2framebuffer;

% Draw Polygons
eval([data.paint_function_name]);

% Swap buffers
refresh_screen;


function render2framebuffer()
% Render to frame buffer
import Tao.OpenGl.*
data=getappdata(gcf,'data');
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, data.FB_fbo);
Gl.glPushAttrib(Gl.GL_VIEWPORT_BIT);
Gl.glViewport(0, 0, data.TextureWidth, data.TextureHeight);

% --- Executes on mouse press over figure background, over a disabled or
% --- inactive control, or over an axes background.
function figure1_WindowButtonUpFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getappdata(gcf,'data');
data.mouse_button='';
setappdata(gcf,'data',data);

function M=ResizeMatrix(s)
	M=[s(1) 0 0 0;
	   0 s(2) 0 0;
	   0 0 s(3) 0;
	   0 0 0 1];
	   
function R=RotationMatrix(r)
% Determine the rotation matrix (View matrix) for rotation angles xyz ...
    Rx=[1 0 0 0; 0 cosd(r(1)) -sind(r(1)) 0; 0 sind(r(1)) cosd(r(1)) 0; 0 0 0 1];
    Ry=[cosd(r(2)) 0 sind(r(2)) 0; 0 1 0 0; -sind(r(2)) 0 cosd(r(2)) 0; 0 0 0 1];
    Rz=[cosd(r(3)) -sind(r(3)) 0 0; sind(r(3)) cosd(r(3)) 0 0; 0 0 1 0; 0 0 0 1];
    R=Rx*Ry*Rz;

function M=TranslateMatrix(t)
	M=[1 0 0 t(1);
	   0 1 0 t(2);
	   0 0 1 t(3);
	   0 0 0 1];

Contact us at files@mathworks.com