SuperDindon pseudonyme obsolète | Bonjour à tous j'ai un blème avec le morceau de code ci-dessous. J'explique vite fait, l'intérêt n'est pas de comprendre le code mais de comprendre le problème : basiquement je propose deux méthodes pour dessiner des surfaces à l'écran, la plus simple charge la surface entière quelle que soit la portion qui nous intéresse ( SourceRectangle ) ( par ex. si on veut seulement afficher un rectangle 256x256 d'une surface 1024x1024 on chargera quand même entièrement la surface 1024x1024 ) puis dessine un seul quad et la seconde plus complexe divise la surface en plusieurs morceaux et colle plusieurs quads pour reformer le quad qu'on veut dessiner. Le rendu en utilisant la première méthode est nickel mais avec la seconde j'ai un petit problème de corruption plus ou moins aléatoire ( et ça scintille ) lorsque je dessine plusieurs rectangles de la même surface, ils se pompent les uns sur les autres comme on le voit bien sur ces captures :
http://moigeeknevro.com/wine/capture16.png
http://moigeeknevro.com/wine/capture17.png
Bon là encore c'est pas très embêtant, mais d'en d'autres cas c'est complètement illisible. La seconde méthode utilise en fait une "texture tampon" qu'on reremplit avec glTexSubImage2D à chaque fois qu'on dessine un nouveau morceau /ou une nouvelle portion ( suffit de jeter un coup d'oeil au code pour comprendre ). Ma question est : je suis assez nouveau en 3D, est-ce que glTexSubImage2D a besoin qu'on lui laisse le tampon ( ici bltBuffer ) pendant un certain temps ? J'ai essayé de placer des glFinish un peu partout pour voir mais ça n'a pas aidé. Quelqu'un qui connaît bien le fonctionnement de glTexSubImage2D et des drivers/matos ( j'ai le problème avec r200 dri et fglrx avec une 9250 sous Linux ) peut me dire ce qui ne va pas ?
edit : bon tout compte fait spa très clair tout ça je vais essayer de reproduire le problème avec un exemple plus simple edit 2 : ah ben en réalité la première méthode marche correctement avec fglrx , je me suis démené pour rien
Code :
- if(splitDrawing) {
- /* The trick is : we split the surface into 128x128,256x256,whatever
- * squares then we draws multiple quads. This helps to upload and bind only
- * needed portions of (especially full-dirty and/or full-screen) surfaces
- * and also will someday take advantage of asynchronous texture uploads
- * ( upload/draw the quad while we convert another portion ).
- * NOTE: the quad size doesn't depend on the rectangle size because this will
- * complexify the code and eat more memory without notable performance boost. */
- /* TODO: There should be a reasonable balance between dirtyfying rate,
- * surface/rect ratio and the drawing method.
- * ( e.g when a surface is never dirtyfied and the rect is not too
- * smaller than the surface size basic drawings should be at least as fast )
- * For instance remember the blts count ( !! max one per frame ) performed
- * since the last dirtyfying */
- d3dfmt_get_conv(Src, (Flags & DDBLT_KEYSRC)?TRUE:FALSE, TRUE, &format, &internal, &type, &convert, &bpp);
- /* Allocate the buffer */
- if(Src->bltBuffer == NULL) /*FIXME: check bpp*/{
- Src->bltBuffer = HeapAlloc(GetProcessHeap(), 0, QUAD_SIZE*QUAD_SIZE*bpp);
- glGenTextures(1, &Src->bltBufferTextureName);
- glBindTexture(GL_TEXTURE_2D, Src->bltBufferTextureName);
- checkGLcall("glBindTexture" );
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- checkGLcall("glTexParameteri" );
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- checkGLcall("glTexParameteri" );
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- checkGLcall("glTexParameteri" );
- glTexImage2D(GL_TEXTURE_2D, 0, internal,
- QUAD_SIZE, QUAD_SIZE, 0,
- format, type, NULL);
- checkGLcall("glTexImage2D" );
- }
- /* FIXME: redundant.. */
- glBindTexture(GL_TEXTURE_2D, Src->bltBufferTextureName);
- checkGLcall("glBindTexture" );
- } else {
- /* Now load the surface */
- IWineD3DSurface_PreLoad((IWineD3DSurface *) Src);
- /* Bind the texture */
- glBindTexture(GL_TEXTURE_2D, Src->glDescription.textureName);
- checkGLcall("glBindTexture" );
- /* No filtering for blts */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- checkGLcall("glTexParameteri" );
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- checkGLcall("glTexParameteri" );
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- checkGLcall("glTexParameteri" );
- }
- glColor3d(1.0f, 1.0f, 1.0f);
- if(splitDrawing) {
- int x,y,i;
- UINT pitch = IWineD3DSurface_GetPitch(SrcSurface);
- int width, height;
- float x_stretch, y_stretch;
- width = SourceRectangle.right - SourceRectangle.left;
- height = SourceRectangle.bottom - SourceRectangle.top;
- x_stretch = (float) (rect.x2 - rect.x1) / (float) width;
- y_stretch = (float) (rect.y2 - rect.y1) / (float) height;
- glTexCoord[0] = 0.0;
- glTexCoord[2] = 0.0;
- glPixelStorei(GL_UNPACK_ROW_LENGTH, QUAD_SIZE);
- checkGLcall("glPixelStorei" );
- for (y = 0; y < height; y += QUAD_SIZE) {
- UINT flush_height;
- if(y + QUAD_SIZE > height) {
- flush_height = height - y;
- glTexCoord[3] = (float) flush_height / (float) QUAD_SIZE;
- } else {
- flush_height = QUAD_SIZE;
- glTexCoord[3] = 1.0;
- }
- for (x = 0; x < width; x += QUAD_SIZE) {
- UINT flush_width;
- BYTE *srcRow = Src->resource.allocatedMemory + ((SourceRectangle.left+x)*bpp) + ((SourceRectangle.top+y)*pitch);
- if(x + QUAD_SIZE > width) {
- flush_width = width - x;
- glTexCoord[1] = (float) flush_width / (float) QUAD_SIZE;
- } else {
- flush_width = QUAD_SIZE;
- glTexCoord[1] = 1.0;
- }
- for (i = 0; i < flush_height; i++, srcRow += pitch) /* row by row */
- d3dfmt_convert_surface(srcRow, Src->bltBuffer + (i*QUAD_SIZE*bpp),
- flush_width, convert, Src);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
- flush_width, flush_height,
- format, type, Src->bltBuffer);
- checkGLcall("glTexSubImage2D" );
- glBegin(GL_QUADS);
- glTexCoord2f(glTexCoord[0], glTexCoord[2]);
- glVertex3f(rect.x1 + (x * x_stretch),
- rect.y1 + (y * y_stretch),
- 0.0);
- glTexCoord2f(glTexCoord[0], glTexCoord[3]);
- glVertex3f(rect.x1 + (x * x_stretch),
- rect.y1 + ((y + flush_height) * y_stretch),
- 0.0);
- glTexCoord2f(glTexCoord[1], glTexCoord[3]);
- glVertex3f(rect.x1 + ((x + flush_width) * x_stretch),
- rect.y1 + ((y + flush_height) * y_stretch),
- 0.0);
- glTexCoord2f(glTexCoord[1], glTexCoord[2]);
- glVertex3f(rect.x1 + ((x + flush_width) * x_stretch),
- rect.y1 + (y * y_stretch),
- 0.0);
- glEnd();
- checkGLcall("glEnd" );
- }
- }
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- checkGLcall("glPixelStorei" );
- } else {
- /* Draw a textured quad */
- glBegin(GL_QUADS);
- glTexCoord2f(glTexCoord[0], glTexCoord[2]);
- glVertex3f(rect.x1,
- rect.y1,
- 0.0);
- glTexCoord2f(glTexCoord[0], glTexCoord[3]);
- glVertex3f(rect.x1, rect.y2, 0.0);
- glTexCoord2f(glTexCoord[1], glTexCoord[3]);
- glVertex3f(rect.x2,
- rect.y2,
- 0.0);
- glTexCoord2f(glTexCoord[1], glTexCoord[2]);
- glVertex3f(rect.x2,
- rect.y1,
- 0.0);
- glEnd();
- checkGLcall("glEnd" );
- }
|
Message édité par SuperDindon le 30-08-2006 à 07:00:33
|