今天,我和我的同事們喝酒,經過五年的啤酒和一些tequillas我發現這問題和想法,「有在!」所以我掙扎了一會兒,但後來我發現了一個使用MEX的簡單解決方案。我推斷,由最後一個窗口創建的OpenGL上下文可以保持活動狀態,因此如果腳本運行在同一個線程中,則可以從「C」訪問。
我創建了一個簡單的「C」程序它調用一個matlab函數,稱爲「testofmyfilter」圖表的過濾器(這是我在手的唯一腳本)的頻率響應。這是使用OpenGL渲染的。然後該程序使用glGetViewport()和glReadPixels()來訪問OpenGL緩衝區。然後它創建一個矩陣,用深度值填充它,並將其傳遞給第二個函數,名爲「trytodisplaydepthmap」。它只是使用imshow函數顯示深度圖。請注意,MEX函數也可以返回值,所以後處理可能不必是另一個函數,但我沒有任何狀態能夠理解它是如何完成的。儘管如此,應該是微不足道的。我今天第一次與MEX合作。
無需進一步的延遲,有源代碼我使用:
testofmyfilter.m
imp = zeros(10000,1);
imp(5000) = 1;
% impulse
[bwb,bwa] = butter(3, 0.1, 'high');
b = filter(bwb, bwa, imp);
% filter impulse by the filter
fs = 44100; % sampling frequency (all frequencies are relative to fs)
frequency_response=fft(b); % calculate response (complex numbers)
amplitude_response=20*log10(abs(frequency_response)); % calculate module of the response, convert to dB
frequency_axis=(0:length(b)-1)*fs/length(b); % generate frequency values for each response value
min_f=2;
max_f=fix(length(b)/2)+1; % min, max frequency
figure(1);
lighting gouraud
set(gcf,'Renderer','OpenGL')
semilogx(frequency_axis(min_f:max_f),amplitude_response(min_f:max_f),'r-') % plot with logarithmic axis using red line
axis([frequency_axis(min_f) frequency_axis(max_f) -90 10]) % set axis limits
xlabel('frequency [Hz]');
ylabel('amplitude [dB]'); % legend
grid on % draw grid
test.c的
//You can include any C libraries that you normally use
#include "windows.h"
#include "stdio.h"
#include "math.h"
#include "mex.h" //--This one is required
extern WINAPI void glGetIntegerv(int n_enum, int *p_value);
extern WINAPI void glReadPixels(int x,
int y,
int width,
int height,
int format,
int type,
void * data);
#define GL_VIEWPORT 0x0BA2
#define GL_DEPTH_COMPONENT 0x1902
#define GL_FLOAT 0x1406
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int viewport[4], i, x, y;
int colLen;
float *data;
double *matrix;
mxArray *arg[1];
mexCallMATLAB(0, NULL, 0, NULL, "testofmyfilter");
// call an .m file which creates OpenGL window and draws a plot inside
glGetIntegerv(GL_VIEWPORT, viewport);
printf("GL_VIEWPORT = [%d, %d, %d, %d]\n", viewport[0], viewport[1], viewport[2], viewport[3]);
// print viewport dimensions, should be [0, 0, m, n]
// where m and n are size of the GL window
data = (float*)malloc(viewport[2] * viewport[3] * sizeof(float));
glReadPixels(0, 0, viewport[2], viewport[3], GL_DEPTH_COMPONENT, GL_FLOAT, data);
// alloc data and read the depth buffer
/*for(i = 0; i < 10; ++ i)
printf("%f\n", data[i]);*/
// debug
arg[0] = mxCreateNumericMatrix(viewport[3], viewport[2], mxDOUBLE_CLASS, mxREAL);
matrix = mxGetPr(arg[0]);
colLen = mxGetM(arg[0]);
printf("0x%08x 0x%08x 0x%08x %d\n", data, arg[0], matrix, colLen); // debug
for(x = 0; x < viewport[2]; ++ x) {
for(y = 0; y < viewport[3]; ++ y)
matrix[x * colLen + y] = data[x + (viewport[3] - 1 - y) * viewport[2]];
}
// create matrix, copy data (this is stupid, but matlab switches
// rows/cols, also convert float to double - but OpenGL could have done that)
free(data);
// don't need this anymore
mexCallMATLAB(0, NULL, 1, arg, "trytodisplaydepthmap");
// pass the array to a function (returnig something from here
// is beyond my understanding of mex, but should be doable)
mxDestroyArray(arg[0]);
// cleanup
return;
}
trytodisplaydepthmap.m:
function [] = trytodisplaydepthmap(depthMap)
figure(2);
imshow(depthMap, []);
% see what's inside
保存所有的ESE到同一目錄,編譯test.c的與(鍵入Matlab的控制檯):
mex test.c Q:\MATLAB\R2008a\sys\lcc\lib\opengl32.lib
其中 「Q:\ MATLAB \ R2008a \ SYS \ LCC \ LIB \ opengl32.lib」 是路徑「opengl32 .lib「文件。
最後僅通過在MATLAB控制檯鍵入「測試」執行的這一切。它應該調出一個帶有濾波器頻率響應的窗口,以及另一個帶有深度緩衝區的窗口。請注意,在「C」代碼讀取深度緩衝區時,正面和背面緩衝區會被交換,因此可能需要兩次運行該腳本才能獲得任何結果(因此現在包含結果的前端緩衝區會再次與後端緩衝區交換,並且深度可以被讀出)。這可以通過「C」自動完成,或者你可以嘗試包括getframe(gcf);在腳本的結尾(也可以從OpenGL讀回,因此它會替換掉你的緩衝區,或者其他的東西)。
這適用於Matlab 7.6.0.324(R2008a)。腳本運行並吐出以下內容:
>>test
GL_VIEWPORT = [0, 0, 560, 419]
0x11150020 0x0bd39620 0x12b20030 419
當然它顯示圖像。請注意,深度緩衝區範圍取決於Matlab,並且可能相當高,因此,對生成的圖像的任何意義可能都不太直觀。
你總是可以試着提供賞金來增加對問題的關注。 – PeterT 2012-01-14 13:48:59
我打算,但只有當我發佈的問題,我只需要等待兩天,直到這個當前問題成爲合格。 – twerdster 2012-01-14 15:49:52
你接受只涉及Matlab的答案嗎?我不知道JOGL。 – 2012-01-16 16:09:18