0

I want to use modern OpenGL to render my first triangle. (I'm using SFML).The program works fine when I use old functions (glBegin,glEnd) I have 2 classes:

global

Where I use this to initialize global sfml variables etc. (not relevant to my problem)

#ifndef GLOBAL_H
#define GLOBAL_H

#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <glm/glm.hpp>

using namespace std;

extern sf::Event Event;
extern sf::Shader defaultShader;
extern sf::ContextSettings settings;
extern sf::Window window;

void initShader();

#endif // GLOBAL_H

and

Model

This loads an obj file loader. I generated it using Blender. Here is it:

#ifndef MODEL_H
#define MODEL_H

#include <GL/glew.h>
#include "global.h"

struct Vertex{
    float x,y,z;
    Vertex(){};
    Vertex(float a,float b,float c){x=a;y=b;z=c;};
};

struct TextureCoordinate{
    float x;
    float y;
    TextureCoordinate(){};
    TextureCoordinate(float a,float b){x=a;y=b;};
};

struct FaceTexture{
    string texture;
    int vertex[3];
};

class Model
{
    public:
        Model();
        vector<Vertex> vertices;
        vector<FaceTexture> faces;
        vector<TextureCoordinate> textureCoordinates;
        vector<Vertex> normals;
        void loadModel(const char *fileName);
        void setupMesh();
        void draw();
    private:
        GLuint VAO, VBO;
};

#endif // MODEL_H

And the Model.cpp:

#include "Model.h"

Model::Model()
{

}

void Model::loadModel(const char *fileName)
{
    int i;
    vector<string>line;
    vector<string>tmp;
    vector<int>V1;vector<int>V2;vector<int>V3;vector<int>T1;vector<int>T2;vector<int>T3;vector<int>N1;vector<int>N2;vector<int>N3;
    vector<TextureCoordinate>tc;
    vector<Vertex>nc;
    ifstream fin(fileName);
    char aux[200],matFileName[200];
    float v1,v2,v3,t1,t2,t3,n1,n2,n3;
    while(!fin.eof())
    {
        fin.getline(aux,256);
        line.push_back(aux);
    }
    fin.close();

    sscanf(line[2].c_str(),"mtllib %s",&matFileName);
    fin.open(("models/"+string("matFileName")).c_str());
    while(!fin.eof())
    {
        fin.getline(aux,200);
        tmp.push_back(aux);
    }
    ///***///
    for(i=3;i<line.size();i++)
    {
        char matName[100];
        if(line[i][0]=='v'&& line[i][1]==' ')
        {
            Vertex v;
            sscanf(line[i].c_str(),"v %f %f %f",&v.x,&v.y,&v.z);
            vertices.push_back(v);
            continue;
        }
        if(line[i][0]=='v'&&line[i][1]=='t')
        {
            TextureCoordinate t;
            sscanf(line[i].c_str(),"vt %f %f",&t.x,&t.y);
            textureCoordinates.push_back(t);
            continue;
        }
        if(line[i][0]=='v'&&line[i][1]=='n')
        {
            Vertex v;
            sscanf(line[i].c_str(),"vn %f %f %f",&v.x,&v.y,&v.z);
            normals.push_back(v);
            continue;
        }
        if(line[i][0]=='u'&&line[i][1]=='s'&&line[i][2]=='e')
        {
            sscanf(line[i].c_str(),"usemtl %s",&matName);
            continue;
        }
        if(line[i][0]=='f'&&line[i][1]==' ')
        {
            FaceTexture f;
            sscanf(line[i].c_str(),"f %d/%d/%d %d/%d/%d %d/%d/%d ",&v1,&v2,&v3,&t1,&t2,&t3,&n1,&n2,&n3);
            f.texture=matName;
            faces.push_back(f);
            V1.push_back(v1);V2.push_back(v2);V3.push_back(v3);
            T1.push_back(t1);T2.push_back(t2);T3.push_back(t3);
            N1.push_back(n1);N2.push_back(n2);N3.push_back(n3);
            continue;
        }
    }
    tc.resize(vertices.size());
    nc.resize(vertices.size());
    textureCoordinates.resize(vertices.size());
    normals.resize(vertices.size());
    for(i=0;i<faces.size();i++)
    {
        tc[V1[i]]=textureCoordinates[T1[i]];
        nc[V1[i]]=normals[N1[i]];
        tc[V2[i]]=textureCoordinates[T2[i]];
        nc[V2[i]]=normals[N2[i]];
        tc[V3[i]]=textureCoordinates[T3[i]];
        nc[V3[i]]=normals[N3[i]];
    }
    for(i=0;i<vertices.size();i++)
    {
        textureCoordinates[i]=tc[i];
        normals[i]=nc[i];
    }
    for(i=0;i<faces.size();i++)
    {
        faces[i].vertex[0]=V1[i];
        faces[i].vertex[1]=V2[i];
        faces[i].vertex[2]=V3[i];
    }
    setupMesh();
}

void Model::setupMesh()
    {
        glGenVertexArrays(1, &VAO);
    glGenBuffers(1, & VBO);
        glBindVertexArray(VAO);
        glBindBuffer(GL_ARRAY_BUFFER,  VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), &vertices[0], GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }

void Model::draw()
{
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(0);
}

The vertex shader:

#version 330 core

layout (location = 0) in vec3 position;
//layout (location = 1) in vec3 color;

out vec3 ourColor;

void main()
{
    ourColor=vec3(1,0,0);
    gl_Position = vec4(position, 1.0f);
    //ourColor = color;
}

And the frag shader:

#version 330 core

in vec3 ourColor;

out vec4 color;

void main()
{
    color = vec4(ourColor, 1.0f);
}

Main.cpp:

#include <GL/glew.h>
#include <global.h>

#include "Model.h"

using namespace std;

Model model;

int main()
{
    glewExperimental = GL_TRUE;
    glewInit();
    glViewport(0,0,800,800);
    initShader();
    model.loadModel("models/1/cube.obj");
    while (window.isOpen())
    {
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        while (window.pollEvent(Event))
        {
            if (Event.type == sf::Event::Closed)
                window.close();
        }
        sf::Shader::bind(&defaultShader);
        model.draw();
        window.display();
    }
    return 0;
}

Why is the program showing me a black screen?

  • 1
    Try some animation: zoom out / translate the model to be further away. The model may be rendered outside the screen, or it may be centered around the camera, showing the inside (which may be hidden because of backface culing). Also I can't seem to find where you set up the modelView and Projection matrices (something like gl/gluPerspective). – Kenney Nov 13 '15 at 17:32
  • Thats not it.If i try to use glBegin and glEnd to render a triangle it works perfectly.But with Modern OpenGL and shaders it doesnt. – Robert Puscasu Nov 13 '15 at 17:37
  • 1
    So the `models/1/cube.obj` is just a triangle? You're changing too many things at once. Stick with rendering the triangle using glBegin/End, and introduce the shaders to see if they work. Then, use a display list for the triangle, and see if that works. Then, load the model. That way it's easier to see where the problem is introduced. – Kenney Nov 13 '15 at 17:42
  • I created a project long time ago that loaded a model and it worked fine.But i used the old functions.Now i wanted to use shaders.Im completely sure that my loader works fine. – Robert Puscasu Nov 13 '15 at 17:46
  • you are not using any matrices in shaders so you are not transforming the Vertex positions, Normals, to your view in any way ... it is the same as you have Identity matrices in `ModelView,Projection,Texture` in old GL stuff which is most likelly not the case see [simple complete GL+GLSL+VAO/VBO normal shading example in C++/VCL](http://stackoverflow.com/a/31913542/2521214) and look at the vertex shader how the matrices are applied... if you are in compatibility profile you can still use `ftransform()` ... – Spektre Nov 14 '15 at 10:32

0 Answers0