Superpowered SDK iOS - Migration from 2.2 -> 2.5 breaking changes - audio
I tried upgrading the Superpowered SDK to 2.5 which had some API changes, and now the audio stopped working. I have very limited knowledge in this language.
This is how the initializer looked before:
Superpowered::Initialize(
licenseKey,
false, // enableAudioAnalysis (using SuperpoweredAnalyzer, SuperpoweredLiveAnalyzer, SuperpoweredWaveform or SuperpoweredBandpassFilterbank)
false, // enableFFTAndFrequencyDomain (using SuperpoweredFrequencyDomain, SuperpoweredFFTComplex, SuperpoweredFFTReal or SuperpoweredPolarFFT)
false, // enableAudioTimeStretching (using SuperpoweredTimeStretching)
true, // enableAudioEffects (using any SuperpoweredFX class)
true, // enableAudioPlayerAndDecoder (using SuperpoweredAdvancedAudioPlayer or SuperpoweredDecoder)
false, // enableCryptographics (using Superpowered::RSAPublicKey, Superpowered::RSAPrivateKey, Superpowered::hasher or Superpowered::AES)
false // enableNetworking (using Superpowered::httpRequest)
);
The new initializer only takes the key, I assume everything else is enabled by default?
Superpowered::Initialize(licenseKey);
The audioProcessing callback changed from
static bool audioProcessing(void *clientdata,
float **inputBuffers,
unsigned int inputChannels,
float **outputBuffers,
unsigned int outputChannels,
unsigned int numberOfFrames,
unsigned int samplerate,
uint64_t hostTime)
To the new version:
static bool audioProcessing(void *clientdata,
float *inputBuffer,
float *outputBuffer,
unsigned int numberOfFrames,
unsigned int samplerate,
uint64_t hostTime)
Previously we passed this as
return [self audioProcessing:outputBuffers[0] right:outputBuffers[1] numFrames:numberOfFrames samplerate:samplerate];
To this function:
- (bool)audioProcessing:(float *)leftOutput
right:(float *)rightOutput
numFrames:(unsigned int)numberOfFrames
samplerate:(unsigned int)samplerate
{
size_t bufferSize = numberOfFrames * 2;
float outputBuffer[bufferSize];
memset(outputBuffer, 0, sizeof(float) * bufferSize);
bool silence = true;
NSArray *players = self.audioPlayerMap.allValues;
for (SPAudioPlayer *player in players)
{
silence &= ![player processStereo:outputBuffer
mix:true
numberOfFrames:numberOfFrames
sampleRate:samplerate];
}
limiter->samplerate = samplerate;
silence &= !limiter->process(outputBuffer, outputBuffer, numberOfFrames);
if (!silence) Superpowered::DeInterleave(outputBuffer, leftOutput, rightOutput, numberOfFrames);
return !silence;
}
But that doesn't work anymore, I've tried to just change how we call it in the audioProcessing callback but it sounds like crap:
return [self audioProcessing:&outputBuffer[0] right:&outputBuffer[1] numFrames:numberOfFrames samplerate:samplerate];
The documentation isn't really helpful, it just mentions that all other properties in the initializer was removed and that all audio is now interleaved
Related
C++ to C# char[]
C# code: class Hello{ public void helloWorld(char[] chars){ //do something } } C++ code to call C#: MyCSDLL::Hello* hello; //init hello, some calls are ok. char* myCharPtr; //init with message HRESULT result = hello->helloWorld(safeArray, (MyCSDLL::_MyRetVal) _retValPtr); Adapting from How to create and initialize SAFEARRAY of doubles in C++ to pass to C# void createSafeArray(SAFEARRAY** saData, char* charPtr) { char* iterator = charPtr; SAFEARRAYBOUND Bound; Bound.lLbound = 0; Bound.cElements = 10; *saData = SafeArrayCreate(VT_R8, 1, &Bound); char HUGEP *pdFreq; HRESULT hr = SafeArrayAccessData(*saData, (void HUGEP* FAR*)&pdFreq); if (SUCCEEDED(hr)) { do { *pdFreq++ = *iterator; } while (*iterator++); } } How to call hello->helloWorld()? it is expecting SAFEARRAY*. The current code gives 80131538 error. How to fix it? C++ Project is not CLR.
Let's suppose the C# code is this: namespace ClassLibrary1 { [ComVisible(true)] [ClassInterface(ClassInterfaceType.AutoDual)] public class Hello { public void helloWorld(char[] chars) { ... } } } Then, you can call it with this C/C++ code, for example: #import "C:\mycode\ClassLibrary1\bin\Debug\classlibrary1.tlb" raw_interfaces_only using namespace ClassLibrary1; HRESULT CallHello(wchar_t* charPtr, int count) { CComPtr<_Hello> p; HRESULT hr = p.CoCreateInstance(__uuidof(Hello)); if (FAILED(hr)) return hr; SAFEARRAY* psa = SafeArrayCreateVector(VT_UI2, 0, count); if (!psa) return E_OUTOFMEMORY; LPVOID pdata; hr = SafeArrayAccessData(psa, &pdata); if (SUCCEEDED(hr)) { CopyMemory(pdata, charPtr, count * 2); // count is the number of chars SafeArrayUnaccessData(psa); hr = p->helloWorld(psa); } SafeArrayDestroy(psa); return hr; } .NET's char type is unicode, so the binary size is two bytes, the C equivalent is wchar_t (or unsigned short, etc...). So the safearray element type must match that, that's why I used VT_UI2 (VT_R8 that you used is Real of size 8 bytes, so it's equivalent to .NET's double type). If you really want to use C's char, then you must do some kind of conversion to a 2-byte character. Also, you can use the SafeArrayCreateVector function which directly allocates a 1-dimension safe array. Don't forget to call cleanup methods.
Creating dynamically sized MPI file views
I would like to write out a binary file using collective MPI I/O. My plan is to create an MPI derived type analogous to struct soln_dynamic_t { int int_data[2]; double *u; /* Length constant for all instances of this struct */ }; Each processor then creates a view based on the derived type, and writes into the view. I have this all working for the case in which *u is replaced with u[10] (see complete code below), but ultimately, I'd like to have a dynamic length array for u. (In case it matters, the length will be fixed for all instances of soln_dynamic_t for any run, but not known at compile time.) What is the best way to handle this? I have read several posts on why I can't use soln_dynamic_t directly as an MPI structure. The problem is that processors are not guaranteed to have the same offset between u[0] and int_data[0]. (Is that right?) On the other hand, the structure struct soln_static_t { int int_data[2]; double u[10]; /* fixed at compile time */ }; works because the offsets are guaranteed to be the same across processors. I've considered several approaches : Create the view based on manually defined offsets, etc, rather than using a derived type. Base the MPI structure on another MPI type, i.e. an contiguous type for ``*u` (is that allowed?) I am guessing there must be a standard way to do this. Any suggestions would be very helpful. Several other posts on this issue have been helpful, although they mostly deal with communication and not file I/O. Here is the complete code:: #include <mpi.h> typedef struct { int int_data[2]; double u[10]; /* Make this a dynamic length (but fixed) */ } soln_static_t; void build_soln_type(int n, int* int_data, double *u, MPI_Datatype *soln_t) { int block_lengths[2] = {2,n}; MPI_Datatype typelist[2] = {MPI_INT, MPI_DOUBLE}; MPI_Aint disp[2], start_address, address; MPI_Address(int_data,&start_address); MPI_Address(u,&address); disp[0] = 0; disp[1] = address-start_address; MPI_Datatype tmp_type; MPI_Type_create_struct(2,block_lengths,disp,typelist,&tmp_type); MPI_Aint extent; extent = block_lengths[0]*sizeof(int) + block_lengths[1]*sizeof(double); MPI_Type_create_resized(tmp_type, 0, extent, soln_t); MPI_Type_commit(soln_t); } void main(int argc, char** argv) { MPI_File file; int globalsize, localsize, starts, order; MPI_Datatype localarray, soln_t; int rank, nprocs, nsize = 10; /* must match size in struct above */ /* --- Initialize MPI */ MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); /* --- Set up data to write out */ soln_static_t data; data.int_data[0] = nsize; data.int_data[1] = rank; data.u[0] = 3.14159; /* To check that data is written as expected */ build_soln_type(nsize, data.int_data, data.u, &soln_t); MPI_File_open(MPI_COMM_WORLD, "bin.out", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &file); /* --- Create file view for this processor */ globalsize = nprocs; localsize = 1; starts = rank; order = MPI_ORDER_C; MPI_Type_create_subarray(1, &globalsize, &localsize, &starts, order, soln_t, &localarray); MPI_Type_commit(&localarray); MPI_File_set_view(file, 0, soln_t, localarray, "native", MPI_INFO_NULL); /* --- Write data into view */ MPI_File_write_all(file, data.int_data, 1, soln_t, MPI_STATUS_IGNORE); /* --- Clean up */ MPI_File_close(&file); MPI_Type_free(&localarray); MPI_Type_free(&soln_t); MPI_Finalize(); }
Since the size of the u array of the soln_dynamic_t type is known at runtime and will not change after that, I'd rather suggest an other approach. Basically, you store all the data contiguous in memory : typedef struct { int int_data[2]; double u[]; /* Make this a dynamic length (but fixed) */ } soln_dynamic_t; Then you have to manually allocate this struct soln_dynamic_t * alloc_soln(int nsize, int count) { return (soln_dynamic_t *)calloc(offsetof(soln_dynamic_t, u)+nsize*sizeof(double), count); } Note you cannot directly access an array of soln_dynamic_t because the size is unknown at compile time. Instead, you have to manually calculate the pointers. soln_dynamic_t *p = alloc_soln(10, 2); p[0].int_data[0] = 1; // OK p[0].u[0] = 2; // OK p[1].int_data[0] = 3; // KO ! since sizeof(soln_dynamic_t) is unknown at compile time. Here is the full rewritten version of your program #include <mpi.h> #include <malloc.h> typedef struct { int int_data[2]; double u[]; /* Make this a dynamic length (but fixed) */ } soln_dynamic_t; void build_soln_type(int n, MPI_Datatype *soln_t) { int block_lengths[2] = {2,n}; MPI_Datatype typelist[2] = {MPI_INT, MPI_DOUBLE}; MPI_Aint disp[2]; disp[0] = offsetof(soln_dynamic_t, int_data); disp[1] = offsetof(soln_dynamic_t, u); MPI_Datatype tmp_type; MPI_Type_create_struct(2,block_lengths,disp,typelist,&tmp_type); MPI_Aint extent; extent = offsetof(soln_dynamic_t, u) + block_lengths[1]*sizeof(double); MPI_Type_create_resized(tmp_type, 0, extent, soln_t); MPI_Type_free(&tmp_type); MPI_Type_commit(soln_t); } soln_dynamic_t * alloc_soln(int nsize, int count) { return (soln_dynamic_t *)calloc(offsetof(soln_dynamic_t, u) + nsize*sizeof(double), count); } int main(int argc, char** argv) { MPI_File file; int globalsize, localsize, starts, order; MPI_Datatype localarray, soln_t; int rank, nprocs, nsize = 10; /* must match size in struct above */ /* --- Initialize MPI */ MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); /* --- Set up data to write out */ soln_dynamic_t *data = alloc_soln(nsize,1); data->int_data[0] = nsize; data->int_data[1] = rank; data->u[0] = 3.14159; /* To check that data is written as expected */ build_soln_type(nsize, &soln_t); MPI_File_open(MPI_COMM_WORLD, "bin2.out", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &file); /* --- Create file view for this processor */ globalsize = nprocs; localsize = 1; starts = rank; order = MPI_ORDER_C; MPI_Type_create_subarray(1, &globalsize, &localsize, &starts, order, soln_t, &localarray); MPI_Type_commit(&localarray); MPI_File_set_view(file, 0, soln_t, localarray, "native", MPI_INFO_NULL); /* --- Write data into view */ MPI_File_write_all(file, data, 1, soln_t, MPI_STATUS_IGNORE); /* --- Clean up */ MPI_File_close(&file); MPI_Type_free(&localarray); MPI_Type_free(&soln_t); MPI_Finalize(); return 0; }
Android Camera output using ndk-blurry result
http://postimg.org/image/btd4u4esx/ Hi, This is the output image(black keyboard with white background) of a code that i modified from one of android samples. I want to take byte data from java file and send it to cpp using jni as unsigned character and and i am trying to display the video frames i receive using open cv mat. JAVA CODE: native int Fibonacci( byte[] n,int width, int height ); static { System.loadLibrary( "CopyofHDRViewFinder" ); } #Override public void run() { // y = 0.299*r + 0.587*g + 0.114*b Log.v(TAG, "enter in imageSaver! Format is: " + mImage.getFormat()); ByteBuffer buffer = mImage.getPlanes()[0].getBuffer(); int heigth=mImage.getHeight(); int width=mImage.getWidth(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes); int a=Fibonacci(bytes,width,heigth); int pixelsize=mImage.getWidth()*mImage.getHeight(); System.out.println("framewidth:"+mImage.getWidth()); System.out.println("frameheight:"+mImage.getHeight()); System.out.println("totalnumberofpixels:"+pixelsize); System.out.println("lastpixelvalue:"+a); then the CPP code:(jni) JNIEXPORT jint JNICALL Java_com_example_android_hdrviewfinder_HdrViewfinderActivity3_00024ImageSaver_Fibonacci (JNIEnv *env, jobject obj, jbyteArray array, jint width, jint height) { i=i+1; int len = env->GetArrayLength (array); unsigned char* img = new unsigned char[len]; env->GetByteArrayRegion (array, 0, len-1, reinterpret_cast<jbyte*>(img)); const cv::Mat hdrimg(height,width, CV_8UC1, img); char buffer[50]; int ab=sprintf(buffer,"/storage/emulated/0/Android/IMAGE%d.jpg",i); cv::imwrite(buffer, hdrimg); /*cv::namedWindow("HDRImage"); cv::imshow("HDRImage", hdrimg); cv::waitKey(0);*/ printf("\n %d", width); printf("\n %d", height); int a; for(int i=0;i<width*height;i++) { a=(int)img[i]; } int c=width*height; return a; } This returns proper pixel values from 0 to 255. my issue is not that. when i check the image it looks blurry and totally horrible, but still i cant deduce that its a keyboard slightly. Anyone has seen similar results? Help, if you can..
STM32F105, arm-none-eabi-gcc, Contiki: Storing float in struct and printing float in C fails
I have two typedef struct as shown below: typedef struct{ UInt32 length; void* data; UInt16 value; } my_type; typedef struct{ UInt8 type; UInt32 length; void* value; } tlv_t; What I trying next is to allocate memory for an my_type struct, a tlv_t struct that is pointed to from the created my_type object and for a float number, which is pointed to from the tlv_t object.If I'm executing the code without the last line of the code below it is working well. I can store the value and I can access it.But as soon as I try to access it a second time the uploaded code isn't running at all anymore on the STM32F105 Contiki-based board. The odd part is that this is only the case when using floating point numbers. No problems at all with other datatypes like int. Unfortunately, I really need to use float... What am I doing wrong? Another problem is that printf doesn't support some flags like %f or %ul. Does anybody know how to add support for it on Contiki? my_type* t = malloc(sizeof(my_type)); t->data = malloc(sizeof(tlv_t)); tlv_t* tv = t->data; tv->type = 10; tv->length = sizeof(float); tv->value = malloc(sizeof(float)); *(float*) tv->value = 212.32; printf("tv->value: %i\n", (int) *(float*) tv->value); printf("tv->value: %i\n", (int) *(float*) tv->value); // without this line it is working EDIT: I forgot to add these typedefs: typedef unsigned char UInt8; typedef unsigned short UInt16; typedef unsigned long UInt32; EDIT2: Here is the complete code: #include <contiki.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <cfs/cfs.h> #include <cfs/cfs-coffee.h> #include "arg.h" /*---------------------------------------------------------------------------*/ PROCESS(main_process, "Contiki CLV build015_1"); AUTOSTART_PROCESSES(&main_process); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(main_process, ev, data) { PROCESS_BEGIN(); my_type* t = malloc(sizeof(my_type)); t->data = malloc(sizeof(tlv_t)); tlv_t* tv = t->data; tv->type = 10; tv->length = sizeof(float); tv->value = malloc(sizeof(float)); *(float*) tv->value = 212.32; printf("tv->value: %i\n", (int) *(float*) tv->value); printf("tv->value: %i\n", (int) *(float*) tv->value); // without this line it is working while (1) { PROCESS_YIELD(); } PROCESS_END(); } EDIT3: I'm using the latest arm-none-eabi-gcc (version 4_8-2013q4-20131204). Are there any known issues when dealing with structs, floats or memory management?
Try PROCESS_THREAD(main_process, ev, data) { static my_type *t; static tlv_t *tv; static float f = 212.32; PROCESS_BEGIN(); t = (my_type *)malloc(sizeof(my_type)); t->data = malloc(sizeof(tlv_t)); tv = (tlv_t *)t->data; tv->type = 10; tv->length = sizeof(float); tv->value = malloc(sizeof(float)); //*(float *) tv->value = 212.32; memmove(tv->value, &f, 4); printf("tv->value: %i\n", (int) *(float*) tv->value); printf("tv->value: %i\n", (int) *(float*) tv->value); // without this line it is working printf("t address: %x \n", (unsigned int)t); while (1) { PROCESS_YIELD(); } PROCESS_END(); }
I suggest you fix your code, so you get no compiler warnings anymore (don't turn them off). Add casts as needed. After I did those fixes your code worked for me, so the code is ugly but ok. #define UInt32 unsigned int #define UInt16 unsigned short #define UInt8 unsigned char typedef struct{ UInt32 length; void* data; UInt16 value; } my_type; typedef struct{ UInt8 type; UInt32 length; void* value; } tlv_t; int _tmain(int argc, _TCHAR* argv[]) { my_type* t = (my_type*)malloc(sizeof(my_type)); t->data = malloc(sizeof(tlv_t)); tlv_t* tv = (tlv_t*)t->data; tv->type = 10; tv->length = sizeof(float); tv->value = malloc(sizeof(float)); *(float*) tv->value = (float)212.32; printf("tv->value: %i\n", (int) *(float*) tv->value); printf("tv->value: %i\n", (int) *(float*) tv->value); // without this line it getchar(); } gives tv->value: 212 tv->value: 212
Looking for code samples for Direct3D tessellation
I am trying to learn how to use the Direct3D function D3DXTessellateRectPatch: msdn.microsoft.com/en-us/library/bb205471(v=VS.85).aspx I have found the MSDN documentation quite useful and have been able to implement tessellation of a single rectangle patch. I am now trying to tesselate a mesh that consists of thirty two bicubic Bezier 3D patches (the Utah teapot). I have tried a simple approach - tesselate each Bezier curve individually, then join the vertices and indices appropriately, taking into account vertex offsets, to create a tessellated merged mesh. However, this does not quite seem to have the desired result. If anyone has hints on this problem or, even better, code samples, much appreciated. Specifically, I have checked: Www.directxtutorial.com http://www.amazon.com/Introduction-Game-Programming-Direct-9-0c/dp/1598220160/ And another Direct3D reference, as well as Google. Thank you and look forward to your advice/pointers. Yours Misha
Tim C Schroeder has been a huge help and suggested I use ID3DXPatchMesh. Here is some sample code that generates a tessellated teapot (place in file tester.cpp): // Main D3DX framework from www.directxtutorial.com (free section) #include <assert.h> #include <stdio.h> // include the basic windows header files and the Direct3D header file #include <windows.h> #include <windowsx.h> #include <d3d9.h> #include <d3dx9.h> // define the screen resolution #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 // include the Direct3D Library files #pragma comment (lib, "d3d9.lib") #pragma comment (lib, "d3dx9.lib") // global declarations LPDIRECT3D9 d3d; LPDIRECT3DDEVICE9 d3ddev; LPD3DXMESH mesh = NULL; // define the mesh pointer // function prototypes void initD3D(HWND hWnd); void render_frame(void); void cleanD3D(void); void init_graphics(void); struct vertex_data { D3DXVECTOR3 position; DWORD color; }; #define FVF_VERTEX_DATA (D3DFVF_XYZ | D3DFVF_DIFFUSE) // the WindowProc function prototype LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // the entry point for any Windows program int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = "WindowClass"; RegisterClassEx(&wc); hWnd = CreateWindowEx(NULL, "WindowClass", "Our Direct3D Program", WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); initD3D(hWnd); MSG msg; while(TRUE) { while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } if(msg.message == WM_QUIT) break; render_frame(); } cleanD3D(); return msg.wParam; } // this is the main message handler for the program LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc (hWnd, message, wParam, lParam); } // this function initializes and prepares Direct3D for use void initD3D(HWND hWnd) { d3d = Direct3DCreate9(D3D_SDK_VERSION); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hWnd; d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; d3dpp.BackBufferWidth = SCREEN_WIDTH; d3dpp.BackBufferHeight = SCREEN_HEIGHT; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); init_graphics(); d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE); // turn off the 3D lighting d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // turn off culling d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer } // this is the function used to render a single frame void render_frame(void) { d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3ddev->BeginScene(); d3ddev->SetFVF(FVF_VERTEX_DATA); // set the view transform D3DXMATRIX matView; // the view transform matrix D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3 (0.0f, 8.0f, 25.0f), // the camera position &D3DXVECTOR3 (0.0f, 0.0f, 0.0f), // the look-at position &D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // the up direction d3ddev->SetTransform(D3DTS_VIEW, &matView); // set the view transform to matView // set the projection transform D3DXMATRIX matProjection; // the projection transform matrix D3DXMatrixPerspectiveFovLH(&matProjection, D3DXToRadian(45), // the horizontal field of view (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio 1.0f, // the near view-plane 100.0f); // the far view-plane d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection // set the world transform static float index = 0.0f; index+=0.03f; // an ever-increasing float value D3DXMATRIX matRotateY; // a matrix to store the rotation for each triangle D3DXMatrixRotationY(&matRotateY, index); // the rotation matrix d3ddev->SetTransform(D3DTS_WORLD, &(matRotateY)); // set the world transform if (mesh) mesh->DrawSubset(0); d3ddev->EndScene(); d3ddev->Present(NULL, NULL, NULL, NULL); } // this is the function that cleans up Direct3D and COM void cleanD3D(void) { if (mesh) mesh->Release(); d3ddev->Release(); d3d->Release(); } #define MAX_PATCHES 1000 #define POINTS_PER_PATCH 16 int num_patches = -1; int patches[MAX_PATCHES][POINTS_PER_PATCH]; void B_patch(int ii, int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p) { assert(ii < MAX_PATCHES); patches[ii][0] = a-1; patches[ii][1] = b-1; patches[ii][2] = c-1; patches[ii][3] = d-1; patches[ii][4] = e-1; patches[ii][5] = f-1; patches[ii][6] = g-1; patches[ii][7] = h-1; patches[ii][8] = i-1; patches[ii][9] = j-1; patches[ii][10] = k-1; patches[ii][11] = l-1; patches[ii][12] = m-1; patches[ii][13] = n-1; patches[ii][14] = o-1; patches[ii][15] = p-1; assert(POINTS_PER_PATCH==16); } #define MAX_POINTS 1000 int num_points = -1; D3DXVECTOR3 points[MAX_POINTS]; void B_point(int ii, double x, double y, double z) { ii--; assert(ii < MAX_POINTS); points[ii].x = x; /*** Y AND Z FLIPPED ***/ points[ii].y = z; points[ii].z = y; } // BEGIN http://www.sjbaker.org/teapot/teaset.tgz /* * The file input.c -- Juhana Kouhia, jk87377#cs.tut.fi, Oct. 25, 1991 * * Load_patch(filename, patches, vertices); * char *filename; int *patches, *vertices; * A sample program to read Bezier patches in. * Returns count of patches and vertices. * User defined subroutines: * B_patch(ii, a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p); * int ii, a, b, ..., p; * Defines one Bezier patch with index number ii, * indexes to points are in a, b, c, ..., p. * B_point(ii, x, y, z); * int ii; double x, y, z; * Defines one point with index number ii. */ #include <stdio.h> // Modified to work with g++ void Load_patch(char *filename, int *patches, int *vertices) { int ii; float x,y,z; int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p; FILE *fp; if (!(fp = fopen(filename,"r"))) { fprintf(stderr,"Load_patch: Can't open %s\n",filename); exit(1); } (void)fscanf(fp,"%i\n",patches); for (ii = 0; ii < *patches; ii++) { (void)fscanf(fp,"%i, %i, %i, %i,",&a,&b,&c,&d); (void)fscanf(fp,"%i, %i, %i, %i,",&e,&f,&g,&h); (void)fscanf(fp,"%i, %i, %i, %i,",&i,&j,&k,&l); (void)fscanf(fp,"%i, %i, %i, %i\n",&m,&n,&o,&p); B_patch(ii, a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p); } (void)fscanf(fp,"%i\n",vertices); for (ii = 1; ii <= *vertices; ii++) { (void)fscanf(fp,"%f, %f, %f\n",&x,&y,&z); B_point(ii, (double)x,(double)y,(double)z); } } // END http://www.sjbaker.org/teapot/teaset.tgz // this is the function that puts the 3D models into video RAM void init_graphics(void) { // load patch char filename[255]; sprintf(filename,"teapot"); Load_patch(filename,&num_patches,&num_points); printf("Loaded patch %s with %d patches and %d vertices.\n", filename,num_patches,num_points); // create declarator from FVF D3DVERTEXELEMENT9 inDecl[MAX_FVF_DECL_SIZE]; if (!SUCCEEDED(D3DXDeclaratorFromFVF(FVF_VERTEX_DATA,inDecl))) assert(FALSE); // create patch mesh LPD3DXPATCHMESH p_mesh; D3DXPATCHINFO info; info.PatchType = D3DXPATCHMESH_RECT; info.Degree = D3DDEGREE_CUBIC; info.Basis = D3DBASIS_BEZIER; if (!SUCCEEDED(D3DXCreatePatchMesh(&info,num_patches,num_points,0,inDecl,d3ddev,&p_mesh))) assert(FALSE); assert(p_mesh->GetControlVerticesPerPatch()==POINTS_PER_PATCH); // copy vertices LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; if (!SUCCEEDED(p_mesh->GetVertexBuffer(&v_buffer))) assert(FALSE); struct vertex_data* vertex_data = NULL; DWORD number_of_vertices=p_mesh->GetNumVertices(); assert(number_of_vertices==num_points); if (!SUCCEEDED(v_buffer->Lock(0,number_of_vertices*sizeof(struct vertex_data),(void **)&vertex_data,D3DLOCK_DISCARD))) assert(FALSE); for (int i=0; i<num_points; i++) { vertex_data[i].position.x = points[i].x; vertex_data[i].position.y = points[i].y; vertex_data[i].position.z = points[i].z; vertex_data[i].color = D3DCOLOR_XRGB(255,0,0); } v_buffer->Unlock(); v_buffer->Release(); // copy indices LPDIRECT3DINDEXBUFFER9 i_buffer = NULL; if (!SUCCEEDED(p_mesh->GetIndexBuffer(&i_buffer))) assert(FALSE); D3DINDEXBUFFER_DESC i_buffer_desc; if (!SUCCEEDED(i_buffer->GetDesc(&i_buffer_desc))) assert(FALSE); assert(i_buffer_desc.Size==num_patches*POINTS_PER_PATCH*sizeof(WORD)); WORD* index_data = NULL; if (!SUCCEEDED(i_buffer->Lock(0,0,(void **)&index_data,D3DLOCK_DISCARD))) assert(FALSE); int idx=0; for (int i=0; i<num_patches; i++) { for (int j=0; j<POINTS_PER_PATCH; j++) { index_data[idx] = patches[i][j]; idx++; } } i_buffer->Unlock(); i_buffer->Release(); // create mesh for tesselation FLOAT fTessLevel=1.0f; DWORD Adaptive=FALSE; DWORD NumTriangles,NumVertices; if (!SUCCEEDED(p_mesh->GetTessSize(fTessLevel,Adaptive,&NumTriangles,&NumVertices))) assert(FALSE); if (!SUCCEEDED(D3DXCreateMeshFVF(NumTriangles,NumVertices,D3DXMESH_MANAGED,FVF_VERTEX_DATA,d3ddev,&mesh))) assert(FALSE); // tesselate assert(Adaptive==FALSE); if (!SUCCEEDED(p_mesh->Tessellate(fTessLevel,mesh))) assert(FALSE); printf("Generated tesselated mesh with %d triangles, %d vertices\n",NumTriangles,NumVertices); p_mesh->Release(); } The teapot data (place in file teapot) is (from http://www.sjbaker.org/teapot/teaset.tgz): 32 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 4,17,18,19,8,20,21,22,12,23,24,25,16,26,27,28 19,29,30,31,22,32,33,34,25,35,36,37,28,38,39,40 31,41,42,1,34,43,44,5,37,45,46,9,40,47,48,13 13,14,15,16,49,50,51,52,53,54,55,56,57,58,59,60 16,26,27,28,52,61,62,63,56,64,65,66,60,67,68,69 28,38,39,40,63,70,71,72,66,73,74,75,69,76,77,78 40,47,48,13,72,79,80,49,75,81,82,53,78,83,84,57 57,58,59,60,85,86,87,88,89,90,91,92,93,94,95,96 60,67,68,69,88,97,98,99,92,100,101,102,96,103,104,105 69,76,77,78,99,106,107,108,102,109,110,111,105,112,113,114 78,83,84,57,108,115,116,85,111,117,118,89,114,119,120,93 121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136 124,137,138,121,128,139,140,125,132,141,142,129,136,143,144,133 133,134,135,136,145,146,147,148,149,150,151,152,69,153,154,155 136,143,144,133,148,156,157,145,152,158,159,149,155,160,161,69 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177 165,178,179,162,169,180,181,166,173,182,183,170,177,184,185,174 174,175,176,177,186,187,188,189,190,191,192,193,194,195,196,197 177,184,185,174,189,198,199,186,193,200,201,190,197,202,203,194 204,204,204,204,207,208,209,210,211,211,211,211,212,213,214,215 204,204,204,204,210,217,218,219,211,211,211,211,215,220,221,222 204,204,204,204,219,224,225,226,211,211,211,211,222,227,228,229 204,204,204,204,226,230,231,207,211,211,211,211,229,232,233,212 212,213,214,215,234,235,236,237,238,239,240,241,242,243,244,245 215,220,221,222,237,246,247,248,241,249,250,251,245,252,253,254 222,227,228,229,248,255,256,257,251,258,259,260,254,261,262,263 229,232,233,212,257,264,265,234,260,266,267,238,263,268,269,242 270,270,270,270,279,280,281,282,275,276,277,278,271,272,273,274 270,270,270,270,282,289,290,291,278,286,287,288,274,283,284,285 270,270,270,270,291,298,299,300,288,295,296,297,285,292,293,294 270,270,270,270,300,305,306,279,297,303,304,275,294,301,302,271 306 1.4,0.0,2.4 1.4,-0.784,2.4 0.784,-1.4,2.4 0.0,-1.4,2.4 1.3375,0.0,2.53125 1.3375,-0.749,2.53125 0.749,-1.3375,2.53125 0.0,-1.3375,2.53125 1.4375,0.0,2.53125 1.4375,-0.805,2.53125 0.805,-1.4375,2.53125 0.0,-1.4375,2.53125 1.5,0.0,2.4 1.5,-0.84,2.4 0.84,-1.5,2.4 0.0,-1.5,2.4 -0.784,-1.4,2.4 -1.4,-0.784,2.4 -1.4,0.0,2.4 -0.749,-1.3375,2.53125 -1.3375,-0.749,2.53125 -1.3375,0.0,2.53125 -0.805,-1.4375,2.53125 -1.4375,-0.805,2.53125 -1.4375,0.0,2.53125 -0.84,-1.5,2.4 -1.5,-0.84,2.4 -1.5,0.0,2.4 -1.4,0.784,2.4 -0.784,1.4,2.4 0.0,1.4,2.4 -1.3375,0.749,2.53125 -0.749,1.3375,2.53125 0.0,1.3375,2.53125 -1.4375,0.805,2.53125 -0.805,1.4375,2.53125 0.0,1.4375,2.53125 -1.5,0.84,2.4 -0.84,1.5,2.4 0.0,1.5,2.4 0.784,1.4,2.4 1.4,0.784,2.4 0.749,1.3375,2.53125 1.3375,0.749,2.53125 0.805,1.4375,2.53125 1.4375,0.805,2.53125 0.84,1.5,2.4 1.5,0.84,2.4 1.75,0.0,1.875 1.75,-0.98,1.875 0.98,-1.75,1.875 0.0,-1.75,1.875 2.0,0.0,1.35 2.0,-1.12,1.35 1.12,-2.0,1.35 0.0,-2.0,1.35 2.0,0.0,0.9 2.0,-1.12,0.9 1.12,-2.0,0.9 0.0,-2.0,0.9 -0.98,-1.75,1.875 -1.75,-0.98,1.875 -1.75,0.0,1.875 -1.12,-2.0,1.35 -2.0,-1.12,1.35 -2.0,0.0,1.35 -1.12,-2.0,0.9 -2.0,-1.12,0.9 -2.0,0.0,0.9 -1.75,0.98,1.875 -0.98,1.75,1.875 0.0,1.75,1.875 -2.0,1.12,1.35 -1.12,2.0,1.35 0.0,2.0,1.35 -2.0,1.12,0.9 -1.12,2.0,0.9 0.0,2.0,0.9 0.98,1.75,1.875 1.75,0.98,1.875 1.12,2.0,1.35 2.0,1.12,1.35 1.12,2.0,0.9 2.0,1.12,0.9 2.0,0.0,0.45 2.0,-1.12,0.45 1.12,-2.0,0.45 0.0,-2.0,0.45 1.5,0.0,0.225 1.5,-0.84,0.225 0.84,-1.5,0.225 0.0,-1.5,0.225 1.5,0.0,0.15 1.5,-0.84,0.15 0.84,-1.5,0.15 0.0,-1.5,0.15 -1.12,-2.0,0.45 -2.0,-1.12,0.45 -2.0,0.0,0.45 -0.84,-1.5,0.225 -1.5,-0.84,0.225 -1.5,0.0,0.225 -0.84,-1.5,0.15 -1.5,-0.84,0.15 -1.5,0.0,0.15 -2.0,1.12,0.45 -1.12,2.0,0.45 0.0,2.0,0.45 -1.5,0.84,0.225 -0.84,1.5,0.225 0.0,1.5,0.225 -1.5,0.84,0.15 -0.84,1.5,0.15 0.0,1.5,0.15 1.12,2.0,0.45 2.0,1.12,0.45 0.84,1.5,0.225 1.5,0.84,0.225 0.84,1.5,0.15 1.5,0.84,0.15 -1.6,0.0,2.025 -1.6,-0.3,2.025 -1.5,-0.3,2.25 -1.5,0.0,2.25 -2.3,0.0,2.025 -2.3,-0.3,2.025 -2.5,-0.3,2.25 -2.5,0.0,2.25 -2.7,0.0,2.025 -2.7,-0.3,2.025 -3.0,-0.3,2.25 -3.0,0.0,2.25 -2.7,0.0,1.8 -2.7,-0.3,1.8 -3.0,-0.3,1.8 -3.0,0.0,1.8 -1.5,0.3,2.25 -1.6,0.3,2.025 -2.5,0.3,2.25 -2.3,0.3,2.025 -3.0,0.3,2.25 -2.7,0.3,2.025 -3.0,0.3,1.8 -2.7,0.3,1.8 -2.7,0.0,1.575 -2.7,-0.3,1.575 -3.0,-0.3,1.35 -3.0,0.0,1.35 -2.5,0.0,1.125 -2.5,-0.3,1.125 -2.65,-0.3,0.9375 -2.65,0.0,0.9375 -2.0,-0.3,0.9 -1.9,-0.3,0.6 -1.9,0.0,0.6 -3.0,0.3,1.35 -2.7,0.3,1.575 -2.65,0.3,0.9375 -2.5,0.3,1.125 -1.9,0.3,0.6 -2.0,0.3,0.9 1.7,0.0,1.425 1.7,-0.66,1.425 1.7,-0.66,0.6 1.7,0.0,0.6 2.6,0.0,1.425 2.6,-0.66,1.425 3.1,-0.66,0.825 3.1,0.0,0.825 2.3,0.0,2.1 2.3,-0.25,2.1 2.4,-0.25,2.025 2.4,0.0,2.025 2.7,0.0,2.4 2.7,-0.25,2.4 3.3,-0.25,2.4 3.3,0.0,2.4 1.7,0.66,0.6 1.7,0.66,1.425 3.1,0.66,0.825 2.6,0.66,1.425 2.4,0.25,2.025 2.3,0.25,2.1 3.3,0.25,2.4 2.7,0.25,2.4 2.8,0.0,2.475 2.8,-0.25,2.475 3.525,-0.25,2.49375 3.525,0.0,2.49375 2.9,0.0,2.475 2.9,-0.15,2.475 3.45,-0.15,2.5125 3.45,0.0,2.5125 2.8,0.0,2.4 2.8,-0.15,2.4 3.2,-0.15,2.4 3.2,0.0,2.4 3.525,0.25,2.49375 2.8,0.25,2.475 3.45,0.15,2.5125 2.9,0.15,2.475 3.2,0.15,2.4 2.8,0.15,2.4 0.0,0.0,3.15 0.0,-0.002,3.15 0.002,0.0,3.15 0.8,0.0,3.15 0.8,-0.45,3.15 0.45,-0.8,3.15 0.0,-0.8,3.15 0.0,0.0,2.85 0.2,0.0,2.7 0.2,-0.112,2.7 0.112,-0.2,2.7 0.0,-0.2,2.7 -0.002,0.0,3.15 -0.45,-0.8,3.15 -0.8,-0.45,3.15 -0.8,0.0,3.15 -0.112,-0.2,2.7 -0.2,-0.112,2.7 -0.2,0.0,2.7 0.0,0.002,3.15 -0.8,0.45,3.15 -0.45,0.8,3.15 0.0,0.8,3.15 -0.2,0.112,2.7 -0.112,0.2,2.7 0.0,0.2,2.7 0.45,0.8,3.15 0.8,0.45,3.15 0.112,0.2,2.7 0.2,0.112,2.7 0.4,0.0,2.55 0.4,-0.224,2.55 0.224,-0.4,2.55 0.0,-0.4,2.55 1.3,0.0,2.55 1.3,-0.728,2.55 0.728,-1.3,2.55 0.0,-1.3,2.55 1.3,0.0,2.4 1.3,-0.728,2.4 0.728,-1.3,2.4 0.0,-1.3,2.4 -0.224,-0.4,2.55 -0.4,-0.224,2.55 -0.4,0.0,2.55 -0.728,-1.3,2.55 -1.3,-0.728,2.55 -1.3,0.0,2.55 -0.728,-1.3,2.4 -1.3,-0.728,2.4 -1.3,0.0,2.4 -0.4,0.224,2.55 -0.224,0.4,2.55 0.0,0.4,2.55 -1.3,0.728,2.55 -0.728,1.3,2.55 0.0,1.3,2.55 -1.3,0.728,2.4 -0.728,1.3,2.4 0.0,1.3,2.4 0.224,0.4,2.55 0.4,0.224,2.55 0.728,1.3,2.55 1.3,0.728,2.55 0.728,1.3,2.4 1.3,0.728,2.4 0.0,0.0,0.0 1.5,0.0,0.15 1.5,0.84,0.15 0.84,1.5,0.15 0.0,1.5,0.15 1.5,0.0,0.075 1.5,0.84,0.075 0.84,1.5,0.075 0.0,1.5,0.075 1.425,0.0,0.0 1.425,0.798,0.0 0.798,1.425,0.0 0.0,1.425,0.0 -0.84,1.5,0.15 -1.5,0.84,0.15 -1.5,0.0,0.15 -0.84,1.5,0.075 -1.5,0.84,0.075 -1.5,0.0,0.075 -0.798,1.425,0.0 -1.425,0.798,0.0 -1.425,0.0,0.0 -1.5,-0.84,0.15 -0.84,-1.5,0.15 0.0,-1.5,0.15 -1.5,-0.84,0.075 -0.84,-1.5,0.075 0.0,-1.5,0.075 -1.425,-0.798,0.0 -0.798,-1.425,0.0 0.0,-1.425,0.0 0.84,-1.5,0.15 1.5,-0.84,0.15 0.84,-1.5,0.075 1.5,-0.84,0.075 0.798,-1.425,0.0 1.425,-0.798,0.0 Finally, to compile using mingw on Ubuntu 10.04 amd64 with proper software installed: #!/bin/bash rm tester.exe > /dev/null 2>&1 i586-mingw32msvc-g++ tester.cpp -o tester.exe -fcheck-new -Idxsdk/DXSDK/Include -ld3d9 dxsdk/DXSDK/Lib/x86/d3dx9.lib