I'm trying to figure out how to use multiple buffers associated to a single vertex array object on the basis of one buffer per "object model" (e.g. verticies, normal, textures). To make it very simple in the sample code that follows I have couple objects composed of just one triangles (3 vertices) and associated colors. Buffer element indexed by ArrayBuffer1 receive the vertex coords (homogeneous coords) and an RGBA color vectors. Same for Buffer element indexed by ArrayBuffer2.
The vertex shader is a passthrough as following
#version 400 core
layout( location = 0 ) in vec4 vPosition;
layout( location = 1 ) in vec4 vColor;
out vec4 color;
void
main()
{
color= vColor;
gl_Position = vPosition;
}
The fragment shader is a passthroug has well
#version 450 core
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
I d like to pass on data with one buffer per object grouping vertex attributes in the same buffer.
I can't figure how to raw these 2 objects.
Here is the client code (init part)
enum VertexDim { xDim, yDim, zDim, wDim, NumDim};
enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer1, ArrayBuffer2, NumBuffers };
enum Attrib_IDs { vPosition = 0, vColor=1 };
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
const GLuint NumVertices = 6;
const GLuint curDim= NumDim;
// first triangle
GLfloat static_vertices1[NumVertices/2][NumDim] = {
{ -0.90f, -0.90f, 0.5f, 1}, { 0.85f, -0.90f, 0.3f, 1 }, { -0.90f, 0.85f, 0.0f, 1 } // Triangle 1
};
// second triangle
GLfloat static_vertices2[NumVertices/2][NumDim] = {
{ 0.90f, -0.85f, -0.1f, 1 }, { 0.90f, 0.90f, -0.5f, 1 }, { -0.85f, 0.90f, -0.8f, 1 } // Triangle 2
};
// a base color from which to compute different vertex colors
GLfloat infColor_value[4]= {0.9f, 0.7f, 0.5f, 1.0f};
//----------------------------------------------------------------------------
//
// init
//
void
init( void )
{
const unsigned int n=NumVertices/2;
GLfloat infColor_values1[n][curDim];
GLfloat infColor_values2[n][curDim];
// compute different vertex colors from base color infColor_value
// .. loop over infColor_values1 and infColor_values2
ShaderInfo shaders[] =
{
{ GL_VERTEX_SHADER, "media/shaders/triangles/triangles2.vert" },
{ GL_FRAGMENT_SHADER, "media/shaders/triangles/triangles2.frag" },
{ GL_NONE, NULL }
};
// LoadShaders is a wrapper to load, compile code and link shaders
GLuint program = LoadShaders( shaders );
if( program == 0) { std::cerr<<"shader program failed to build" << std::endl; }
glUseProgram( program );
glGenVertexArrays( NumVAOs, VAOs );
glBindVertexArray( VAOs[Triangles] );
glCreateBuffers( NumBuffers, Buffers );
// vertex 1
glBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer1] );
glNamedBufferData( Buffers[ArrayBuffer1], sizeof(static_vertices1)+sizeof(infColor_values1) , NULL, GL_STATIC_DRAW);
glNamedBufferSubData( Buffers[ArrayBuffer1], 0, sizeof(static_vertices1), static_vertices1);
glNamedBufferSubData( Buffers[ArrayBuffer1], sizeof(static_vertices1), sizeof(infColor_values1), infColor_values1);
GLuint64 offset = 0;
glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
glEnableVertexAttribArray( vPosition );
offset = sizeof(static_vertices1);
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
glEnableVertexAttribArray( vColor );
// vertex 2
glBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer2] );
glNamedBufferData( Buffers[ArrayBuffer2], sizeof(static_vertices2)+sizeof(infColor_values2) , NULL, GL_STATIC_DRAW);
glNamedBufferSubData( Buffers[ArrayBuffer2], 0, sizeof(static_vertices2), static_vertices1);
glNamedBufferSubData( Buffers[ArrayBuffer2], sizeof(static_vertices2), sizeof(infColor_values2), infColor_values2);
offset = 0;
glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
glEnableVertexAttribArray( vPosition );
offset = sizeof(static_vertices2);
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
glEnableVertexAttribArray( vColor );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindVertexArray(0);
}
and here follows the code to render
void
display( void )
{
static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
glClearBufferfv(GL_COLOR, 0, black);
glBindVertexArray( VAOs[Triangles] );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
glBindVertexArray(0);
}
to sum it up : how to store an object vertices attributes in a single buffer and still display multiple objects ?
I could fetch verything in the same sub buffers (one for vertex coord, one for vetex colors) but I can't come up wit ha solution where I would sparate the obejcts to render.
I ve read close answers ( Architecture to draw many different objects in OpenGL What are Vertex Array Objects? ) related to this question yet it does not answer my question.
Defining a VAO for each object made it following #Rabbid76 advice
change for the init code
enum Buffer_IDs { Mesh, NumBuffers };
//....
// triangle 1
glBindBuffer( GL_ARRAY_BUFFER, Buffers1[Mesh] );
glNamedBufferData( Buffers1[Mesh], sizeof(static_vertices1)+sizeof(infColor_values1) , NULL, GL_STATIC_DRAW);
glNamedBufferSubData( Buffers1[Mesh], 0, sizeof(static_vertices1), static_vertices1);
glNamedBufferSubData( Buffers1[Mesh], sizeof(static_vertices1), sizeof(infColor_values1), infColor_values1);
GLuint64 offset = 0;
glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
glEnableVertexAttribArray( vPosition );
offset = sizeof(static_vertices1);
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
glEnableVertexAttribArray( vColor );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindVertexArray(0);
// triangle 2
glBindVertexArray( VAOs[Triangle2] );
glCreateBuffers( NumBuffers, Buffers2 );
glBindBuffer( GL_ARRAY_BUFFER, Buffers2[Mesh] );
glNamedBufferData( Buffers2[Mesh], sizeof(static_vertices2)+sizeof(infColor_values2) , NULL, GL_STATIC_DRAW);
glNamedBufferSubData( Buffers2[Mesh], 0, sizeof(static_vertices2), static_vertices2);
glNamedBufferSubData( Buffers2[Mesh], sizeof(static_vertices2), sizeof(infColor_values2), infColor_values2);
offset = 0;
glVertexAttribPointer( vPosition, NumDim, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
glEnableVertexAttribArray( vPosition );
offset = sizeof(static_vertices2);
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)offset );
glEnableVertexAttribArray( vColor );
change for the render code
void
display( void )
{
static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
glClearBufferfv(GL_COLOR, 0, black);
glBindVertexArray( VAOs[Triangle1] );
glDrawArrays( GL_TRIANGLES, 0, NumVertices/2 );
glBindVertexArray( VAOs[Triangle2] );
glDrawArrays( GL_TRIANGLES, 0, NumVertices/2 );
glBindVertexArray(0);
}
This is the goal:
I can get the inverted triangle with:
GLfloat vertices[][4] = {
{-0.75, 0.5, 0.0, 1.0},
{0.75, 0.5, 0.0, 1.0},
{0.0, -0.75, 0.0, 1.0}};
and some of the rectangle with:
GLfloat vertices[][4] = {
{-0.9, 0.0, 0.0, 1.0},
{0.9, 0.0, 0.0, 1.0},
{-0.9, -0.9, 0.0, 1.0}};
When I try to add the fourth vertex ({0.0, -0.9, 0.0, 1.0}), it loses its form and creates a skinny rectangle in the top left like this:
When I try to draw them both at the same time, I get a black screen.
How can I draw that goal image?
full code:
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#define BUFFER_OFFSET(offset) ((GLvoid *) offset)
GLuint buffer = 0;
GLuint vPos;
GLuint program;
void init()
{
// Three vertexes that define a triangle.
GLfloat vertices[][ 4 ] =
{
{-0.75, -0.5, 0.0, 1.0},
{0.75, -0.5, 0.0, 1.0},
{0.0, 0.75, 0.0, 1.0}
};
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
// OpenGL vertex shader source code
const char* vSource =
{
"#version 330\n"
"in vec4 vPos;"
"void main() {"
" gl_Position = vPos * vec4(1.0f, 1.0f, 1.0f, 1.0f);"
"}"
};
// OpenGL fragment shader source code
const char* fSource =
{
"#version 330\n"
"out vec4 fragColor;"
"void main() {"
" fragColor = vec4(0.8, 0.8, 0, 1);"
"}"
};
// Declare shader IDs
GLuint vShader, fShader;
// Create empty shader objects
vShader = glCreateShader( GL_VERTEX_SHADER );
fShader = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( vShader, 1, &vSource, NULL );
glShaderSource( fShader, 1, &fSource, NULL );
glCompileShader( vShader );
glCompileShader( fShader );
// Create an empty shader program object
program = glCreateProgram();
// Attach vertex and fragment shaders to the shader program
glAttachShader( program, vShader );
glAttachShader( program, fShader );
// Link the shader program
glLinkProgram( program );
vPos = glGetAttribLocation( program, "vPos" );
// Specify the background color
glClearColor( 0, 0, 0, 1 );
}
void reshape( int width, int height )
{
// Specify the width and height of the picture within the window
glViewport( 0, 0, width, height );
}
void display()
{
// Clear the window with the background color
glClear( GL_COLOR_BUFFER_BIT );
// Activate the shader program
glUseProgram( program );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
glVertexAttribPointer( vPos, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET( 0 ) );
glEnableVertexAttribArray( vPos );
// Start the shader program
glDrawArrays( GL_TRIANGLES, 0, 3 );
// Refresh the window
glutSwapBuffers();
}
void main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutCreateWindow( argv[ 0 ] );
glewInit();
init();
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutMainLoop();
}
I am using Xcode to write openGL. What I am doing is to draw a circle, a triangle, and a square.
However, I found that my circle only can display on
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
the triangle and square can only display on glutInitDisplayMode(GLUT_3_2_CORE_PROFILE|GLUT_RGBA | GLUT_SINGLE);
How can i make them display together?
Here is part of my entire code:
#include "Angel.h" //includes gl.h, glut.h and other stuff...
void m_glewInitAndVersion(void); //pre-implementation declaration (could do in header file)
void close(void);
//Mesh 0
GLuint buffer[3];
GLuint VAO[3];
GLuint color_loc;
GLuint program;
const int NumVertices = 4;
// Vertices of a unit cube centered at origin, sides aligned with axes
vec2 points[4] = {
vec2( 0.25, 0.25),
vec2( 0.75, 0.25),
vec2( 0.75, 0.75),
vec2( 0.25, 0.75)
};
vec2 points2[3]={
vec2(-1,-1),
vec2(0,-1),
vec2(0,-0.7)};
// RGBA colors
vec4 blue_opaque = vec4( 0.0, 0.0, 1.0, 1.0 );
vec4 red_opaque = vec4(1.0, 0.0, 0.0, 1.0);
//----------------------------------------------------------------------------
// OpenGL initialization
void
init()
{
glClearColor( 1.0, 1.0, 1.0, 1.0 );
// glColor3f(1.0, 0.0, 0.0);
// glMatrixMode(GL_PROJECTION);
// glLoadIdentity();
// gluOrtho2D(-3.5, 3.5, -3.5, 3.5);
// Create and initialize a buffer object
glGenBuffers( 2, buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer[0] );
glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );
// Load shaders and use the resulting shader program
program = InitShader( "vshader00_v150.glsl", "fshader00_v150.glsl" );
glUseProgram( program );
// set up vertex arrays
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
//Set up VAO
glGenVertexArrays(2,VAO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER,buffer[0]);
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
color_loc = glGetUniformLocation(program, "color");
//triangle
// glBindVertexArray(VAO[1]);
// glBindBuffer(GL_ARRAY_BUFFER, buffer[1]);
// glBufferData(GL_ARRAY_BUFFER, sizeof(points2), points2, GL_STATIC_DRAW);
// glUseProgram(program);
// glEnableVertexAttribArray(vPosition);
// glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
}
//----------------------------------------------------------------------------
void
display( void )
{
glClear( GL_COLOR_BUFFER_BIT );
// const float PI=3.14159;
// glBegin(GL_TRIANGLE_FAN);
// All triangles fan out starting with this point
// glVertex2f (0.0,0.0);
// for (int i = 0; i <=361; i++)
// {
// glColor3f(float(rand())/float(RAND_MAX),
// float(rand())/float(RAND_MAX),
// float(rand())/float(RAND_MAX));
// glVertex2f(2.0*cos(i*PI/180), 2.0*sin(i*PI/180));
// }
// glEnd();
glBindVertexArray(VAO[0]);
glDrawArrays( GL_TRIANGLE_FAN, 0, NumVertices );
glUseProgram(program);
glUniform4fv(color_loc, 1, blue_opaque);
// glBindVertexArray(VAO[1]);
// glDrawArrays( GL_TRIANGLE_FAN, 0, 3);
// glUseProgram(program);
// glUniform4fv(color_loc, 1, red_opaque);
glFlush();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
#ifdef __APPLE__
glutInitDisplayMode(GLUT_3_2_CORE_PROFILE|GLUT_RGBA | GLUT_SINGLE);
#else
glutInitDisplayMode( GLUT_RGBA | GLUT_SINGLE);
#endif
glutInitWindowSize( 500, 500 );
glutCreateWindow( "CS 432 Hello World" );
m_glewInitAndVersion();
init();
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutWMCloseFunc(close);
glutMainLoop();
return 0;
}
Your circle code doesn't work with GLUT_3_2_CORE_PROFILE because glBegin, glColor3f, glVertex2f and glEnd were removed in OpenGL 3, so OpenGL 3.2 (or later) doesn't have them.
I'm not sure exactly why your triangle and square code doesn't work without GLUT_3_2_CORE_PROFILE, but consider that VAOs were added in OpenGL 3, and when you don't specify GLUT_3_2_CORE_PROFILE, you get a version before 3.
Pick a version and stick with it.
I just wanna do the basics... give the shaders information from my application. I tried everything and nothing worked because I can never figure out what is new and what is deprecated in OpenGL
Vertex Shader:
#version 420 core
layout(location = 0) in vec2 p_rect;
layout(location = 1) in vec2 p_clipRect;
out vec2 texturePoint;
void main()
{
gl_Position = vec4( p_rect, 0.0, 1.0 );
texturePoint = p_clipRect;
}
Fragment Shader:
#version 420 core
uniform sampler2D p_texture;
in vec2 texturePoint;
out vec4 outColor;
void main()
{
outColor = texture( p_texture, texturePoint );
}
OpenGL Code:
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, texture );
GLint texture_id( glGetUniformLocation( programId, "p_texture" ) );
glUniform1i( texture_id, texture );
// Element
static const GLushort element[] = { 0, 1, 2, 3 };
GLuint element_id;
glGenBuffers( 1, &element_id );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, element_id );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( element ), element, GL_STATIC_DRAW );
// Vertex data
struct VertexInput
{
GLfloat m_rect[ 8 ];
GLfloat m_clipRect[ 8 ];
}
vertex;
// fill it up with data
GLfloat vertex_data[] =
{
-1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, -1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
};
memcpy( &vertex, &vertex_data, sizeof( vertex_data ) );
// VBO
GLuint vertex_id;
glGenBuffers( 1, &vertex_id );
glBindBuffer( GL_ARRAY_BUFFER, vertex_id );
glBufferData( GL_ARRAY_BUFFER, sizeof(vertex), &vertex, GL_STATIC_DRAW );
glEnableVertexAttribArray( 0 );
glEnableVertexAttribArray( 1 );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_TRUE, 0, (void*)offsetof( VertexInput, m_rect ) );
glVertexAttribPointer( 1, 2, GL_FLOAT, GL_TRUE, 0, (void*)offsetof( VertexInput, m_clipRect ) );
// render the VBO
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, element_id );
glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0 );
// clean it up ;-)
glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 1 );
The weird thing:
Case 1: If programId is the actual program id, I get texture_id = 0 but no information gets to the shader... nothing happens...
Case 2: If programId is anything other than the actual program id, I get texture_id = -1 but my code RENDERS the image perfectly (WEARD).
The thing is that... I know it's still wrong. I need to be able to give information to the shader and then render... I really don't know how the case 2 is working, but the fact is that I need to give more information to the shaders, like other textures, MVP matrix and so son. I can't do it. What is wrong? How do I give the correct value of my program id and get this information in the shader?
glActiveTexture( GL_TEXTURE0 );
...
glUniform1i( texture_id, texture );
Try this instead:
glActiveTexture( GL_TEXTURE0 + 0 );
...
glUniform1i( texture_id, 0 );
Sampler uniforms should be assigned the index of the desired texture unit, not the texture object ID.
I'm just trying to draw a bunch of lines that make up a "cube". I can't for the life of me figure out why this is producing a black screen. The debugger does not break at any point.
I'm sure it's a problem with my pointers, as I'm only decent at them in regular c++ and in OpenGL it gets even worse.
const char* vertexSource =
"#version 150\n"
"in vec3 position;"
"void main() {"
" gl_Position = vec4(position, 1.0);"
"}";
const char* fragmentSource =
"#version 150\n"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";
int main() {
initializeGLFW();
// Initialize GLEW
glewExperimental = GL_TRUE;
glewInit();
// Create Vertex Array Object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers( 1, &vbo );
float vertices[] = {
1.0f, 1.0f, 1.0f, // Vertex 0 (X, Y, Z)
-1.0f, 1.0f, 1.0f, // Vertex 1 (X, Y, Z)
-1.0f, -1.0f, 1.0f, // Vertex 2 (X, Y, Z)
1.0f, -1.0f, 1.0f, // Vertex 3 (X, Y, Z)
1.0f, 1.0f, -1.0f, // Vertex 4 (X, Y, Z)
-1.0f, 1.0f, -1.0f, // Vertex 5 (X, Y, Z)
-1.0f, -1.0f, -1.0f, // Vertex 6 (X, Y, Z)
1.0f, -1.0f, -1.0f // Vertex 7 (X, Y, Z)
};
GLuint indices[] = {
0, 1,
1, 2,
2, 3,
3, 0,
4, 5,
5, 6,
6, 7,
7, 4,
0, 4,
1, 5,
2, 6,
3, 7
};
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
//glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vbo);
//glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW );
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertexShader, 1, &vertexSource, NULL );
glCompileShader( vertexShader );
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( fragmentShader, 1, &fragmentSource, NULL );
glCompileShader( fragmentShader );
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader( shaderProgram, vertexShader );
glAttachShader( shaderProgram, fragmentShader );
glBindFragDataLocation( shaderProgram, 0, "outColor" );
glLinkProgram (shaderProgram);
glUseProgram( shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation( shaderProgram, "position" );
glEnableVertexAttribArray( posAttrib );
glVertexAttribPointer( posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0 );
// Main loop
while(glfwGetWindowParam(GLFW_OPENED)) {
// Clear the screen to black
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );
// Draw lines from 2 vertices
glDrawElements(GL_LINES, sizeof(indices), GL_UNSIGNED_INT, indices );
// Swap buffers
glfwSwapBuffers();
}
// Clean up
glDeleteProgram( shaderProgram );
glDeleteShader( fragmentShader );
glDeleteShader( vertexShader );
//glDeleteBuffers( 1, &ebo );
glDeleteBuffers( 1, &vbo );
glDeleteVertexArrays( 1, &vao );
glfwTerminate();
exit( EXIT_SUCCESS );
}
EDIT: Full code trying the first answer's recommendation. Still blank.
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/glfw.h>
#include <iostream>
#pragma comment( lib, "glfw.lib")
#pragma comment( lib, "opengl32.lib")
#pragma comment( lib, "glew32s.lib")
const char* vertexSource =
"#version 150\n"
"in vec3 position;"
"void main() {"
" gl_Position = vec4(position.x, position.y, position.z - 0.9, 1.0);"
"}";
const char* fragmentSource =
"#version 150\n"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";
void initializeGLFW();
int main() {
initializeGLFW();
// Initialize GLEW
glewExperimental = GL_TRUE;
glewInit();
// Create Vertex Array Object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers( 1, &vbo );
float vertices[] = {
1.0f, 1.0f, 1.0f, // Vertex 0 (X, Y, Z)
-1.0f, 1.0f, 1.0f, // Vertex 1 (X, Y, Z)
-1.0f, -1.0f, 1.0f, // Vertex 2 (X, Y, Z)
1.0f, -1.0f, 1.0f, // Vertex 3 (X, Y, Z)
1.0f, 1.0f, -1.0f, // Vertex 4 (X, Y, Z)
-1.0f, 1.0f, -1.0f, // Vertex 5 (X, Y, Z)
-1.0f, -1.0f, -1.0f, // Vertex 6 (X, Y, Z)
1.0f, -1.0f, -1.0f // Vertex 7 (X, Y, Z)
};
size_t vertCount = sizeof( vertices ) / sizeof( float );
for( size_t i = 0; i < vertCount; ++i ) {
vertices[i] /= 2.0f;
}
GLubyte indices[] = {
0, 1,
1, 2,
2, 3,
3, 0,
4, 5,
5, 6,
6, 7,
7, 4,
0, 4,
1, 5,
2, 6,
3, 7
};
glBindBuffer( GL_ARRAY_BUFFER, vbo );
//glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vbo);
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertexShader, 1, &vertexSource, NULL );
glCompileShader( vertexShader );
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( fragmentShader, 1, &fragmentSource, NULL );
glCompileShader( fragmentShader );
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader( shaderProgram, vertexShader );
glAttachShader( shaderProgram, fragmentShader );
glBindFragDataLocation( shaderProgram, 0, "outColor" );
glLinkProgram (shaderProgram);
glUseProgram( shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation( shaderProgram, "position" );
glEnableVertexAttribArray( posAttrib );
glVertexAttribPointer( posAttrib, 3, GL_FLOAT, GL_FALSE, 0, vertices );
// Main loop
while(glfwGetWindowParam(GLFW_OPENED)) {
// Clear the screen to black
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );
// Draw lines from 2 vertices
glDrawElements(GL_LINES, 24, GL_UNSIGNED_BYTE, indices);
// Swap buffers
glfwSwapBuffers();
}
// Clean up
glDeleteProgram( shaderProgram );
glDeleteShader( fragmentShader );
glDeleteShader( vertexShader );
//glDeleteBuffers( 1, &ebo );
glDeleteBuffers( 1, &vbo );
glDeleteVertexArrays( 1, &vao );
glfwTerminate();
exit( EXIT_SUCCESS );
}
void initializeGLFW() {
glfwInit();
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MAJOR, 3 );
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MINOR, 2 );
glfwOpenWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
glfwOpenWindowHint( GLFW_WINDOW_NO_RESIZE, GL_TRUE );
glfwOpenWindow( 800, 600, 0, 0, 0, 0, 0, 0, GLFW_WINDOW );
glfwSetWindowTitle( "OpenGL" );
}
The "default" projection is essentially glOrtho(-1, 1, -1, 1, -1, 1) with the camera at (0,0,0) looking down the -Z axis.
Move the camera back:
const char* vertexSource =
"#version 150\n"
"in vec3 position;"
"void main() {"
" gl_Position = vec4(position.x, position.y, position.z - 0.9, 1.0);"
"}";
And make your object smaller:
float vertices[] = {
1.0f, 1.0f, 1.0f, // Vertex 0 (X, Y, Z)
-1.0f, 1.0f, 1.0f, // Vertex 1 (X, Y, Z)
-1.0f, -1.0f, 1.0f, // Vertex 2 (X, Y, Z)
1.0f, -1.0f, 1.0f, // Vertex 3 (X, Y, Z)
1.0f, 1.0f, -1.0f, // Vertex 4 (X, Y, Z)
-1.0f, 1.0f, -1.0f, // Vertex 5 (X, Y, Z)
-1.0f, -1.0f, -1.0f, // Vertex 6 (X, Y, Z)
1.0f, -1.0f, -1.0f // Vertex 7 (X, Y, Z)
};
size_t vertCount = sizeof( vertices ) / sizeof( float );
for( size_t i = 0; i < vertCount; ++i )
{
vertices[i] /= 2.0f;
}
Complete:
#include <GL/glew.h>
#include <GL/glfw.h>
#include <cstdlib>
const char* vertexSource =
"#version 150\n"
"in vec3 position;"
"void main() {"
" gl_Position = vec4(position.x, position.y, position.z - 0.9, 1.0);"
"}";
const char* fragmentSource =
"#version 150\n"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";
void initializeGLFW()
{
glfwInit();
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MAJOR, 3 );
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MINOR, 2 );
glfwOpenWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
glfwOpenWindowHint( GLFW_WINDOW_NO_RESIZE, GL_TRUE );
glfwOpenWindow( 800, 600, 0, 0, 0, 0, 0, 0, GLFW_WINDOW );
glfwSetWindowTitle( "OpenGL" );
}
int main()
{
initializeGLFW();
// Initialize GLEW
glewExperimental = GL_TRUE;
glewInit();
// Create Vertex Array Object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers( 1, &vbo );
float vertices[] =
{
1.0f, 1.0f, 1.0f, // Vertex 0 (X, Y, Z)
-1.0f, 1.0f, 1.0f, // Vertex 1 (X, Y, Z)
-1.0f, -1.0f, 1.0f, // Vertex 2 (X, Y, Z)
1.0f, -1.0f, 1.0f, // Vertex 3 (X, Y, Z)
1.0f, 1.0f, -1.0f, // Vertex 4 (X, Y, Z)
-1.0f, 1.0f, -1.0f, // Vertex 5 (X, Y, Z)
-1.0f, -1.0f, -1.0f, // Vertex 6 (X, Y, Z)
1.0f, -1.0f, -1.0f // Vertex 7 (X, Y, Z)
};
size_t vertCount = sizeof( vertices ) / sizeof( float );
for( size_t i = 0; i < vertCount; ++i )
{
vertices[i] /= 2.0f;
}
GLuint indices[] =
{
0, 1,
1, 2,
2, 3,
3, 0,
4, 5,
5, 6,
6, 7,
7, 4,
0, 4,
1, 5,
2, 6,
3, 7
};
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertexShader, 1, &vertexSource, NULL );
glCompileShader( vertexShader );
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( fragmentShader, 1, &fragmentSource, NULL );
glCompileShader( fragmentShader );
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader( shaderProgram, vertexShader );
glAttachShader( shaderProgram, fragmentShader );
glBindFragDataLocation( shaderProgram, 0, "outColor" );
glLinkProgram (shaderProgram);
glUseProgram( shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation( shaderProgram, "position" );
glEnableVertexAttribArray( posAttrib );
glVertexAttribPointer( posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0 );
// Main loop
while(glfwGetWindowParam(GLFW_OPENED))
{
// Clear the screen to black
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );
// Draw lines from 2 vertices
glDrawElements(GL_LINES, sizeof(indices), GL_UNSIGNED_INT, indices );
// Swap buffers
glfwSwapBuffers();
}
// Clean up
glDeleteProgram( shaderProgram );
glDeleteShader( fragmentShader );
glDeleteShader( vertexShader );
//glDeleteBuffers( 1, &ebo );
glDeleteBuffers( 1, &vbo );
glDeleteVertexArrays( 1, &vao );
glfwTerminate();
exit( EXIT_SUCCESS );
}