2008-11-06 87 views
0

放大視圖儘管前面一個問題(asked here),我們的項目被限制使用glDrawPixels,所以我們必須做一些兩輪牛車。glDrawPixels/glCopyPixels獲得生產嚴重夾緊圖像

之一特徵的要求是能夠以具有放大視圖顯示在圖像的點擊區域;所以,看着圖像,我想點擊鼠標,並有一個200%的圖像窗口顯示鼠標的位置。當我拖動光標時,窗口應該跟隨光標。

上下文設置如下:

大紅書有代碼看起來像這樣:

 Gl.glShadeModel(Gl.GL_FLAT); 
     Gl.glClearColor(0.1f, 0.1f, 0.1f, 0.0f); 
     Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 2); 
     Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_LINE); 

     Gl.glDisable(Gl.GL_SCISSOR_TEST); 
     Gl.glDisable(Gl.GL_ALPHA_TEST); 
     Gl.glDisable(Gl.GL_STENCIL_TEST); 
     Gl.glDisable(Gl.GL_DEPTH_TEST); 
     Gl.glDisable(Gl.GL_BLEND); 
     Gl.glDisable(Gl.GL_DITHER); 
     Gl.glDisable(Gl.GL_LOGIC_OP); 
     Gl.glDisable(Gl.GL_LIGHTING); 
     Gl.glDisable(Gl.GL_FOG); 
     Gl.glDisable(Gl.GL_TEXTURE_1D); 
     Gl.glDisable(Gl.GL_TEXTURE_2D); 
     Gl.glPixelTransferi(Gl.GL_MAP_COLOR, Gl.GL_TRUE); 
     Gl.glPixelTransferf(Gl.GL_RED_SCALE, 1.0f); 
     Gl.glPixelTransferi(Gl.GL_RED_BIAS, 0); 
     Gl.glPixelTransferf(Gl.GL_GREEN_SCALE, 1.0f); 
     Gl.glPixelTransferi(Gl.GL_GREEN_BIAS, 0); 
     Gl.glPixelTransferf(Gl.GL_BLUE_SCALE, 1.0f); 
     Gl.glPixelTransferi(Gl.GL_BLUE_BIAS, 0); 
     Gl.glPixelTransferi(Gl.GL_ALPHA_SCALE, 1); 
     Gl.glPixelTransferi(Gl.GL_ALPHA_BIAS, 0); 

然後調用使較小但縮放的圖像看起來像

 int width = (int)((this.Width * 0.2)/2.0); 
     Gl.glReadBuffer(Gl.GL_FRONT_AND_BACK); 
     Gl.glRasterPos2i(0, 0); 
     Gl.glBitmap(0, 0, 0, 0, mStartX - (width*2), mStartY, null); 

     Gl.glPixelZoom(2.0f, 2.0f); 
     Gl.glCopyPixels(mStartX - width, mStartY, width, width, Gl.GL_COLOR); 

其中mStartY和mStartX在哪裏點擊發生的點。

問題是,出現的窗口確實會弄亂查找表,並且真正將圖像固定爲黑白二進制圖像(即,沒有灰色陰影)。

的數據是黑色和白色的無符號短陣列,並且被設定爲這樣的代碼:

 float step = (65535.0f/(float)(max - min)); 
     mColorTable = new ushort[65536]; 
     int i; 
     for (i = 0; i < 65536; i++) 
     { 
      if (i < min) 
       mColorTable[i] = 0; 
      else if (i > max) 
       mColorTable[i] = 65535; 
      else 
       mColorTable[i] = (ushort)((float)(i - min) * step); 
     }  
     .... //some irrelevant code 

     Gl.glPixelMapusv(Gl.GL_PIXEL_MAP_R_TO_R, 65536, mColorTable); 
     Gl.glPixelMapusv(Gl.GL_PIXEL_MAP_G_TO_G, 65536, mColorTable); 
     Gl.glPixelMapusv(Gl.GL_PIXEL_MAP_B_TO_B, 65536, mColorTable); 

現在,根據this documentation,應該使用GL_PIXEL_MAP_I_TO_I並設置INDEX_SCALE和INDEX_BIAS到零,但這樣做不會改變結果,圖像被嚴重夾住。 「嚴重夾住」我的意思是黑色或白色,灰色很少,但原始未放大的圖像看起來像預期的那樣。

那麼,如何避免放大顯示的夾緊?我應該在光標後面做第二個控件,並使用第一個控件的數據填充它嗎?這種方法看起來好像將圖形卡之外的陣列副本放入C#中,這幾乎是定義較慢,因此使控制無響應。

哦,我正在使用C#和Tao框架,如果這很重要。

回答

2

答案如下。問題是,LUT是被應用了兩次,所以調用副本之前,請致電:

Gl.glPixelTransferi(Gl.GL_MAP_COLOR, Gl.GL_FALSE); 

然後,一旦完成,致電:

Gl.glPixelTransferi(Gl.GL_MAP_COLOR, Gl.GL_TRUE); 

這樣一來,「極端夾緊」我是描述被刪除。

@ thing2k--您的解決方案會導致複製發生在圖形卡之外,因此拖慢鼠標拖動時的繪圖速度,但不能修復雙重鉗位。

0

請,用糖,糖漿,灑負荷和高果糖玉米糖漿的頂部霧,並且將遍佈拜託,解釋爲什麼你不能只用紋理映射繪製此圖像。

紋理映射是OpenGL的核心,基本,日常運行,花園多樣,標準,典型,預期和一般的漂亮功能。它在版本1.4中。爲什麼不把它作爲一個起點?

+0

因爲我們不能 - 我們試過了。我們必須支持的各種圖形硬件顯然不允許我們需要做的事情。我們試過了,在任何機器上約五分鐘後,內存損壞變得非常糟糕,我們必須重新啓動程序。 – mmr 2008-11-06 16:10:37

0

如果我正確理解你,那麼這應該是接近你後,使用glReadPixels和glDrawPixels。

對不起它的C++而不是C#,但OpenGL的功能應該仍然是相同的。

// main.cpp 
// glut Text 

#ifdef __WIN32__ 
    #define WIN32_LEAN_AND_MEAN 
    #include <windows.h> 
#endif 
#include <GL/glut.h> 
#include <cstdio> 

int WIDTH = 800; 
int HEIGHT = 600; 
int MouseButton, MouseY = 0, MouseX = 0; 
const int size = 80; 
char *image, rect[size*size*3]; 
int imagewidth, imageheight; 

bool Init() 
{ 
    int offset; 
    FILE* file = fopen("image.bmp", "rb"); 
    if (file == NULL) 
     return false; 
    fseek(file, 10, SEEK_SET); 
    fread(&offset, sizeof(int), 1, file); 
    fseek(file, 18, SEEK_SET); 
    fread(&imagewidth, sizeof(int), 1, file); 
    fread(&imageheight, sizeof(int), 1, file); 
    fseek(file, offset, SEEK_SET); 
    image = new char[imagewidth*imageheight*3]; 
    if (image == NULL) 
     return false; 
    fread(image, 1, imagewidth*imageheight*3, file); 
    fclose(file); 
    return true; 
} 

void Reshape(int width, int height) 
{ 
    WIDTH = width; 
    HEIGHT = height; 
    glViewport(0 , 0, width, height); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluOrtho2D(0, width, 0, height); 
} 

void Display() 
{ 
    int size2 = size/2; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glRasterPos2i(0,0); 
    glPixelZoom(1.f, 1.f); 
    glDrawPixels(imagewidth, imageheight, 0x80E0/*GL_RGB*/, GL_UNSIGNED_BYTE, image); 
    glReadPixels(MouseX-size2, MouseY-size2, size, size, GL_RGB, GL_UNSIGNED_BYTE, rect); 
    glPixelZoom(2.f, 2.f); 
    glRasterPos2i(MouseX-size, MouseY-size); 
    glDrawPixels(size, size, GL_RGB, GL_UNSIGNED_BYTE, rect); 
    glFlush(); 
    glutSwapBuffers(); 
} 

void Mouse(int button, int state, int x, int y) 
{ 
    if (state == GLUT_DOWN) 
     MouseButton &= (1<<button); 
    else 
     MouseButton &= ~(1<<button); 
} 

void MouseMove(int x, int y) 
{ 
    MouseX = x; 
    MouseY = HEIGHT - y; 
} 

int main(int argc, char* argv[]) 
{ 
    glutInit(&argc, argv); 
    if (Init() == false) 
     return 1; 
    glutInitWindowSize(WIDTH, HEIGHT); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); 
    glutCreateWindow("glut_Text"); 
    glClearColor(0.25, 0.25, 0.25, 1.0); 
    glutReshapeFunc(Reshape); 
    glutDisplayFunc(Display); 
    glutIdleFunc(Display); 
    glutMouseFunc(Mouse); 
    glutMotionFunc(MouseMove); 
    glutPassiveMotionFunc(MouseMove); 

    glutMainLoop(); 
    return 0; 
} 

希望這會有所幫助。