Flickering Displlay rendering

Started by
5 comments, last by hahaha 16 years, 9 months ago
Im using opengl c++ and win32. Ive modified nehes opengl tutorial on rendering an AVI video. I changed two things: 1) It draws directly to the global HDC 2) It draws with glVertex2f not glVertex3f so that i can use it in orthographic modes. Everything works fine except the video flickers a lot when rendering heres the code(ive wrapped it up into an easy class for me):

Cavi.h
#ifndef AVI_H
#define AVI_H
#include "Main.h" // Includes All Headers and declaration of global //HINSTANCE,HDC,HWND etc...
typedef void (*CallBack)();
class CAvi
{
    private:
        int			next;												
        int			frame;															
        AVISTREAMINFO		psi;										
        PAVISTREAM			pavi;										
        PGETFRAME			pgf;										
        BITMAPINFOHEADER	bmih;										
        long				lastframe;									
        int					width;										
        int					height;										
        char				*pdata;										
        int					mpf;										
        GLUquadricObj *quadratic;										
        HDRAWDIB hdd;													
        HBITMAP hBitmap;												
        HDC hdc;								
        unsigned char* data;
        CallBack CB;		    
    public:
        CAvi();
        ~CAvi();
        void flipIt(void* buffer);
        void OpenAVI(LPCSTR szFile);
        void GrabAVIFrame(int frame);
        void CloseAVI(void);
        bool Init();
        void SetCB(CallBack cb);
        void Deinitialize (void);
        void Update (DWORD milliseconds);
        void Draw();												
};
#endif

CAvi.cpp
#include "CAvi.h"

CAvi::CAvi()
{
    hdc = CreateCompatibleDC(0);
    data = 0;
}
CAvi::~CAvi(){}
void CAvi::SetCB(CallBack cb)
{
     CB = cb;
}
void CAvi::flipIt(void* buffer)										
{
	unsigned char *b = (BYTE *)buffer;                          
	
	char temp;
    for(int i = 0; i < 256*256*3; i+=3)                         
	{
	    temp = b;                                            
 	    b = b[i+2];                                          
 	    b[i+2] = temp;                                          
    }
}								
void CAvi::OpenAVI(LPCSTR szFile)										
{
	TCHAR	title[100];											
	AVIFileInit();												
	if (AVIStreamOpenFromFile(&pavi, szFile, streamtypeVIDEO, 0, OF_READ, NULL) !=0)
	       PostQuitMessage(0);
	AVIStreamInfo(pavi, ψ, sizeof(psi));						
	width=psi.rcFrame.right-psi.rcFrame.left;					
	height=psi.rcFrame.bottom-psi.rcFrame.top;					
	lastframe=AVIStreamLength(pavi);							
	mpf=AVIStreamSampleToTime(pavi,lastframe)/lastframe;		
	bmih.biSize = sizeof (BITMAPINFOHEADER);					
	bmih.biPlanes = 1;											
	bmih.biBitCount = 24;										
	bmih.biWidth = 256;											
	bmih.biHeight = 256;										
	bmih.biCompression = BI_RGB;								
	hBitmap = CreateDIBSection (hdc, (BITMAPINFO*)(&bmih), DIB_RGB_COLORS, (void**)(&data), NULL, 0);
	SelectObject (hdc, hBitmap);								
	pgf=AVIStreamGetFrameOpen(pavi, NULL);						
	if (pgf==NULL)PostQuitMessage(0);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, data);					
}
void CAvi::GrabAVIFrame(int frame)									
{
	LPBITMAPINFOHEADER lpbi;									
	lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, frame);	
	pdata=(char *)lpbi+lpbi->biSize+lpbi->biClrUsed * sizeof(RGBQUAD);	
	DrawDibDraw (hdd,g_hDC, 0, 0, 800,600, lpbi, pdata, 0, 0,width,height, 0);
	flipIt(data);												
	glTexSubImage2D(GL_TEXTURE_2D,0,0,0,800,600,GL_RGB,GL_UNSIGNED_BYTE,data);
}
void CAvi::CloseAVI(void)												
{
	DeleteObject(hBitmap);										
	DrawDibClose(hdd);											
	AVIStreamGetFrameClose(pgf);								
	AVIStreamRelease(pavi);										
	AVIFileExit();												
}
bool CAvi::Init()
{
    hdd = DrawDibOpen();
    return true;	 
}
void CAvi::Deinitialize (void)										
{
	CloseAVI();													
}
void CAvi::Update (DWORD milliseconds)								
{											
	next+=milliseconds;											
	frame=next/mpf;												
	if (frame>=lastframe)										
	{
		frame=0;												
		next=0;	
        CB();												
	}
}
void CAvi::Draw (void)												
{	
	GrabAVIFrame(frame);																				
	glBegin(GL_QUADS);										
		glTexCoord2f(1.0f, 1.0f); glVertex2f(0,0);
		glTexCoord2f(0.0f, 1.0f); glVertex2f(-11.0f,0);
		glTexCoord2f(0.0f, 0.0f); glVertex2f(-11.0f,-8.3f);
		glTexCoord2f(1.0f, 0.0f); glVertex2f(0, -8.3f);
	glEnd();																								
}

please can someone help me find whats going wrong here and why its flickering thanks
Advertisement
Does the whole scene flicker or only the animation??
Are you using double buffering?Is V-sync on or off?
What does CB do by the way?(just being curios[grin])
0) Drawing to the "global" DC is probably part of the problem, as it implies you aren't buffering anything and are competing with everything else drawing there (the OS). Don't do that. It's not "faster."

1) There's no such thing as "orthographic mode." You can have an orthographic projection matrix assigned, but this is still just a transformation in 3D space. You're still using 3D coordinates; glVertex2f(x,y) is the same as glVertex3f(x,y,0).

2) Main.h kind of global headers are usually a bad idea if they #include anything else, in more complex projects they can cause a translation unit to fail to compile because of include ordering.
Sorry CB is just a pointer to a function i created to let the game know the video is finished...

Double buffering is on but If i dont draw to the global HDC then what else do I draw to?
If I draw to the original HDC (hdc) in the tutorial nothing happens
I couldn't tell you, since I don't know anything about rendering AVIs. I can tell you that drawing to the global HDC is probably wrong, and that just because the other option doesn't work doesn't mean the original option is the correct way. Focus on finding out why the original way doesn't work, because presumably it works in the tutorial.
i changed it to draw to hdc not g_hDC and use glDrawPixels to draw the image created by drawing to hdc. It doesnt flicker now and the color is right.

Thanks for the help everyone

This topic is closed to new replies.

Advertisement