我是OpenGL的新手。我使用OpenGL 3和QT5来最终渲染类似地形的类似地形。到目前为止,我只尝试渲染一个立方体,但我一直在看一个空白的屏幕。我正在学习本教程系列:https://www.youtube.com/playlist?list=PLRwVmtr-pp06qT6ckboaOhnm9FxmzHpbY,这里是代码:
glwindow.h:
#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_3_Core>
class glWiwndow : public QOpenGLWidget,
protected QOpenGLFunctions_4_3_Core
{
protected:
void sendDataToOpenGL();
void installShaders();
QString readShaderCode(const QString fileName);
void initializeGL();
void paintGL();
void teardownGL();
public:
};
vertex.h:
#pragma once
#include <glm\glm.hpp>
struct Vertex
{
glm::vec3 position;
glm::vec3 color;
glm::vec3 normal;
};
shapedata.h:
#pragma once
#include <QOpenGLShaderProgram>
#include"vertex.h"
struct shapeData
{
shapeData() :
vertices(0), numVertices(0),
indices(0), numIndices(0) {}
Vertex* vertices;
GLuint numVertices;
GLushort* indices;
GLuint numIndices;
GLsizeiptr vertexBufferSize() const
{
return numVertices * sizeof(Vertex);
}
GLsizeiptr indexBufferSize() const
{
return numIndices * sizeof(GLushort);
}
void cleanup()
{
delete [] vertices;
delete [] indices;
numVertices = numIndices = 0;
}
};
shapegenerator.h:
#include"shapedata.h"
class ShapeGenerator
{
public:
ShapeGenerator();
static shapeData makeTriangle();
static shapeData makeCube();
};
glwindow.cpp:
#include "glwindow.h"
#include"shapegenerator.h"
#include<iostream>
#include <QDebug>
#include <QString>
#include <QOpenGLShaderProgram>
#include<QMessageBox>
#include<QStringList>
#include <QMatrix4x4>
#include<QFile>
#include "glm\gtc\matrix_transform.hpp"
#include "glm\gtx\transform.hpp"
using glm::mat4;
using glm::vec3;
GLint programID;
GLuint numIndices;
QString glWiwndow::readShaderCode(const QString fileName){
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return NULL;
}
QByteArray total;
QByteArray line;
while (!file.atEnd()) {
line = file.read(1024);
total.append(line);
}
return QString(total);
}
void glWiwndow::installShaders(){
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar * adapter[1];
QString temp = readShaderCode(":/vertexshader.vert");
adapter[0] = temp.toStdString().c_str();
glShaderSource(vertexShaderID,1,adapter,0);
temp = readShaderCode(":/fragmentshader.frag");
adapter[0] = temp.toStdString().c_str();
glShaderSource(fragmentShaderID,1,adapter,0);
//cout<<"here";
glCompileShader(vertexShaderID);
//cout<<"yoo";
glCompileShader(fragmentShaderID);
GLuint programID = glCreateProgram();
glAttachShader(programID,vertexShaderID);
glAttachShader(programID,fragmentShaderID);
glLinkProgram(programID);
glUseProgram(programID);
}
void glWiwndow :: initializeGL(){
// Initialize OpenGL Backend
initializeOpenGLFunctions();
connect(context(), SIGNAL(aboutToBeDestroyed()), this, SLOT(teardownGL()), Qt::DirectConnection);
glEnable(GL_DEPTH_TEST);
shapeData cube = ShapeGenerator::makeCube();
GLuint myBufferID;
glGenBuffers(1,&myBufferID);
glBindBuffer(GL_ARRAY_BUFFER,myBufferID);
glBufferData(GL_ARRAY_BUFFER,cube.vertexBufferSize(),cube.vertices,GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(float)*6,0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(float)*6,(char*)(sizeof(float)*3));
GLuint indexArrayBufferID;
glGenBuffers(1,&indexArrayBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexArrayBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,cube.indexBufferSize(),cube.indices,GL_STATIC_DRAW);
numIndices = cube.numIndices;
installShaders();
}
void glWiwndow :: paintGL(){
glClearColor(0.0f,0.0f,0.0f,0.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glViewport(0,0,width(),height());
mat4 modelTransformMatrix = glm::translate(mat4(),vec3(0.0f,0.0f,-3.0f));
mat4 projectionMatrix = glm::perspective(60.0f, ((float)width()) / height(), 0.1f, 20.0f);
GLint modelTransformMatrixUniformLocation = glGetUniformLocation(programID,"modelTransformMatrix");
GLint projectionMatrixUniformLocation = glGetUniformLocation(programID,"projectionMatrix");
glUniformMatrix4fv(modelTransformMatrixUniformLocation,1,GL_FALSE,&modelTransformMatrix[0][0]);
glUniformMatrix4fv(projectionMatrixUniformLocation,1,GL_FALSE,&projectionMatrix[0][0]);
glDrawElements(GL_TRIANGLES,numIndices,GL_UNSIGNED_SHORT,0);
}
void glWiwndow::teardownGL()
{
}
shapegenerator.cpp:
#include "ShapeGenerator.h"
#include <glm\glm.hpp>
#include <glm\gtc\matrix_transform.hpp>
#include <vertex.h>
using glm::vec3;
using glm::mat4;
using glm::mat3;
#define NUM_ARRAY_ELEMENTS(a) sizeof(a) / sizeof(*a)
glm::vec3 randomColor()
{
glm::vec3 ret;
ret.x = rand() / (float)RAND_MAX;
ret.y = rand() / (float)RAND_MAX;
ret.z = rand() / (float)RAND_MAX;
return ret;
}
shapeData ShapeGenerator::makeTriangle()
{
shapeData ret;
Vertex verts[] =
{
glm::vec3(+0.0f, +1.0f, +0.0f),
glm::vec3(+0.0f, +1.0f, +0.0f),
glm::vec3(-1.0f, -1.0f, +0.0f),
glm::vec3(+0.0f, +1.0f, +0.0f),
glm::vec3(+1.0f, -1.0f, +0.0f),
glm::vec3(+0.0f, +0.0f, +1.0f),
};
ret.numVertices = NUM_ARRAY_ELEMENTS(verts);
ret.vertices = new Vertex[ret.numVertices];
memcpy(ret.vertices, verts, sizeof(verts));
GLushort indices[] = { 0, 1, 2 };
ret.numIndices = NUM_ARRAY_ELEMENTS(indices);
ret.indices = new GLushort[ret.numIndices];
memcpy(ret.indices, indices, sizeof(indices));
return ret;
}
shapeData ShapeGenerator::makeCube() {
shapeData ret;
Vertex stackVerts[] =
{
vec3(-1.0f, +1.0f, +1.0f), // 0
vec3(+1.0f, +0.0f, +0.0f), // Color
vec3(+1.0f, +1.0f, +1.0f), // 1
vec3(+0.0f, +1.0f, +0.0f), // Color
vec3(+1.0f, +1.0f, -1.0f), // 2
vec3(+0.0f, +0.0f, +1.0f), // Color
vec3(-1.0f, +1.0f, -1.0f), // 3
vec3(+1.0f, +1.0f, +1.0f), // Color
vec3(-1.0f, +1.0f, -1.0f), // 4
vec3(+1.0f, +0.0f, +1.0f), // Color
vec3(+1.0f, +1.0f, -1.0f), // 5
vec3(+0.0f, +0.5f, +0.2f), // Color
vec3(+1.0f, -1.0f, -1.0f), // 6
vec3(+0.8f, +0.6f, +0.4f), // Color
vec3(-1.0f, -1.0f, -1.0f), // 7
vec3(+0.3f, +1.0f, +0.5f), // Color
vec3(+1.0f, +1.0f, -1.0f), // 8
vec3(+0.2f, +0.5f, +0.2f), // Color
vec3(+1.0f, +1.0f, +1.0f), // 9
vec3(+0.9f, +0.3f, +0.7f), // Color
vec3(+1.0f, -1.0f, +1.0f), // 10
vec3(+0.3f, +0.7f, +0.5f), // Color
vec3(+1.0f, -1.0f, -1.0f), // 11
vec3(+0.5f, +0.7f, +0.5f), // Color
vec3(-1.0f, +1.0f, +1.0f), // 12
vec3(+0.7f, +0.8f, +0.2f), // Color
vec3(-1.0f, +1.0f, -1.0f), // 13
vec3(+0.5f, +0.7f, +0.3f), // Color
vec3(-1.0f, -1.0f, -1.0f), // 14
vec3(+0.4f, +0.7f, +0.7f), // Color
vec3(-1.0f, -1.0f, +1.0f), // 15
vec3(+0.2f, +0.5f, +1.0f), // Color
vec3(+1.0f, +1.0f, +1.0f), // 16
vec3(+0.6f, +1.0f, +0.7f), // Color
vec3(-1.0f, +1.0f, +1.0f), // 17
vec3(+0.6f, +0.4f, +0.8f), // Color
vec3(-1.0f, -1.0f, +1.0f), // 18
vec3(+0.2f, +0.8f, +0.7f), // Color
vec3(+1.0f, -1.0f, +1.0f), // 19
vec3(+0.2f, +0.7f, +1.0f), // Color
vec3(+1.0f, -1.0f, -1.0f), // 20
vec3(+0.8f, +0.3f, +0.7f), // Color
vec3(-1.0f, -1.0f, -1.0f), // 21
vec3(+0.8f, +0.9f, +0.5f), // Color
vec3(-1.0f, -1.0f, +1.0f), // 22
vec3(+0.5f, +0.8f, +0.5f), // Color
vec3(+1.0f, -1.0f, +1.0f), // 23
vec3(+0.9f, +1.0f, +0.2f), // Color
};
ret.numVertices = NUM_ARRAY_ELEMENTS(stackVerts);
ret.vertices = new Vertex[ret.numVertices];
memcpy(ret.vertices, stackVerts, sizeof(stackVerts));
unsigned short stackIndices[] = {
0, 1, 2, 0, 2, 3, // Top
4, 5, 6, 4, 6, 7, // Front
8, 9, 10, 8, 10, 11, // Right
12, 13, 14, 12, 14, 15, // Left
16, 17, 18, 16, 18, 19, // Back
20, 22, 21, 20, 23, 22, // Bottom
};
ret.numIndices = NUM_ARRAY_ELEMENTS(stackIndices);
ret.indices = new GLushort[ret.numIndices];
memcpy(ret.indices, stackIndices, sizeof(stackIndices));
return ret;
}
main.cpp中:
#include "glwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
glWiwndow w;
w.show();
return a.exec();
}
顶点着色器代码:(vertexshader.vert)
#version 430
layout(location = 0) in vec3 position;
layout(location=1) in vec3 vertexColor;
uniform mat4 modelTransformMatrix;
uniform mat4 projectionMatrix;
out vec3 theColor;
void main()
{
vec4 v = vec4(position,1.0);
vec4 newPosition = modelTransformMatrix * v;
vec4 projectedPosition = projectionMatrix * newPosition;
gl_Position = projectedPosition;
theColor = vertexColor;
}
片段着色器代码:(fragmentshader.frag)
#version 430
out highp vec4 fColor;
in vec3 theColor;
void main()
{
fColor =vec4(theColor,1.0);
}
答案 0 :(得分:0)
问题在于programID
,但不是我在评论中概述的原因。目前,您有一个全球可靠的...
GLint programID;
然后在glWiwndow::installShaders
你有......
GLuint programID = glCreateProgram();
因此,您的代码使用本地作用域glUseProgram
调用programID
,然后在glWiwndow::paintGL
中将未初始化的全局programID
传递给glGetUniformLocation
,返回-1表示失败。你真的需要在GL中检查这些类型的错误。