Estoy haciendo una clase en C++ que representara una imagen. La idea es crear un DC y un BITMAP que se le agregara con un SelectObject(), el problema es que no consigo crear un DC a mi gusto. Si uso algo como CreateCompatibleDC(NULL) me crea un DC para memoria(que es lo que busco,claro) pero compatible con el modo grafico de windows, es decir, cuando haga un CreateBitmap() debera tener la misma profundidad de color que windows en ese momento si es de 32bits no podre asociarle un BITMAP creado con 16bits de color.
Existe la posibilidad de usar CreateCompatibleBitmap() claro, pero se creara con la profundidad de color de windows en ese momento, no??
Por eso necesito un DC hacho a medida y pense en usar CreateDC(), pero es realmente complejo y toda la documentacion que encuentro parecen conformarse con CreateCompatibleDC(). Si uso CreateDC(), solo me funciona si pongo "DISPLAY" como primer parametro, lo cual crea un DC para display y lo quiero para memoria, si dejo en NULL el primer parametro y trato de pasarle un DEVMODE en el ultimo no consigo crearlo, los parametros que le pongo en DEVMODE son los siguientes:
DEVMODE devModeInfo;
ZeroMemory(&devModeInfo,sizeof(DEVMODE));
devModeInfo.dmSize=sizeof(DEVMODE);
devModeInfo.dmBitsPerPel=32;
devModeInfo.dmPelsWidth=800;
devModeInfo.dmPelsHeight=600;
devModeInfo.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
Como puedo crear un DC a mi gusto?!?! y si no es posible, si creo un CreateCompatibleDC(NULL), como puedo matenerlo con un BITMAP a mi "gusto"??
Son preguntas algo elementales, pero el API de windows no es mi lugar habitual, gracias.
Saludos.
pues da la casualidad de que yo estoy liado con este tema de creacion de texturas i no e probador eso, ahora lo probare haber que pasa.
Yo creo un DC con
dcSuperficie.CreateCompatibleDC(NULL);
y luego creo el bitmap con:
char *pBufSuperficie;
BITMAPINFO bmi;
ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
bmi.bmiHeader.biWidth=ancho;
bmi.bmiHeader.biHeight=alto;
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=24;
bmi.bmiHeader.biSizeImage=0;
bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biClrUsed= 0;
bmi.bmiHeader.biClrImportant= 0;
m_hBitmap= CreateDIBSection(dcSuperficie.m_hDC,&bmi,DIB_RGB_COLORS,(void**)&pBufSuperficie,NULL,0);
dcSuperficie.SelectObject(m_hBitmap);
en pBufSuperficie tengo el puntero a la memoria del bitmap. Yo siempre hago bitmaps de 24 bits, aunque el escritorio esté a bpp diferentes, así que no he probado mucho con bitmaps de 16 bits.
un saludo
puedes crear el bitmap con CreateCompatibleBitmap o algo asi era ;)
para crear DC a tu gusto tienes que usar CreateIC o CreateDC
saludos
Es que CreateCompatibleBitmap(), no me lo permite crear al gusto.
fiero ha dado en el clavo, esta probado, gracias a todos!
Saludos.
pero si pintas en formatos de bpp diferentes al del escritorio el rendimiento te bajara ya que windows realizara una conversion de "x bpp" a "escritorio bpp" bajo manga, si lo que quieres es velocidad al pintar te recomiendo usar el mismo bpp que el escritorio recuerda que no es lo mismo mover x memoria del tiron que mover x y saltarse x y mover x .....
no se si me he explicado bien, venga saludos
Si, pero el bliteo de superficies windows lo suele hacer por hardware siempre que puede, así que no merece la pena. Yo decidí utilizar solo bitmaps de 24 bits cuando uso DCs porque el trabajo con ellos a la hora de hacer blendings, filtros y demás historias en ensamblador era más rápido que hacerlo con mapas de 16 bits. Si hay que manejar pixels uno a uno es más lento andar descomponiendo los RGB de 16 bits. Pero, vaya esto a gusto del consumidor...
un saludo
siento decirte que el gdi es puro software de toda la vida, si quieres hardware tienes que usar opengl o directx
Entiendo lo que decis, pero deseo mantener las propiedades de la imagen independiente de lo demas.
Respecto a lo de la aceleracion por hardware, yo juraria que si que acelera las operaciones de dibujo de windows, es mas antiguamente algunas targetas (targetas S3 y demas engendros), se vendian como tal cosa, como tagertas que aceleraban las funciones de dibujo de windows. Pero de todas formas eso ya es otro tema.
Saludos.
umm si es cierto lo que dices que puede serlo 100% real ya que yo no he hecho windows :D, al pintar con directdraw o direct3d iria a la misma velocidad que pintar sobre un dc y esto no sucede, pintar en un dc es algo lentisimo y no te digo pintar con mascara de color (asco), si es por hardware ocurriria el mismo problema pero le pasariamos la pelota a la tarjeta grafica
ademas se supone que el nuevo windows utilizara para el escritorio directx con lo que entonces el xp y antecesores no lo debe de estar haciendo, a no ser que claro nos quieran vender la moto o microsoft o las tarjetas graficas antiguas <_<
A mi me va a la misma velocidad usando GDI que usando DirectX (Con las superficies en memoria de sistema). Lo que va por hardware en algunas tarjetas (a mi entender) es el CDC::BitBlt, no las funciones de pintar cosas. En la ayuda de dicha función pone claramente que no es soportada por algunas tarjetas gráficas; si fuera por software no tendría que poner tal cosa, ya que sería soportada por todas. En resumen, creo que lo que hacian las s3 y compañía por harware era el bliteo y consiguiente conversión de formato de las superficies.
Otra cosa muy diferente es que DirectX te permite crear las superficies en memoria de video, lo cual no se puede hacer con GDI. De esta forma el bliteo es mucho más rápido, pero no quiere decir que GDI no esté usando las capacidades hardware de las tarjetas, sólo que al utilizar superficies en RAM de sistema es más lento.
Hay poca info al respecto.
un saludo
hay una mencion diciendo que la funcion hace la conversion que es lo que importa pero no dice si es por soft o hard simplemente dice que la funcion BitBlt convierte el origen al formato del destino, osea que tiembla (uoh) puede que lo haga hasta el condensador gimnasticu oculto de los microprocesadores :P
CitarIf destination, source, and pattern bitmaps do not have the same color format, the BitBlt function converts the source and pattern bitmaps to match the destination
Una posible pregunta tonta.
Puedo usar el puntero pBufSuperficie, de la funcion CreateDIBSection(), para acceder directamente a los datos de color de la imagen? o he de tomar alguna "precaucion"?
Es que al probarlo, diria que la informacion de la imagen empieza al final de esta, es decir al enviar X bytes en serie desde donde apunta ese puntero se ve como se a rellenado desde abajo a arriba.
Gracias!!Saludos.
A ver si puede ser por esto (sacado de la MSDN en referencia a la estructura
BITMAPINFOHEADER):
CitarbiHeight
Specifies the height of the bitmap, in pixels. If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, the bitmap is a top-down DIB and its origin is the upper-left corner.
Eso podría explicar que cuando empiezas a escribir los datos en el bitmap, empiece desde abajo.
Saludos.
Ostras! pues si, no si se dar las gracias o pedir directamente disculpas, se me paso completamente.
Gracias.
CitarPuedo usar el puntero pBufSuperficie, de la funcion CreateDIBSection(), para acceder directamente a los datos de color de la imagen? o he de tomar alguna "precaucion"?
ese puntero es la zona de memoria donde se guarda la imagen del bitmap, puedes acceder a ella sin mas, lo unico que tienes que tener en cuenta es que el ancho de los bitmaps es siempre multiplo de 4, para calcular la suma entre salto de linea del bitmap puedes utilizar esta formula: (anchoimage % 4) y si le sumas a este resultado su ancho te dara en bytes el salto de linea total
CitarEs que al probarlo, diria que la informacion de la imagen empieza al final de esta, es decir al enviar X bytes en serie desde donde apunta ese puntero se ve como se a rellenado desde abajo a arriba.
los bmps siempre se guardan a la inversa, si lees directamente un archivo bmp del disco veras que siempre ocurre esto, para solucionar esto al crear el bitmap puedes indicarle un alto negativo y asi darle la vuelta
saludos
pd: he probado la velocidad del bitblt y me va mas lenta que usando surfaces de directx en memoria, ademas despues de probar varias veces los bitmaps de 32bpp son los mas rapidos sin importar el bpp del escritorio con lo que que sin duda alguna todo el gdi de windows va por software, la imagen con la que probe fue 1024x768, gdi con bitblt 14fps y directx 82fps