我正在使用Qt(5.6.0)在Qt和遊戲場景(3D地圖,角色,怪物等)中完成界面製作地牢爬行器/流氓類。 )在OpenGL中。該視圖是一個提升的QWidget,我可以使用舊的glBegin/glEnd方法進行繪製,但每當我嘗試使用glDrawArrays或glDrawElements時,我都會看到一個空白屏幕。QT OpenGL,glDrawElements和glDrawArray只顯示空白屏幕
清晰的顏色工作,被設置爲比黑色稍輕,所以應該顯示黑色的形狀。我正在使用glBegin/glEnd方法用相同的頂點進行測試,並且它的渲染效果與它應該一樣。我嘗試了一個或多或少的直接OpenGL方法,如Jamie King所示,通過幾個更多示例和教程,最後以this example結尾,以便使用QOpenGLShaderProgram和QOpenGLVertexArrayObject對象以及QOpenGLShaderProgram Qt文檔中的示例。目前initializeGL函數中的着色器代碼阻止繪製glBegin/glEnd三角形。
目前代碼:
oglwidget.cpp:
#include "GL/glew.h"
#include "GL/glext.h"
#include "oglwidget.h"
#include "general.h"
#define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))
extern const char * vertexShader;
extern const char * fragmentShader;
OGLWidget::OGLWidget(QWidget *parent): QOpenGLWidget(parent){
}
OGLWidget::~OGLWidget(){
}
void OGLWidget::initializeGL(){
QOpenGLFunctions gl;
gl.initializeOpenGLFunctions();
cout<<"Init"<<endl;
//-----Create Shader
shader2.create();
shader2.addShaderFromSourceCode(QOpenGLShader::Vertex,vertexShader);
shader2.addShaderFromSourceCode(QOpenGLShader::Fragment,fragmentShader);
shader2.link();
shader2.bind();
int vertexLocation = shader2.attributeLocation("vertex");
int matrixLocation = shader2.uniformLocation("matrix");
int colorLocation = shader2.uniformLocation("color");
QMatrix4x4 pmvMatrix;
pmvMatrix.ortho(rect());
QColor color(0, 255, 0, 255);
shader2.enableAttributeArray(vertexLocation);
shader2.setAttributeArray(vertexLocation, verts, 3);
shader2.setUniformValue(matrixLocation, pmvMatrix);
shader2.setUniformValue(colorLocation, color);
//-----Create VAO2
VAO2=new QOpenGLVertexArrayObject(this);
VAO2->create();
VAO2->bind();
//-----Create VBO2
VBO2.create();
VBO2.setUsagePattern(QOpenGLBuffer::StaticDraw);
VBO2.bind();
VBO2.allocate(verts,sizeof(verts));
}
void OGLWidget::paintGL(){
cout<<"Painting"<<endl;
QOpenGLFunctions gl;
gl.initializeOpenGLFunctions();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.05,0.05,0.05,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-2.0f);
//draw();
shader2.bind();
VAO2->bind();
glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_INT,inds);
VAO2->release();
}
void OGLWidget::resizeGL(int w, int h){
cout<<"Resizing"<<endl;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glFrustum (-1.0, 1.0, -1.0, 1.0, 1, 1000.0); //-----Assuming this is right?
glOrtho(-5,5,-5,5,-5,5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int OGLWidget::loadModel(string path){
//-----loads the model path if not already loaded, returns the index of the model
//---check if already loaded
for(int p=0;p<loadedPaths.size();p++){
if(!loadedPaths[p].compare(path)){
return p;
}
}
loadedPaths.push_back(path);
//-----continue with path loading
Model m;
m.loadModel(path);
return loadedPaths.size()-1;
}
void OGLWidget::draw(){
cout<<"drawing..."<<endl;
glBegin(GL_TRIANGLES);
for(int i=0;i<sizeof(verts)/sizeof(GLfloat);i+=3){
//cout<<i<<endl;
glVertex3f(verts[i],verts[i+1],verts[i+2]);
}
glEnd();
}
oglwidget.h:
#ifndef OGLWIDGET_H
#define OGLWIDGET_H
#include <QWidget>
#include <QOpenGLWidget>
#include <glm/glm.hpp>
#include <QOpenGLFunctions>
#include <vector>
#include "entity.h"
#include "general.h"
#include <qopenglfunctions_3_3_core.h>
//#include <GL/glu.h>
//#include <GL/gl.h>
#define VERTEXATTR 0
#define INDEXATTR 1
#define POSITIONATTR 2
#define ROTATIONATTR 3
using namespace std;
class OGLWidget : public QOpenGLWidget
{
//QOpenGLFunctions gl;
//QOpenGLFunctions_3_3_Core core;
QOpenGLVertexArrayObject *VAO2;
QOpenGLBuffer VBO2;
QOpenGLShaderProgram shader2;
QOpenGLContext *m_context;
vector<GLuint>statics; //-----buffer number for static models
vector<GLuint>dynamics; //-----buffer number of dynamic models
vector<GLfloat[1]>staticVerts; //-----vertex data for static models
vector<GLfloat[1]>dynamicVerts; //-----vertex data for dynamic models
vector<vector<GLfloat>*>staticPos; //-----position data for static models
vector<vector<GLfloat>*>dynamicPos; //-----position data for dynamic models
vector<GLfloat>staticRot; //-----rotation data for static models
vector<GLfloat>dynamicRot; //-----rotation data for dynamic models
vector<string>loadedPaths; //-----name in folder of matching VBO
GLuint VBO;
GLuint IND;
GLuint FragID;
GLuint VertID;
GLuint shader;
//-----Testing
GLfloat verts[9]={-1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f};
GLuint inds[3]={0,1,2};
public:
OGLWidget(QWidget *parent = 0);
~OGLWidget();
int loadModel(string path);
private:
void draw();
QGLShaderProgram m_shader;
QGLBuffer m_vertexBuffer;
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
};
#endif // OGLWIDGET_H
shader.cpp:
const char * vertexShader=
"attribute highp vec4 vertex;\n"
"uniform highp mat4 matrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = matrix * vertex;\n"
"}";
const char * fragmentShader=
"uniform mediump vec4 color;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = color;\n"
"}";
從我讀過(糾正我,如果我錯了)它的目標使用VAO將頂點,顏色,紋理和其他數據加載到GPU內存,在繪製之前重新綁定VAO,使用glDrawArrays或glDrawElement繪製並釋放VAO。使用函數的索引版本將允許位置,比例和旋轉的更改,這意味着更大數量的同一對象(即遊戲切片)的更快渲染和GL_STATIC_DRAW應該用於未經常更新的對象,其中GL_DYNAMIC_DRAW一切。
我想知道我錯過了什麼,或者做錯了什麼應該是一個簡單的練習。我已經重做了至少5次,完全失利。
- OS:Debian的測試
- GPU:的GeForce610米
- OpenGL的核心:3.3
- 的Qt:5.6
- 軟件:Qt Creator的
你有沒有嘗試添加誤差glGetError檢查()? –
綁定vao後,需要綁定頂點的東西(vao在那裏存儲綁定)。您可以設置正投影顯示窗口座標(0左上角,y正下),但是您的座標應在[0-1]左右,大小約爲一個像素。你也試圖綁定一個緩衝區和數組都作爲頂點屬性(它應該只是緩衝區) – PeterT
最後一點我的意思是使用'setAttributeBuffer'而不是'setAttributeArray'(並且在綁定緩衝區後明顯做到這一點) – PeterT