Can someone help me with this OpenGL code
Unsolved
Game Development
-
I am trying to load a model and it is the first time. I want to apply 2 textures to my mesh. It is a computer monitor which is black. I edited the uv's in my .obj file so the screen is on the left and the other faces are on the right. I get these errors when I try to run it.
cglwidget.obj:-1: error: LNK2019: unresolved external symbol __imp_glClear referenced in function "protected: virtual void __cdecl GLWidget::paintGL(void)" (?paintGL@GLWidget@@MEAAXXZ) glwidget.obj:-1: error: LNK2019: unresolved external symbol __imp_glClearColor referenced in function "protected: virtual void __cdecl GLWidget::paintGL(void)" (?paintGL@GLWidget@@MEAAXXZ) glwidget.obj:-1: error: LNK2019: unresolved external symbol __imp_glDrawElements referenced in function "protected: virtual void __cdecl GLWidget::paintGL(void)" (?paintGL@GLWidget@@MEAAXXZ) C:\Users\damon\Documents\QT\build-readinggl-Desktop_Qt_5_15_2_MSVC2015_64bit-Debug\debug\readinggl.exe:-1: error: LNK1120: 3 unresolved externals
this is my glwidget.h file
#ifndef GLWIDGET_H #define GLWIDGET_H #include <QtOpenGL/QGLWidget> #include <QOpenGLTexture> #include <QOpenGLFunctions> #include <QOpenGLBuffer> #include <QOpenGLShaderProgram> class GLWidget : public QGLWidget { public: explicit GLWidget(QWidget *parent = 0); void getfile(); void setTexture(QImage img); protected: virtual void initializeGL(); virtual void resizeGL(int w, int h); virtual void paintGL(); private: void makeObject(); void createShaders(); const char *loadText(QString filaname); unsigned int *pasind1; unsigned int *pasind2; unsigned int passiz1; unsigned int passiz2; QOpenGLTexture *mytext = nullptr; QOpenGLTexture *blank = nullptr; QOpenGLBuffer vbo; QOpenGLShaderProgram *program = nullptr; }; #endif // GLWIDGET_H
this is my widget.cpp
#include "glwidget.h" #include <QFile> #include "modelloader.h" GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent) { } void GLWidget::initializeGL() { //glEnable(GL_DEPTH_TEST); //glEnable(GL_CULL_FACE); #define PROGRAM_VERTEX_ATTRIBUTE 0 #define PROGRAM_TEXCOORD_ATTRIBUTE 1 //initializeOpenGLFunctions(); QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); const char *vsrc = loadText("C:\\Users\\damon\\Documents\\QT\\readinggl\\simple.vert"); vshader->compileSourceCode(vsrc); QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); const char *fsrc = loadText("C:\\Users\\damon\\Documents\\QT\\readinggl\\simple.frag"); fshader->compileSourceCode(fsrc); program = new QOpenGLShaderProgram; program->addShader(vshader); program->addShader(fshader); program->bindAttributeLocation("vertex", PROGRAM_VERTEX_ATTRIBUTE); program->bindAttributeLocation("texCoord", PROGRAM_TEXCOORD_ATTRIBUTE); program->link(); program->bind(); blank = new QOpenGLTexture(QImage(QString("C:\\Users\\damon\\Documents\\textures\\blanktex.png"))); mytext = new QOpenGLTexture(QImage(QString("C:\\Users\\damon\\Documents\\textures\\blanktex.png"))); } void GLWidget::resizeGL(int w, int h) { } void GLWidget::paintGL() { glClearColor(.5, .5, .5, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); program->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE); program->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE); program->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 3, 5 * sizeof(GLfloat)); program->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 3 * sizeof(GLfloat), 2, 5 * sizeof(GLfloat)); blank->bind(); glDrawElements(GL_TRIANGLES, passiz1, GL_UNSIGNED_INT, &pasind1); //mytext->bind(); //glDrawElements(GL_TRIANGLES, passiz2, GL_UNSIGNED_INT, pasind2); } void GLWidget::setTexture(QImage img) { mytext = new QOpenGLTexture(QImage(img)); } void GLWidget::makeObject(){ ModelLoader loader; bool loaded = loader.loadOBJ("C:\\Users\\damon\\Documents\\monitor.obj"); int loc; if (loaded){ QVector<int> indu1; QVector<int> indu2; Vertex curver; QVector<GLfloat> vertData; for (int i=0;i<loader.mVertices.size();i++){ curver = loader.mVertices.at(i); vertData.push_back(curver.position.x); vertData.push_back(curver.position.y); vertData.push_back(curver.position.z); vertData.push_back(curver.texCoords.s); vertData.push_back(curver.texCoords.t); if (curver.isscrn){ vertData.push_back(1); }else{ vertData.push_back(0); } } vbo.create(); vbo.bind(); vbo.allocate(vertData.constData(), vertData.count() * sizeof(GLfloat)); for (int i = 0;i < loader.indu.size();i++){ loc = loader.indu.at(i); if (loader.mVertices.at(loc).isscrn){ indu2.push_back(loc); }else{ indu1.push_back(loc); } } passiz1 = indu1.size(); pasind1 = new unsigned int[passiz1]; for (int i = 0;i < indu1.size();i++) pasind1[i] = indu1.at(i); passiz2 = indu2.size(); pasind2 = new unsigned int[passiz2]; for (int i = 0;i < indu2.size();i++) pasind2[i] = indu2.at(i); } } void GLWidget::createShaders(){ } const char *GLWidget::loadText(QString filename) { QString theText = ""; QFile fil(filename); if (!fil.open(QFile::ReadOnly | QFile::Text)){ } QTextStream inp(&fil); theText = inp.readAll(); fil.close(); const char *rets = theText.toStdString().c_str(); return rets; }
the modelloader.h
#ifndef MODELLOADER_H #define MODELLOADER_H #include <assimp/Importer.hpp> // C++ importer interface #include <assimp/scene.h> // Output data structure #include <assimp/postprocess.h> #include <QtCore> #include <sstream> #include <fstream> struct vec3{ float x, y, z; }; struct vec2{ float s, t; }; struct Vertex{ vec3 position; vec2 texCoords; bool isscrn; }; class ModelLoader { public: ModelLoader(); float *calculateNormal(float *coord1, float *coord2, float *coord3); bool DoTheImportThing( const std::string& pFile); bool loadOBJ(const std::string& filename); QString error; QVector<int> indu; QVector<vec3> norms; QVector<Vertex> mVertices; }; #endif // MODELLOADER_H
my modelloader.cpp
#include "modelloader.h" #include <math.h> ModelLoader::ModelLoader() { } float *ModelLoader::calculateNormal(float *coord1, float *coord2, float *coord3) { float va[3], vb[3], vr[3], val; float *norm = new float[3]; va[0] = coord1[0] - coord2[0]; va[1] = coord1[1] - coord2[1]; va[2] = coord1[2] - coord2[2]; vb[0] = coord1[0] - coord3[0]; vb[1] = coord1[1] - coord3[1]; vb[2] = coord1[2] - coord3[2]; /* cross product */ vr[0] = va[1] * vb[2] - vb[1] * va[2]; vr[1] = vb[0] * va[2] - va[0] * vb[2]; vr[2] = va[0] * vb[1] - vb[0] * va[1]; /* normalization factor */ val = sqrt( vr[0]*vr[0] + vr[1]*vr[1] + vr[2]*vr[2] ); norm[0] = vr[0]/val; norm[1] = vr[1]/val; norm[2] = vr[2]/val; return norm; } bool ModelLoader::loadOBJ(const std::string& filename) { std::vector<unsigned int> vertexIndices, uvIndices; std::vector<vec3> tempVertices; std::vector<vec2> tempUVs; float coor1[3]; float coor2[3]; float coor3[3]; float *norm; vec3 tempn; indu.clear(); norms.clear(); mVertices.clear(); if (filename.find(".obj") != std::string::npos) { std::ifstream fin(filename, std::ios::in); if (!fin) { error = "Cannot open " + QString::fromStdString(filename); return false; } std::string lineBuffer; while (std::getline(fin, lineBuffer)) { if (lineBuffer.substr(0, 2) == "v ") { std::istringstream v(lineBuffer.substr(2)); vec3 vertex; v >> vertex.x; v >> vertex.y; v >> vertex.z; tempVertices.push_back(vertex); } else if (lineBuffer.substr(0, 2) == "vt") { std::istringstream vt(lineBuffer.substr(3)); vec2 uv; vt >> uv.s; vt >> uv.t; tempUVs.push_back(uv); } else if (lineBuffer.substr(0, 2) == "f ") { int p1, p2, p3; //to store mesh index int t1, t2, t3; //to store texture index int n1, n2, n3; const char* face = lineBuffer.c_str(); int match = sscanf_s(face, "f %i/%i/%i %i/%i/%i %i/%i/%i", &p1, &t1, &n1, &p2, &t2, &n2, &p3, &t3, &n3); if (match != 9){ error = "Failed to parse OBJ file using our very simple OBJ loader"; return false; } // We are ignoring normals (for now) vertexIndices.push_back(p1); vertexIndices.push_back(p2); vertexIndices.push_back(p3); uvIndices.push_back(t1); uvIndices.push_back(t2); uvIndices.push_back(t3); } } // Close the file fin.close(); // For each vertex of each triangle for (unsigned int i = 0; i < vertexIndices.size(); i++) { // Get the attributes using the indices vec3 vertex = tempVertices[vertexIndices[i] - 1]; vec2 uv = tempUVs[uvIndices[i] - 1]; Vertex meshVertex; meshVertex.position = vertex; meshVertex.texCoords = uv; meshVertex.isscrn = false; mVertices.push_back(meshVertex); indu.push_back(vertexIndices[i]); } for (int i = 0;i < int(mVertices.size() / 3);i++){ coor1[0] = mVertices.at(i * 3).position.x; coor1[1] = mVertices.at(i * 3).position.y; coor1[2] = mVertices.at(i * 3).position.z; coor2[0] = mVertices.at(i * 3 + 1).position.x; coor2[1] = mVertices.at(i * 3 + 1).position.y; coor2[2] = mVertices.at(i * 3 + 1).position.z; coor3[0] = mVertices.at(i * 3 + 2).position.x; coor3[1] = mVertices.at(i * 3 + 2).position.y; coor3[2] = mVertices.at(i * 3 + 2).position.z; norm = calculateNormal(coor1, coor2, coor3); tempn.x = norm[0]; tempn.y = norm[1]; tempn.z = norm[2]; norms.push_back(tempn); } return true; } // We shouldn't get here so return failure return false; } /* bool ModelLoader::DoTheImportThing( const std::string& pFile) { // Create an instance of the Importer class Assimp::Importer importer; // And have it read the given file with some example postprocessing // Usually - if speed is not the most important aspect for you - you'll // probably to request more postprocessing than we do in this example. const aiScene* scene = importer.ReadFile( pFile, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType); // If the import failed, report it if( !scene) { error = importer.GetErrorString(); return false; } // Now we can access the file's contents. //DoTheSceneProcessing( scene); aiMesh *mymeshes; aiVector3D pos; aiVector3D normal; float texco; aiColor4D color; float coor1[3]; float coor2[3]; float coor3[3]; float *norm; int refp; for(int i=0;i < scene->mNumMeshes;i++){ aiMesh* mesh = scene->mMeshes[i]; int iMeshFaces = mesh->mNumFaces; for (int j=0;j < iMeshFaces;j++){ const aiFace& face = mesh->mFaces[j]; for (int k=0;k<3;k++){ indu.push_back(face.mIndices[k]); pos = mesh->mVertices[face.mIndices[k]]; vert_x.push_back(pos.x); vert_y.push_back(pos.y); vert_z.push_back(pos.z); //color = scene->mMeshes[i]->mColors[i][j]; tex_x.push_back(mesh->mTextureCoords[0][j * 3 + k].x); tex_y.push_back(mesh->mTextureCoords[0][j * 3 + k].y); } refp = vert_x.size() - 1; coor1[0] = vert_x.at(refp - 2); coor1[1] = vert_y.at(refp - 2); coor1[2] = vert_z.at(refp - 2); coor2[0] = vert_x.at(refp - 1); coor2[1] = vert_y.at(refp - 1); coor2[2] = vert_z.at(refp - 1); coor3[0] = vert_x.at(refp); coor3[1] = vert_y.at(refp); coor3[2] = vert_z.at(refp); norm = calculateNormal(coor1, coor2, coor3); norm_x.push_back(norm[0]); norm_y.push_back(norm[1]); norm_z.push_back(norm[2]); } } // We're done. Everything will be cleaned up by the importer destructor return true; } */
the vertex shader
attribute vec3 qt_Vertex; attribute vec2 qt_MultiTexCoord0; varying vec4 qt_TexCoord0; void main(void) { gl_Position = qt_Vertex; qt_TexCoord0 = qt_MultiTexCoord0; }
and the fragment shader
uniform sampler2D qt_Texture0; varying vec4 qt_TexCoord0; void main(void) { gl_FragColor = texture2D(qt_Texture0, qt_TexCoord0.st); }
-
@AI_Messiah said in Can someone help me with this OpenGL code:
I get these errors when I try to run it.
These are link errors, you don't even get to the point of running anything. Firstly do switch to
QOpenGLWidget
instead of the deprecated class you use.