我正在使用Qt(5.6.0)与Qt中的界面和OpenGL中的游戏场景(3D地图,角色,怪物......)制作一个地下城爬虫/流氓。视图是一个提升的QWidget,我可以使用旧的glBegin / glEnd方法进行绘制,但每当我尝试使用glDrawArrays或glDrawElements时,我都会得到一个空白屏幕。
清晰的颜色正在工作,并且设置为比黑色略亮,因此应显示黑色形状。我使用glBegin / glEnd方法测试相同的顶点,它确实渲染它应该。我已经尝试了一种或多或少直接的OpenGL方法,如Jamie King所示,通过几个示例和教程,最后以this example结束,以便使用QOpenGLShaderProgram和QOpenGLVertexArrayObject对象以及QOpenGLShaderProgram Qt doc中的示例。目前,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进行绘制或glDrawElements并发布VAO。使用该函数的索引版本将允许更改位置,比例和旋转,这意味着更快的渲染更大量的相同对象(即游戏磁贴)和GL_STATIC_DRAW应该用于不经常更新的对象,使用GL_DYNAMIC_DRAW其他一切。
我想知道我错过了什么,或者做错了什么应该是一个简单的练习。我已经重做了至少5次,完全失去了。
答案 0 :(得分:0)
感谢评论中的@PeterT:将着色器enableAttributeArray和setAttributeBuffer(从setAttributeArray更改)移动到VBO分配之后,将顶点坐标和ortho修改为“更大”。
void OGLWidget::initializeGL()
{
QOpenGLFunctions gl;
gl.initializeOpenGLFunctions();
glDisable(GL_CULL_FACE);
cout<<"Init"<<endl;
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());
pmvMatrix.ortho(-100,100,-100,100,-1000,1000);
QColor color(0, 255, 0, 255);
shader2.enableAttributeArray(vertexLocation);
shader2.setUniformValue(matrixLocation, pmvMatrix);
shader2.setUniformValue(colorLocation, color);
//-----Create VAO2
VAO2=new QOpenGLVertexArrayObject(this);
VAO2->create();
VAO2->bind();
VBO2.create();
VBO2.setUsagePattern(QOpenGLBuffer::StaticDraw);
VBO2.bind();
VBO2.allocate(verts,sizeof(verts));
shader2.enableAttributeArray("vertex");
shader2.setAttributeBuffer("vertex",GL_FLOAT,0,3,0);
}
*
GLfloat verts[9]={-100.0f, 0.0f, 30.0f,
0.0f, 100.0f, 50.0f,
100.0f, 0.0f, 30.0f};