简体   繁体   中英

Can't draw triangle using Opengl

in this code i want to draw a simple triangle on a blue background using openGL however when i compile and run the code only a window with the blue background appears (without the white triangle that is supposed to be drawn), iam using Xcode

my code

#include <iostream>
#include <string>
#include <GLUT/glut.h>
#include <OpenGL/gl3.h>
#include <fstream>

using namespace std;

// VAO & VBO objects
GLuint VBO;
GLuint VAO;

void display();

// vertex Data (position)
float vertex[] = {-1.0, 0.0 , 1.0,
                   0.0, 1.0 , 0.0,
                   0.0, 0.0 , 0.0 };

GLuint Program;

GLuint Vshader;
GLuint Fshader;

// main program

int main (int argc, char *argv[])

{    

   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_DOUBLE);
   glutInitWindowSize(1000, 400);
   glutInitWindowPosition(100, 100);
   glutCreateWindow("My First GLUT/OpenGL Window");
   glutDisplayFunc(display);
   glutMainLoop();


   return 0;
}



// main display function 

void display()

{
// reading the vertex shader

fstream VertexS;
VertexS.open("/Users/hawbashali/Desktop/Project X/BwlbWl/BwlbWl/vertexShader");

if(VertexS.good() == false)
    cout << "Error openning the file \n";
if(VertexS.bad() == true)
    cout << "Read/writing error on i/o operation \n";
if (VertexS.fail() == true)
    cout <<"Logical error on i/o operation \n";

VertexS.seekg(0,ios::end);
int size =  (int)VertexS.tellg();
VertexS.clear();
VertexS.seekg(0,ios::beg);

char* vBuffer = new (nothrow) char[size];

VertexS.read(vBuffer,size);

VertexS.close();



// reading fragment shader

fstream FragS;
FragS.open("/Users/hawbashali/Desktop/Project X/BwlbWl/BwlbWl/fragmentShader");

if(FragS.good() == false)
    cout << "Error openning the file \n";
if(FragS.bad() == true)
    cout << "Read/writing error on i/o operation \n";
if (FragS.fail() == true)
    cout <<"Logical error on i/o operation \n";

FragS.seekg(0,ios::end);
int size2 =  (int)FragS.tellg();
FragS.clear();
FragS.seekg(0,ios::beg);

char* fBuffer = new (nothrow) char[size2];

FragS.read(fBuffer,size2);

FragS.close();


// creating shaders

Vshader = glCreateShader(GL_VERTEX_SHADER);
Fshader = glCreateShader(GL_FRAGMENT_SHADER);

GLint x = size;
GLint y = size2;


glShaderSource(Vshader, 1,(const char**)&vBuffer, &x);
glShaderSource(Fshader, 1, (const char**)&fBuffer, &y);

glCompileShader(Vshader);
glCompileShader(Fshader);

Program = glCreateProgram();

glAttachShader(Program, Vshader);
glAttachShader(Program, Fshader);

glLinkProgram(Program);

glUseProgram(Program);



glClearColor(0, 0, 1,1);
glClear(GL_COLOR_BUFFER_BIT);

glGenBuffers(1,&VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER,9 *sizeof(vertex),vertex, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);

glVertexAttribPointer(0, 3,GL_FLOAT, GL_TRUE, 0, 0);

// Drawing the triangle
glDrawArrays(GL_TRIANGLES, 0, 3);

glDisableVertexAttribArray(0);

glutSwapBuffers();

glDeleteShader(Vshader);
glDeleteShader(Fshader);

delete [] vBuffer;
delete [] fBuffer;

};

Vertex shader:

#version 320 core
layout(location = 0) in vec4 vPosition;
void
main()
 {
     gl_Position = vPosition;
}

Fragment Shader

#version 320 core
out vec4 fColor;
void
main()
{
  fColor = vec4(0.0, 0.0, 1.0, 1.0);
}
glClearColor(0, 0, 1,1);
...
fColor = vec4(0.0, 0.0, 1.0, 1.0);

You're trying to draw a blue triangle on top of a blue background. You'll have to dial up your contrast pretty high to see that :)

Make one of them a different color, like red.

You're also:

Try this:

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <vector>
#include <iostream>

struct Program
{
    static GLuint Load( const char* vert, const char* geom, const char* frag )
    {
        GLuint prog = glCreateProgram();
        if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
        if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
        if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    }

private:
    static void CheckStatus( GLuint obj )
    {
        GLint status = GL_FALSE, len = 10;
        if( glIsShader(obj) )   glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        if( glIsShader(obj) )   glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
        std::vector< char > log( len, 'X' );
        if( glIsShader(obj) )   glGetShaderInfoLog( obj, len, NULL, &log[0] );
        if( glIsProgram(obj) )  glGetProgramInfoLog( obj, len, NULL, &log[0] );
        std::cerr << &log[0] << std::endl;
        exit( -1 );
    }

    static void AttachShader( GLuint program, GLenum type, const char* src )
    {
        GLuint shader = glCreateShader( type );
        glShaderSource( shader, 1, &src, NULL );
        glCompileShader( shader );
        CheckStatus( shader );
        glAttachShader( program, shader );
        glDeleteShader( shader );
    }
};

#define GLSL(version, shader) "#version " #version "\n" #shader

const char* vert = GLSL
( 
    150 core,
    layout(location = 0) in vec4 vPosition;
    void
    main()
    {
        gl_Position = vPosition;
    }
);

const char* frag = GLSL
( 
    150 core,
    out vec4 fColor;
    void
    main()
    {
        fColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
);

// VAO & VBO objects
GLuint VAO;
GLuint VBO;
GLuint prog;
void init()
{
    // vertex Data (position)
    float vertex[] = { -1.0, -1.0 , 0.0,
                        1.0, -1.0 , 0.0,
                        0.0,  1.0 , 0.0 };

    glGenVertexArrays( 1, &VAO );
    glBindVertexArray( VAO );

    glGenBuffers(1,&VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(vertex), vertex, GL_STATIC_DRAW);

    prog = Program::Load( vert, NULL, frag );
    glUseProgram( prog );

    glEnableVertexAttribArray(0);
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, 0 );
}

void display()
{
    glClearColor(0, 0, 1,1);
    glClear(GL_COLOR_BUFFER_BIT);

    // Drawing the triangle
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glutSwapBuffers();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
    glutInitWindowSize(1000, 400);
    glutInitWindowPosition(100, 100);
    glutInitContextVersion(3, 2);
    glutInitContextProfile(GLUT_CORE_PROFILE);
    glutCreateWindow("My First GLUT/OpenGL Window");

    glewExperimental = GL_TRUE;
    if( GLEW_OK != glewInit() )
        return -1;

    init();

    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

EDIT : Ported to GL 2.1:

#include <GL/glew.h>
#include <GL/glut.h>
#include <vector>
#include <iostream>

struct Program
{
    static GLuint Load( const char* vert, const char* geom, const char* frag )
    {
        GLuint prog = glCreateProgram();
        if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
        if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
        if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    }

private:
    static void CheckStatus( GLuint obj )
    {
        GLint status = GL_FALSE, len = 10;
        if( glIsShader(obj) )   glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        if( glIsShader(obj) )   glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
        std::vector< char > log( len, 'X' );
        if( glIsShader(obj) )   glGetShaderInfoLog( obj, len, NULL, &log[0] );
        if( glIsProgram(obj) )  glGetProgramInfoLog( obj, len, NULL, &log[0] );
        std::cerr << &log[0] << std::endl;
        exit( -1 );
    }

    static void AttachShader( GLuint program, GLenum type, const char* src )
    {
        GLuint shader = glCreateShader( type );
        glShaderSource( shader, 1, &src, NULL );
        glCompileShader( shader );
        CheckStatus( shader );
        glAttachShader( program, shader );
        glDeleteShader( shader );
    }
};

#define GLSL(version, shader) "#version " #version "\n" #shader

const char* vert = GLSL
( 
    120,
    attribute vec4 vPosition;
    void main()
    {
        gl_Position = vPosition;
    }
);

const char* frag = GLSL
( 
    120,
    void main()
    {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
);

// VBO objects
GLuint VBO;
GLuint prog;
void init()
{
    // vertex Data (position)
    float vertex[] = { -1.0, -1.0 , 0.0,
                        1.0, -1.0 , 0.0,
                        0.0,  1.0 , 0.0 };

    glGenBuffers(1,&VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(vertex), vertex, GL_STATIC_DRAW);

    prog = Program::Load( vert, NULL, frag );
    glUseProgram( prog );

    int posLoc = glGetAttribLocation( prog, "vPosition" );
    glEnableVertexAttribArray( posLoc );
    glVertexAttribPointer( posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0 );
}

void display()
{
    glClearColor(0, 0, 1,1);
    glClear(GL_COLOR_BUFFER_BIT);

    // Drawing the triangle
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glutSwapBuffers();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
    glutInitWindowSize(1000, 400);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("My First GLUT/OpenGL Window");

    if( GLEW_OK != glewInit() )
        return -1;

    init();

    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

You have provided invalid buffer size in the following line:

glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(vertex), vertex, GL_STATIC_DRAW);

Because sizeof(vertex) should return the total size of the array (eg 36) not the underlying type, thus no need to multiply by 9. If you still want to use multiplication try following:

9 * sizeof(float)

I have to write this down... You should separate your initialization and draw cycle like in genpfault's answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM