Configuring SDI input/output for passthru input card->gpu->output card - linux

I'm using the Quadro SDI SDK along with my Quadro K6000+ SDI Input & output cards and have converted the included cudaDVP SDK sample to send raw image buffers directly to the GPU from the SDI input card.
In the next step I display the data via opengl bindings. Finally I want to output the same identical data to my output card, and this is where I'm having troubles.
I am getting correct input data and I do manage to output to the screen but there appears to be some data modifications happening in the SDI output pipeline as the outgoing image is not quite correct (wrong colors etc). I'm passing the raw input buffer as can be seen below.
Which output card configuration should I use to match my input settings (see below)?
Which if any modifications to the OpenGL output texture configuration are required (see below)?
Input/output Capture/receive options & GL bindings in order of being called in the application:
........
Display *dpy = XOpenDisplay(NULL);
//scan the systems for GPUs
int num_gpus = ScanHW(dpy,gpuList);
if(num_gpus < 1)
exit(1);
//grab the first GPU for now for DVP
HGPUNV *g = &gpuList[0];
////////////////////////////////////////////////////////////////////////////////////////////////
/// Input related SDI settings and OpenGL settings
// Query input , in our case Video format: NV_CTRL_GVIO_VIDEO_FORMAT_576I_50_00_SMPTE259_PAL
XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT, &m_videoFormat);
//
// Set desired parameters
//
// Signal format.
XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, m_videoFormat);
//Bits per component - 10 bits
XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT, NV_CTRL_GVI_BITS_PER_COMPONENT_10);
// Component sampling -422
XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING, NV_CTRL_GVI_COMPONENT_SAMPLING_422);
// Chroma expansion OFF
XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVI_REQUESTED_STREAM_CHROMA_EXPAND, NV_CTRL_GVI_CHROMA_EXPAND_FALSE);
// Query the width and height of the input signal format
XNVCTRLQueryAttribute(dpy, g->deviceXScreen, value, NV_CTRL_GVIO_VIDEO_FORMAT_WIDTH, &m_videoWidth);
XNVCTRLQueryAttribute(dpy, g->deviceXScreen, value, NV_CTRL_GVIO_VIDEO_FORMAT_HEIGHT, &m_videoHeight);
....
GLuint m_videoSlot; // Video slot number
GLuint m_vidBuf; // Video capture buffers
GLint m_bufPitch; // Buffer pitch
GLuint m_vidTex; // Video capture textures
m_videoSlot = 1;
//////////////////////////////////////
////////// OpenGL related settings
// No video color conversion desired ( we want the raw data, NULL )
glVideoCaptureStreamParameterfvNV(m_videoSlot, 0, GL_VIDEO_COLOR_CONVERSION_MATRIX_NV, NULL);
glVideoCaptureStreamParameterfvNV(m_videoSlot, 0,GL_VIDEO_COLOR_CONVERSION_MAX_NV, NULL);
glVideoCaptureStreamParameterfvNV(m_videoSlot, 0,GL_VIDEO_COLOR_CONVERSION_MIN_NV, NULL);
glVideoCaptureStreamParameterfvNV(m_videoSlot, 0,GL_VIDEO_COLOR_CONVERSION_OFFSET_NV, NULL);
// Set the buffer object capture data format. - IE number of components in a pixel
glVideoCaptureStreamParameterivNV(m_videoSlot, 0, GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV, &GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV);
// Get the video buffer pitch
glGetVideoCaptureStreamivNV(m_videoSlot, 0, GL_VIDEO_BUFFER_PITCH_NV, &m_bufPitch);
// Bind the buffer
glBindBufferARB(GL_VIDEO_BUFFER_NV, m_vidBuf);
// Allocate required space in video capture buffer
glBufferDataARB(GL_VIDEO_BUFFER_NV, m_bufPitch * m_videoHeight, NULL, GL_STREAM_READ_ARB);
// Bind the buffer to the video capture device.
glBindVideoCaptureStreamBufferNV(m_videoSlot, 0, GL_FRAME_NV, 0);
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
/// SDI Output card settings
GLuint m_CudaOutTexture; // Texture to send to the output device
GLuint m_CudaOutBuffer; // Texture to send to the output device
GLuint m_OutTexture;
// Set video format - same as input - NV_CTRL_GVIO_VIDEO_FORMAT_576I_50_00_SMPTE259_PAL
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT, m_videoFormat);
// Set data format format.
// Attempted several different settings here....
data_format = NV_CTRL_GVO_DATA_FORMAT_R8G8B8_TO_YCRCB422;
//data_format = NV_CTRL_GVO_DATA_FORMAT_X10X10X10_422_PASSTHRU;
//data_format = NV_CTRL_GVO_DATA_FORMAT_X8X8X8_422_PASSTHRU;
//data_format = NV_CTRL_GVO_DATA_FORMAT_R10G10B10_TO_YCRCB422;
//data_format = NV_CTRL_GVO_DATA_FORMAT_X12X12X12_422_PASSTHRU;
//data_format = NV_CTRL_GVO_DATA_FORMAT_Y10CR10CB10_TO_YCRCB444;
//data_format = NV_CTRL_GVO_DATA_FORMAT_X10X8X8_422_PASSTHRU;
//data_format = NV_CTRL_GVO_ENABLE_RGB_DATA_DISABLE
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_DATA_FORMAT, data_format);
// Set sync mode
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_SYNC_MODE, NV_CTRL_GVO_SYNC_MODE_FREE_RUNNING);
// Set sync source
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_SYNC_SOURCE, NV_CTRL_GVO_SYNC_SOURCE_SDI);
// Set flip queue length
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_FLIP_QUEUE_SIZE, 5);
.....
///////////////////////////////////////////////////////////////////
// OpenGL related settings for output
//Setup the output after the capture is configured.
glGenTextures(1, &m_OutTexture);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_OutTexture);
glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA8, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
////////////////////////////////////////////////////////
//Setup GL output from cuda
// Create and initialize a texture objects.
glGenBuffersARB(1, &m_CudaOutBuffer);
assert(glGetError() == GL_NO_ERROR);
glBindBufferARB(GL_VIDEO_BUFFER_NV, m_CudaOutBuffer);
assert(glGetError() == GL_NO_ERROR);
// Allocate required space in video capture buffer
glBufferDataARB(GL_VIDEO_BUFFER_NV, pitch * height, NULL, GL_STREAM_COPY);
glGenTextures(1, &m_CudaOutTexture);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_CudaOutTexture);
glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
assert(glGetError() == GL_NO_ERROR);
glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA8, width,height,
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
//register the buffer objects
cudaRegisterBuffers();
....
////////////////////////////////////////////////////////////////
/////////// Data transfer from GPU to output device buffer (to be outputted to the SDI output card)
GLint inBuf = m_vidBuf;
// Map buffer(s) into CUDA
cudaError_t cerr;
unsigned char *inDevicePtr;
cerr = cudaGLMapBufferObject((void**)&inDevicePtr, inBuf);
cudaCheckErrors("map");
unsigned char *outDevicePtr;
cerr = cudaGLMapBufferObject((void**)&outDevicePtr, m_CudaOutBuffer);
cudaCheckErrors("map");
//
// Dummy CUDA operation:
// Perform CUDA Operations here such as a kernel call with outDevicePtr and inDevicePtr.
//
unsigned int pitch = m_SDIin.getBufferObjectPitch(0);
unsigned int height = m_SDIin.getHeight();
cudaMemcpy(outDevicePtr,inDevicePtr,pitch*height,cudaMemcpyDeviceToDevice);
////////////////////////////////////////////////////////
/////// output
GLboolean C_cudaDVP::OutputVideo()
{
if(!m_SDIoutEnabled)
return GL_FALSE;
//send the texture to SDI out.
glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_OutTexture);
glEnable(GL_TEXTURE_RECTANGLE_NV);
glPresentFrameKeyedNV(1, 0,
0, 0,
GL_FRAME_NV,
GL_TEXTURE_RECTANGLE_NV, m_OutTexture, 0,
GL_NONE, 0, 0);
GLenum l_eVal = glGetError();
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
if (l_eVal != GL_NO_ERROR) {
fprintf(stderr, "glPresentFameKeyedNV returned error: %s\n", gluErrorString(l_eVal));
return FALSE;
}
return GL_TRUE;
}
.....
// After which we call:
// To skip a costly data copy from video buffer to texture we
// can just bind a video buffer to GL_PIXEL_UNPACK_BUFFER_ARB and call
// glTexSubImage2D referencing into the buffer with the PixelData pointer
// set to 0.
glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_CudaOutTexture);
//glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_SDIin.getBufferObjectHandle(0));
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_CudaOutBuffer);
glPixelStorei(GL_UNPACK_ROW_LENGTH,pitch/4);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
//////////////////////////////////////////////////////

Related

OpenGL double buffers on Ubuntu does not work

I'm testing out several of Sumantha Guha's code and there's something that isn't working quite right... All of the sample code where he uses GLUT_DOUBLE and glutSwapBuffers() does not work on my ubuntu machine, but works on my Windows machine. More accurately the window that pops out simply traces the background.
I've had this issue before on Windows where Flush and single buffers don't work, but now this is happening on Linux where Double buffers and glutSwapBuffers do not work. Any idea as to what may be causing this?
Sample of code that I tried loading. Compiles fine, just get a window that traces the background.
///////////////////////////////////////////////////////////////////////////////////////////////////////
// loadTextures.cpp
//
// This stripped-down program shows how to load both external and program-generated images as textures.
//
// NOTE: The Textures folder must be in the same one as this program.
//
// Interaction:
// Press the left and right arrow keys to rotate the square.
// Press space to toggle between textures.
// Press delete to reset.
//
// Sumanta Guha
///////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////
// TEXTURE GREDITS:
// canLabel.bmp, thanks anonymous.
// canTop.bmp, thanks www.acoustica.com.
// cray2.bmp, thanks NASA website www.nasa.gov.
// grass.bmp, thanks www.amazingtextures.com.
// launch.bmp, thanks NASA website www.nasa.gov.
// nightsky.bmp, thanks anonymous.
// sky.bmp, thanks www.mega-tex.nl.
// trees.bmp, thanks anonymous.
////////////////////////////////////////////////
#include <cstdlib>
#include <iostream>
#include <fstream>
#ifdef __APPLE__
# include <GLUT/glut.h>
# include <OpenGL/glext.h>
#else
# include <GL/glut.h>
# include <GL/glext.h>
#endif
using namespace std;
// Globals.
static unsigned int texture[2]; // Array of texture indices.
static unsigned char chessboard[64][64][3]; // Storage for chessboard image.
static float angle = 0.0; // Angle to rotate textured square.
static int id = 0; // Currently displayed texture id.
// Struct of bitmap file.
struct BitMapFile
{
int sizeX;
int sizeY;
unsigned char *data;
};
// Routine to read a bitmap file.
// Works only for uncompressed bmp files of 24-bit color.
BitMapFile *getBMPData(string filename)
{
BitMapFile *bmp = new BitMapFile;
unsigned int size, offset, headerSize;
// Read input file name.
ifstream infile(filename.c_str(), ios::binary);
// Get the starting point of the image data.
infile.seekg(10);
infile.read((char *) &offset, 4);
// Get the header size of the bitmap.
infile.read((char *) &headerSize,4);
// Get width and height values in the bitmap header.
infile.seekg(18);
infile.read( (char *) &bmp->sizeX, 4);
infile.read( (char *) &bmp->sizeY, 4);
// Allocate buffer for the image.
size = bmp->sizeX * bmp->sizeY * 24;
bmp->data = new unsigned char[size];
// Read bitmap data.
infile.seekg(offset);
infile.read((char *) bmp->data , size);
// Reverse color from bgr to rgb.
int temp;
for (int i = 0; i < size; i += 3)
{
temp = bmp->data[i];
bmp->data[i] = bmp->data[i+2];
bmp->data[i+2] = temp;
}
return bmp;
}
// Load external textures.
void loadExternalTextures()
{
// Local storage for bmp image data.
BitMapFile *image[1];
// Load the texture.
image[0] = getBMPData("Textures/launch.bmp");
// Activate texture index texture[0].
glBindTexture(GL_TEXTURE_2D, texture[0]);
// Set texture parameters for wrapping.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture parameters for filtering.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Specify an image as the texture to be bound with the currently active texture index.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image[0]->sizeX, image[0]->sizeY, 0,
GL_RGB, GL_UNSIGNED_BYTE, image[0]->data);
}
// Routine to load a program-generated image as a texture.
void loadProceduralTextures()
{
// Activate texture index texture[1].
glBindTexture(GL_TEXTURE_2D, texture[1]);
// Set texture parameters for wrapping.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture parameters for filtering.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Specify an image as the texture to be bound with the currently active texture index.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, chessboard);
}
// Create 64 x 64 RGB image of a chessboard.
void createChessboard(void)
{
int i, j;
for (i = 0; i < 64; i++)
for (j = 0; j < 64; j++)
if ( ( ((i/8)%2) && ((j/8)%2) ) || ( !((i/8)%2) && !((j/8)%2) ) )
{
chessboard[i][j][0] = 0x00;
chessboard[i][j][1] = 0x00;
chessboard[i][j][2] = 0x00;
}
else
{
chessboard[i][j][0] = 0xFF;
chessboard[i][j][1] = 0xFF;
chessboard[i][j][2] = 0xFF;
}
}
// Initialization routine.
void setup(void)
{
glClearColor(0.8, 0.8, 0.8, 0.0);
// Create texture index array.
glGenTextures(2, texture);
// Load external texture and generate and load procedural texture.
loadExternalTextures();
createChessboard();
loadProceduralTextures();
// Turn on OpenGL texturing.
glEnable(GL_TEXTURE_2D);
// Specify how texture values combine with current surface color values.
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
// Drawing routine.
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(angle, 0.0, 1.0, 0.0);
// Activate a texture.
glBindTexture(GL_TEXTURE_2D, texture[id]);
// Map the texture onto a square polygon.
glBegin(GL_POLYGON);
glTexCoord2f(0.0, 0.0); glVertex3f(-10.0, -10.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(10.0, -10.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(10.0, 10.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-10.0, 10.0, 0.0);
glEnd();
glutSwapBuffers();
}
// OpenGL window reshape routine.
void resize(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-5.0, 5.0, -5.0, 5.0, 5.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch(key)
{
case 27:
exit(0);
break;
case ' ':
id++;
if (id == 2) id = 0;
glutPostRedisplay();
break;
case 127:
angle = 0.0;
glutPostRedisplay();
break;
default:
break;
}
}
// Callback routine for non-ASCII key entry.
void specialKeyInput(int key, int x, int y)
{
if (key == GLUT_KEY_LEFT)
{
angle -= 5.0;
if (angle < 0.0) angle += 360.0;
}
if (key == GLUT_KEY_RIGHT)
{
angle += 5.0;
if (angle > 360.0) angle -= 360.0;
}
glutPostRedisplay();
}
// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
cout << "Interaction:" << endl;
cout << "Press the left and right arrow keys to rotate the square." << endl
<< "Press space to toggle between textures." << endl
<< "Press delete to reset." << endl;
}
// Main routine.
int main(int argc, char **argv)
{
printInteraction();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("loadTextures.cpp");
setup();
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(keyInput);
glutSpecialFunc(specialKeyInput);
glutMainLoop();
return 0;
}

3ds object is not visible (beginner)

As a part of my project i need to draw some 3d models.
dont have time to learn about 3ds files and how to load them,
which looks to me pretty complicated,
so i found functions on the web,
but the object wont render (or maybe render but not seen).
here is the relevant source code :
void initGL(int *argc, char **argv)
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(width, height);
glutCreateWindow("CUDA Particle System");
GLenum err = glewInit();
if (GLEW_OK != err)
{
printf ("Error: openGL is not supported");
exit (0);
}
glEnable(GL_DEPTH_TEST);
glEnable (GL_CULL_FACE);
glCullFace(GL_FRONT);
glClearColor( 0.7, 0.7 , 0.9 , 0 );
glutReportErrors();
glFrustum(-1,1,-1,1,0.3,100);
Chesspawn.load( &chesspawn ,"chesspawn.3DS");
/*glClear (GL_COLOR_BUFFER_BIT);
glColor3f ( 0.7, 0.7 , 0.9 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,-1,1);
gluLookAt(0,0,0,0,0,-100,0,1,0);
glViewport (250, 250, width, height);*/
}
void display()
{
sdkStartTimer(&timer.timer);
p_system->update(time_Step);
//set Positions vbo
renderer->setVertexBuffer(p_system->getPosVbo(),p_system->getNumParticles());
//render
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// view transform
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, modelView);
gluLookAt (Params_Camera[CAMERA_X], Params_Camera[CAMERA_Y], Params_Camera[CAMERA_Z], // camera
Params_Camera[CAMERA_X] + Params_Camera[DIR_X], Params_Camera[CAMERA_Y] , Params_Camera[CAMERA_Z] + Params_Camera[DIR_Z], // center
0, 1, 0 // up
);
renderer->display();
drawFloor();
glScaled (0.001,0.001,1);
Chesspawn.render(&chesspawn);
//glutSolidSphere (0.5,50,50);
/*glTranslated (0,0,-10);
glutSolidSphere(0.1,20,20);*/
sdkStopTimer(&timer.timer);
glutSwapBuffers();
glutReportErrors();
char sFps[256];
fps = timer.computeFps();
sprintf(sFps, " %s: %d particles %3.1f fps",proc, numParticles, fps);
if (fps <24.0)
printf ("Slow fps : %f \n", fps);
glutSetWindowTitle(sFps);
}
and this is the load and render functions:
static char C_3dsObject::load (obj_type_ptr p_object, char *p_filename)
{
int i; //Index variable
int File_Length = 0;
FILE *l_file; //File pointer
unsigned short l_chunk_id; //Chunk identifier
unsigned int l_chunk_lenght; //Chunk lenght
unsigned char l_char; //Char variable
unsigned short l_qty; //Number of elements in each chunk
unsigned short l_face_flags; //Flag that stores some face information
if ((l_file=fopen (p_filename, "rb"))== NULL)
return 0; //Open the file
fseek (l_file, 0, SEEK_END); // get file length
File_Length = ftell (l_file);
fseek(l_file, 0L, SEEK_SET);
while (ftell (l_file) < File_Length ) //Loop to scan the whole file
{
//getche(); //Insert this command for debug (to wait for keypress for each chuck reading)
fread (&l_chunk_id, 2, 1, l_file); //Read the chunk header
//printf("ChunkID: %x\n",l_chunk_id);
fread (&l_chunk_lenght, 4, 1, l_file); //Read the lenght of the chunk
//printf("ChunkLenght: %x\n",l_chunk_lenght);
switch (l_chunk_id)
{
//----------------- MAIN3DS -----------------
// Description: Main chunk, contains all the other chunks
// Chunk ID: 4d4d
// Chunk Lenght: 0 + sub chunks
//-------------------------------------------
case 0x4d4d:
break;
//----------------- EDIT3DS -----------------
// Description: 3D Editor chunk, objects layout info
// Chunk ID: 3d3d (hex)
// Chunk Lenght: 0 + sub chunks
//-------------------------------------------
case 0x3d3d:
break;
//--------------- EDIT_OBJECT ---------------
// Description: Object block, info for each object
// Chunk ID: 4000 (hex)
// Chunk Lenght: len(object name) + sub chunks
//-------------------------------------------
case 0x4000:
i=0;
do
{
fread (&l_char, 1, 1, l_file);
p_object->name[i]=l_char;
i++;
}while(l_char != '\0' && i<20);
break;
//--------------- OBJ_TRIMESH ---------------
// Description: Triangular mesh, contains chunks for 3d mesh info
// Chunk ID: 4100 (hex)
// Chunk Lenght: 0 + sub chunks
//-------------------------------------------
case 0x4100:
break;
//--------------- TRI_VERTEXL ---------------
// Description: Vertices list
// Chunk ID: 4110 (hex)
// Chunk Lenght: 1 x unsigned short (number of vertices)
// + 3 x float (vertex coordinates) x (number of vertices)
// + sub chunks
//-------------------------------------------
case 0x4110:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->vertices_qty = l_qty;
//printf("Number of vertices: %d\n",l_qty);
for (i=0; i<l_qty; i++)
{
fread (&p_object->vertex[i].x, sizeof(float), 1, l_file);
//printf("Vertices list x: %f\n",p_object->vertex[i].x);
fread (&p_object->vertex[i].y, sizeof(float), 1, l_file);
//printf("Vertices list y: %f\n",p_object->vertex[i].y);
fread (&p_object->vertex[i].z, sizeof(float), 1, l_file);
//printf("Vertices list z: %f\n",p_object->vertex[i].z);
//Insert into the database
}
break;
//--------------- TRI_FACEL1 ----------------
// Description: Polygons (faces) list
// Chunk ID: 4120 (hex)
// Chunk Lenght: 1 x unsigned short (number of polygons)
// + 3 x unsigned short (polygon points) x (number of polygons)
// + sub chunks
//-------------------------------------------
case 0x4120:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->polygons_qty = l_qty;
//printf("Number of polygons: %d\n",l_qty);
for (i=0; i<l_qty; i++)
{
fread (&p_object->polygon[i].a, sizeof (unsigned short), 1, l_file);
//printf("Polygon point a: %d\n",p_object->polygon[i].a);
fread (&p_object->polygon[i].b, sizeof (unsigned short), 1, l_file);
//printf("Polygon point b: %d\n",p_object->polygon[i].b);
fread (&p_object->polygon[i].c, sizeof (unsigned short), 1, l_file);
//printf("Polygon point c: %d\n",p_object->polygon[i].c);
fread (&l_face_flags, sizeof (unsigned short), 1, l_file);
//printf("Face flags: %x\n",l_face_flags);
}
break;
//------------- TRI_MAPPINGCOORS ------------
// Description: Vertices list
// Chunk ID: 4140 (hex)
// Chunk Lenght: 1 x unsigned short (number of mapping points)
// + 2 x float (mapping coordinates) x (number of mapping points)
// + sub chunks
//-------------------------------------------
//----------- Skip unknow chunks ------------
//We need to skip all the chunks that currently we don't use
//We use the chunk lenght information to set the file pointer
//to the same level next chunk
//-------------------------------------------
default:
fseek(l_file, l_chunk_lenght-6, SEEK_CUR);
}
}
fclose (l_file); // Closes the file stream
return (1); // Returns ok
}
void render (obj_type_ptr object)
{
int l_index;
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glMatrixMode(GL_MODELVIEW); // Modeling transformation
glLoadIdentity();
//glTranslatef(0.0,0.0,-500.0);
glColor3d(1,1,0);
// Rotations of the object (the model matrix is multiplied by the rotation matrices)
glRotatef(rotation_x,1.0,0.0,0.0);
glRotatef(rotation_y,0.0,1.0,0.0);
glRotatef(rotation_z,0.0,0.0,1.0);
// TODO: Add your message handler code here
//rotation_x = rotation_x + rotation_x_increment; /////
//rotation_y = rotation_y + rotation_y_increment;
//rotation_z = rotation_z + rotation_z_increment;
if (rotation_x > 359) rotation_x = 0;
if (rotation_y > 359) rotation_y = 0;
if (rotation_z > 359) rotation_z = 0;
// glBegin and glEnd delimit the vertices that define a primitive (in our case triangles)
glBegin(GL_TRIANGLES);
for (l_index=0;l_index < object->polygons_qty;l_index++)
{
//----------------- FIRST VERTEX -----------------
// Coordinates of the first vertex
glVertex3f( object->vertex[ object->polygon[l_index].a ].x,
object->vertex[ object->polygon[l_index].a ].y,
object->vertex[ object->polygon[l_index].a ].z);
//Vertex definition
//----------------- SECOND VERTEX -----------------
// Coordinates of the second vertex
//float x= object.vertex[ object.polygon[l_index].b ].x;
glVertex3f( object->vertex[ object->polygon[l_index].b ].x,
object->vertex[ object->polygon[l_index].b ].y,
object->vertex[ object->polygon[l_index].b ].z);
//----------------- THIRD VERTEX -----------------
// Coordinates of the Third vertex
glVertex3f( object->vertex[ object->polygon[l_index].c ].x,
object->vertex[ object->polygon[l_index].c ].y,
object->vertex[ object->polygon[l_index].c ].z);
}
glEnd();
glutSwapBuffers();
}
what i tried so far:
debuging & checking if the vertices have a valid values:
for the 3ds file that was attached to the code - seems that yes
for other 3ds files i found - no.
trying to scale the object up and down - no result
replacing all the code inside render() with glutSolidSphere(0.5,50,50) - the sphere is visible
as you see in render() i disabled glClear() and glMatrixMode()
thats because i think they not needed,
if enabled they make all other object disapear without seeing the 3ds object.
my questions are:
is load() looks correct?
are there other vertions of 3ds file which not "feet" for this load()?
is there any setting to openGL which i can try to change in order to see the object?
do you know other 3d model format which is simpler to load and yet well distribution
and easy to find, as 3ds is?
do you know other 3d model format which is simpler to load and yet well distribution and easy to find, as 3ds is?
To load objects from 3d studio max, you can try using the obj wavefront format, (there is an option in 3ds max to import in obj format) It is human readable format with triplets of vertex, vertex normals, and vertex textures, which can be easily parsed and passed to glut for rendering.
I wrote some code for loading 3d models, source available here
It parses the obj files and stores the vertices, texture coordinates and normals in arrays which are passed to glut function for rendering
More about the obj format here
If you are beginner for rendering 3d models then don't try 3ds models use obj format. Obj is simple and human readable, simple to understand and write your own parser. You can learn simple tutorials form here and start to write your own parser.

How to show a webcam feed in a Qt GUI application using OpenCv?

I need to show a webcam feed in a Qt GUI application. How do I do it using OpenCv? I've been breaking my head about this since morning. If anyone can show a sample code, I would really appreciate it.
This worked for me:
QImage MatToQImage(const Mat& mat)
{
// 8-bits unsigned, NO. OF CHANNELS=1
if(mat.type()==CV_8UC1)
{
// Set the color table (used to translate colour indexes to qRgb values)
QVector<QRgb> colorTable;
for (int i=0; i<256; i++)
colorTable.push_back(qRgb(i,i,i));
// Copy input Mat
const uchar *qImageBuffer = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8);
img.setColorTable(colorTable);
return img;
}
// 8-bits unsigned, NO. OF CHANNELS=3
if(mat.type()==CV_8UC3)
{
// Copy input Mat
const uchar *qImageBuffer = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return img.rgbSwapped();
}
else
{
qDebug() << "ERROR: Mat could not be converted to QImage.";
return QImage();
}
} // MatToQImage()
....
// Then use it in main code as follows
// Display frame in main window
frameLabel->setPixmap(QPixmap::fromImage(frame));
....

Reading from multiple render targets in DirectX

I have two render target views, my back buffer and a Texture2D that represents a specialized mask (I can't use the stencil buffer for what I need). My render method looks roughly like this:
// clear the render target and depth stencil views, set render targets,
// update subresources, set vertex buffers, topology, input layout, etc.
// draw to the back buffer and the mask
m_d3dContext->PSSetShader(m_pixelShader1.Get(), nullptr, 0);
m_d3dContext->IASetIndexBuffer(m_indexBuffer1.Get(), DXGI_FORMAT_R16_UINT, 0);
m_d3dContext->DrawIndexed(m_indexCount1, 0, 0);
// read from the mask and draw to the back buffer
m_d3dContext->PSSetShader(m_pixelShader2.Get(), nullptr, 0);
m_d3dContext->IASetIndexBuffer(m_indexBuffer2.Get(), DXGI_FORMAT_R16_UINT, 0);
m_d3dContext->DrawIndexed(m_indexCount2, 0, 0);
PixelShader1 looks like this (leaving out the input struct and some other parts):
struct PixelShaderInput
{
float4 Color : COLOR;
float2 Texture : TEXCOORD;
};
struct PixelShaderOutput
{
float4 Color : SV_TARGET0;
float4 Mask : SV_TARGET1;
};
PixelShaderOutput main(PixelShaderInput input)
{
PixelShaderOutput output;
output.Color.rgba = input.Color;
output.Mask.rgba = float4(1, 0, 0, 1);
return output;
}
PixelShader2 looks like this:
struct PixelShaderInput
{
float3 Color : COLOR0;
float2 Texture : TEXCOORD0;
float4 Mask : COLOR1;
};
struct PixelShaderOutput
{
float4 Color : SV_TARGET0;
};
PixelShaderOutput main(PixelShaderInput input)
{
PixelShaderOutput output;
// do some work with input.Texture
if (input.Mask.x == 0)
{
output.Color = float4(0, 0, 0, 1); }
}
else
{
output.Color = float4(1, 1, 1, 1);
}
return output;
}
Using Visual Studio's graphics debugging tools, I can see that the mask texture is written correctly by PixelShader1. At the end of the frame, there is red geometry appearing in the right positions. Further the output to the back buffer (which looks different) is also as expected. So I strongly believe that PixelShader1 is correct.
However, I am getting unexpected results from PixelShader2. Stepping through it, the values for input.Mask.x are all over the place. One would expect them to be either 1 or 0, as that is all the other pixel shader sets them to be, but instead the values look an awful lot like the texture coordinates.
So, first of all, is what I'm trying to do even possible? If it is, can anybody spot my error in how I'm reading COLOR1? I have been stumped by this for hours, so any help would be greatly appreciated.
I'm working in DirectX 11, shader model 4.0 level 9_1, and vc110.
You have a few concepts wrong in how your PixelShader2 is written. PixelShader1 writes to two render textures the values of Color and Mask. In PixelShader 2 you will need to read these values from textures, and not as vertex input.
Texture2D<float4> MaskTexture;
SamplerState MaskSampler;
struct PixelShaderInput
{
float3 Color : COLOR0;
float2 Texture : TEXCOORD0;
};
struct PixelShaderOutput
{
float4 Color : SV_TARGET0;
};
PixelShaderOutput main(PixelShaderInput input)
{
PixelShaderOutput output;
// do some work with input.Texture
float maskValue = MaskTexture.Sample(MaskSampler, Texture).x;
if (maskValue == 0)
{
output.Color = float4(0, 0, 0, 1);
}
else
{
output.Color = float4(1, 1, 1, 1);
}
return output;
}
So in order to do that you will need to pass in MaskTexture (this is your second render target output from PixelShader1) as a ShaderResource, via SetShaderResources(). You will also need to create a SamplerState and set that into the device also via SetSamplerStates().

Capture screenshot of OpenGL/Direct3D 3rd party application

I want to capture the contents (client area) of a window, in my VS2008, MFC, C++ project. I have tried using the PrintWindow technique described here:
How to get screenshot of a window as bitmap object in C++?
I have also tried blitting the contents of the window using the following code:
void captureWindow(int winId)
{
HDC handle(::GetDC(HWND(winId)));
CDC sourceContext;
CBitmap bm;
CDC destContext;
if( !sourceContext.Attach(handle) )
{
printf("Failed to attach to window\n");
goto cleanup;
}
RECT winRect;
sourceContext.GetWindow()->GetWindowRect(&winRect);
int width = winRect.right-winRect.left;
int height = winRect.bottom-winRect.top;
destContext.CreateCompatibleDC( &sourceContext );
if(!bm.CreateCompatibleBitmap(&sourceContext, width, height)) {
printf("Failed to create bm\n");
goto cleanup;
}
{
//show a message in the window to enable us to visually confirm we got the right window
CRect rcText( 0, 0, 0 ,0 );
CPen pen(PS_SOLID, 5, 0x00ffff);
sourceContext.SelectObject(&pen);
const char *msg = "Window Captured!";
sourceContext.DrawText( msg, &rcText, DT_CALCRECT );
sourceContext.DrawText( msg, &rcText, DT_CENTER );
HGDIOBJ hOldDest = destContext.SelectObject(bm);
if( hOldDest==NULL )
{
printf("SelectObject failed with error %d\n", GetLastError());
goto cleanup;
}
if ( !destContext.BitBlt( 0, 0, width, height, &sourceContext, 0, 0, SRCCOPY ) ){
printf("Failed to blit\n");
goto cleanup;
}
//assume this function saves the bitmap to a file
saveImage(bm, "capture.bmp");
destContext.SelectObject(hOldDest);
}
cleanup:
destContext.DeleteDC();
sourceContext.Detach();
::ReleaseDC(0, handle);
}
The code works fine for most applications. The specific application where I need to capture the screenshot however, has a window that I think is rendered using OpenGl or Direct3D. Both methods will capture most of the app just fine, but the "3d" area will be left black or garbled.
I do not have access to the application code, so I cannot change it in any way.
Is there any way to capture all the contents, including the "3d" window?
The data in your 3D area is generated by the graphics adapter further down the graphics funnel and may not be available to your application to read the byte data from the rendering context. In OpenGL you can can use glReadPixels() to pull that data back up the funnel into your application memory. See here for usage:
http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml

Resources