2010-11-30 5 views
9

Sizin bir çoğunuz Qt (4.6 özellikle) kullanıcıları OpenGL eğiticileriyle sağlanan Overpainting örneğine aşina olacaklardır, çok benzer şeyler yapmaya çalışıyorum ama saf OpenGL için gölgelendiriciler kullanıyorum Eski sabit işlevli boru hattı yerine veriler.Shader kullanırken QGLWidget içinde QGaWidget üzerinde QPainter'ı kullanma

// Set background and state. 
makeCurrent(); 
qglClearColor(bgColour_); 

glEnable(GL_DEPTH_TEST); 
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 

if (smoothLines_) { 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glEnable(GL_LINE_SMOOTH); 
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 
} 

// Clear the buffers. 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glUseProgram(shader_); 

// Draw the grid. 
try { 
    glLineWidth(2.0f); 
    manager_->setColour(centreColour_); 
    grid_->draw(oE_GLGrid::Centre); 

    glLineWidth(1.5f); 
    manager_->setColour(majorColour_); 
    grid_->draw(oE_GLGrid::Major); 

    glLineWidth(1.0f); 
    manager_->setColour(minorColour_); 
    grid_->draw(oE_GLGrid::Minor); 
} catch(oE_GLException& e) { 
    cout << "OpenGL Error: " << e.what() << endl; 
    return; 
} 

// Reset OpenGL state for overlays. 
glDisable(GL_DEPTH_TEST); 
if (smoothLines_) { 
    glDisable(GL_BLEND); 
    glDisable(GL_LINE_SMOOTH); 
} 

// Draw the overlays. 
QPainter p(this); 
p.beginNativePainting(); 
p.fillRect(10, 10, 100, 100, 
     QColor(255, 0, 0)); 
p.endNativePainting(); 

Bu nedenle, bir 3D varlık uygulaması yapıyorum. Çalışırken gerçekten belirgin hale getirmek için, widget'ın sol üst köşesinde büyük bir kırmızı dikdörtgen görünmelidir - ancak öyle değil.

3D çalışıyor, ancak QPainter ekrana hiçbir şey alamaz. Benim ve dokümanlar arasında görebildiğim tek gerçek fark, tüm projeksiyon ve dönüşüm matrisi hesaplarının diğer işlevlerde gizlenip glUniform ile gölgelendiriciye yüklendiğidir. belki bir yerlerde ekran dışında ama - QPainter üçgen içine 2D varlıkları böler Muhtemelen gibi bu QPainter en gölgelendiriciler benim kırmızı üçgen çizilmiş başlar; böylece, benim projeksiyon/transformasyon matrisleri erişimi yok demektir.

cevap

10

Çağrı beginNativePainting() OpenGL çağrıları yapmadan önce. OpenGL durumunun bir glPush/Pop'u da gerekli olabilir.

QPainter p(this); 
p.beginNativePainting(); 

// Maybe necessary 
glPushAttrib(GL_ALL_ATTRIB_BITS); 
glMatrixMode(GL_PROJECTION); 
glPushMatrix(); 
glMatrixMode(GL_MODELVIEW); 
glPushMatrix(); 

// Put OpenGL code here 

// Necessary if used glPush-es above 
glMatrixMode(GL_PROJECTION); 
glPopMatrix(); 
glMatrixMode(GL_MODELVIEW); 
glPopMatrix(); 
glPopAttrib(); 

p.endNativePainting(); 

p.fillRect(10, 10, 100, 100, 
     QColor(255, 0, 0)); 
+0

Yine hiç şans çağrıları ekleme gibi başka değişiklikler için gerek yoktu

, 3D veri etkilenmez ama QPainter veri görünmüyor. Bir piksel arabelleği oluşturmanın daha hızlı/daha kolay olacağını, bir QPainter'ı arka plan pixmap olarak yükleyip sonra da ekrana çizim yapmadan önce üstünü 'boyayacağını' merak ediyorum. Yoksa sesinden çok daha mı yavaş? – cmannett85

+0

3B çizimi yapmıyorsanız QPainter verileri görünüyor mu? – baysmith

+0

I (docs 2D boyama örnekte olduğu gibi) sadece QPainter görüşmeleri ile paintEvent() işlevini doldurdu ve hiçbir şey ekranda belirir - Widget siyah doldurulur hariç. – cmannett85

1

Ben güçlendirmek ve ben cmannet85 tarafından bulunan gerçek çözümü, olarak gördükleri netleştirmek için bu cevabı post ediyorum etmek, (baysmith yukarıda tarafından cevap yorumum): Aşağıdaki gibi bir şey deneyin QPainter kodunu çağırmadan önce OpenGL köşe tamponu bağlantıları temizleyin.

ben QPainter fonksiyonlarını ve OpenGL işlevlerini kullanarak arasında geçiş yapmak için gerekli içinde, neredeyse özdeş sorunu vardı. cmannet85 tespit olarak, tek nedeni OpenGL fonksiyonları arkasında köşe tampon bağlı terk, onlar OpenGL QPainter kullanmasına müdahale olmasıdır.

Ben glBindBuffer denilen benim OpenGL ES 2.0 kodunun tüm parçaların sonunda bu ifadeyi ekleyerek sorunu çözmek başardı:

glBindBuffer(GL_ARRAY_BUFFER,0); 

0 ise ikinci parametre tamponu keser. vb, beginNativePainting ... endNativePainting için