मैंने पहले एसडीएल में ओपनजीएल का उपयोग किया है, लेकिन मैंने अभी क्यूटी सीखना शुरू कर दिया है। क्यूटी में, ओपनजीएल का उपयोग करना दर्द का कुछ हद तक साबित हो रहा है।QGLWidget केवल खाली स्क्रीन क्यों प्रस्तुत करता है?
main.cpp
#include <stdio.h>
#include <QApplication>
#include "glwidget.hpp"
#include <QGLFormat>
int main(int args, char *argv[]) {
QApplication app(args, argv);
GLWidget openGLWidget;
openGLWidget.show();
return app.exec();
}
glwidget.hpp
#include <GL/glew.h>
#include <QGLWidget>
class GLWidget : public QGLWidget {
protected:
void initializeGL();
void paintGL();
};
void GLWidget::initializeGL() {
if(glewInit() != GLEW_OK) {
fprintf(stderr, "GLEW failed to initialize.");
}
}
void GLWidget::paintGL() {
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
QGLWidget::swapBuffers();
}
helloworld.pro
TEMPLATE = app
INCLUDEPATH += .
LIBS += -lGL -lGLEW
# Input
SOURCES += main.cpp
HEADERS += glwidget.hpp
QT += widgets opengl
जब मैं संकलन और इस चलाने के लिए, मैं: मैं निम्न दो फ़ाइलें है एक खिड़की जिस पर सृजन के समय उसके पीछे जो कुछ भी था, उस पर छापे हुए थे। मैं जो उम्मीद कर रहा हूं वह एक लाल स्क्रीन है। मैं क्या खो रहा हूँ?
अद्यतन
मैं अपने GLWidget कार्यान्वयन संपादित किया है, और मैं इसे काम करने के लिए मिला है। हालांकि, यह केवल तब काम करता है जब मैं glDrawArrays को कॉल करता हूं (नीचे पेंटजीएल फ़ंक्शन देखें)। एसडीएल में, एक खाली रंगीन स्क्रीन देखने के लिए glDrawArrays आवश्यक नहीं था। GlDrawArrays के बिना, qt कुछ कारणों से glClear() को अनदेखा करता है। क्या किसी को पता है क्यों?
GLWidget::GLWidget(QGLWidget* parent) : QGLWidget(QGLFormat(), parent) {
}
void GLWidget::initializeGL() {
if(glewInit() != GLEW_OK) {
fprintf(stderr, "GLEW failed to initialize.");
}
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
shaderProgram.addShaderFromSourceFile(QGLShader::Vertex,
"vertexShader.vert");
shaderProgram.addShaderFromSourceFile(QGLShader::Fragment,
"fragmentShader.frag");
shaderProgram.link();
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
}
void GLWidget::paintGL() {
shaderProgram.bind();
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
setAutoBufferSwap(false);
//glDrawArrays(GL_TRIANGLES, 0, 1);
swapBuffers();
shaderProgram.release();
}
void GLWidget::resizeGL(int width, int height) {
if(height == 0) {
height = 1;
}
if(width == 0) {
width = 1;
}
glViewport(0, 0, width, height);
}
अद्यतन 2
मैंने सोचा कि शायद क्यूटी हुड के नीचे कुछ डरपोक कर रहा था, और है कि अगर मैं सब कुछ मैन्युअल रूप से किया था, मैं इस समस्या से छुटकारा मिलेगा। लेकिन क्यूटी अभी भी किसी भी तरह से जानता है कि मैं प्रोग्राम का उपयोग कर रहा हूं या नहीं, और क्या मैं glDrawArrays का उपयोग कर रहा हूं या नहीं। नीचे दिए गए कोड में, या तो glDrawArrays या glUseProgram लेना कोड को काम नहीं करता है। QGLContext के अंदर क्या होता है इसके साथ कुछ करना होगा।
#include <stdio.h>
#include <fstream>
#include <string>
#include "glwidget.hpp"
GLWidget::GLWidget(QWidget* parent) : QGLWidget(QGLFormat(), parent) {
}
void GLWidget::initializeGL() {
if(glewInit() != GLEW_OK) {
fprintf(stderr, "GLEW failed to initialize.");
}
glContext = this->context();
if(!glContext->create()) {
fprintf(stderr, "Failed to create context.\n");
}
glContext->makeCurrent();
program = glCreateProgram();
addShader(program, GL_VERTEX_SHADER, "vertexShader.vert");
addShader(program, GL_FRAGMENT_SHADER, "fragmentShader.frag");
linkProgram(program);
setAutoBufferSwap(false);
}
void GLWidget::paintGL() {
glUseProgram(program);
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 1);
glContext->swapBuffers();
glUseProgram(0);
}
void GLWidget::resizeGL(int width, int height) {
if(height == 0) {
height = 1;
}
if(width == 0) {
width = 1;
}
glViewport(0, 0, width, height);
}
GLuint GLWidget::addShader(GLuint programID, GLuint shaderType, std::string fileName) {
GLuint shader = glCreateShader(shaderType);
std::ifstream file(fileName.c_str());
std::string source = "";
if(file.is_open()) {
std::string line;
while(getline(file, line)) {
source += line + "\n";
}
} else {
fprintf(stderr, "File %s failed to open.\n", fileName.c_str());
}
const char* sourceC = source.c_str();
glShaderSource(shader, 1, &sourceC, NULL);
glCompileShader(shader);
GLint compileStatus;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
if(compileStatus == GL_FALSE) {
fprintf(stderr, "Shader %s failed to compile.\n", fileName.c_str());
return 0;
}
glAttachShader(programID, shader);
return shader;
}
void GLWidget::linkProgram(GLuint programID) {
glLinkProgram(programID);
GLint linkStatus;
glGetProgramiv(programID, GL_LINK_STATUS, &linkStatus);
if(linkStatus == GL_FALSE) {
fprintf(stderr,"Failed to link program.\n");
}
}
कारण यह हो सकता है। यह केवल तभी काम करता है जब विजेट का प्रारूप डबल बफर मोड निर्दिष्ट करता है। > आम तौर पर, इस फ़ंक्शन को स्पष्ट रूप से कॉल करने की कोई आवश्यकता नहीं है क्योंकि यह प्रत्येक विजेट रीपेंट के बाद स्वचालित रूप से किया जाता है, यानी पेंटजीएल() को निष्पादित करने के बाद प्रत्येक बार। – rpress
@rpress मैंने उस विचार के साथ थोड़ा सा खेला, लेकिन मुझे नहीं लगता कि यह समस्या है। अधिक जानकारी के लिए अद्यतन देखें। –
@WilliamOliver जो मूल समस्या थी - कम से कम, मैं आपके मूल कोड में "रिक्त स्क्रीन" को पुन: उत्पन्न कर सकता हूं, और वांछित लाल स्क्रीन * या तो * को 'स्वैपबफर' पर कॉल हटाकर या 'setAutoBufferSwap' पर कॉल जोड़कर (गलत) '। क्या यह काम नहीं करता? – Lack