OpenGL. Cannot draw multiple shapes. New init clears previously drawn shape - opengl

I'm trying to draw some squares within squares. I have two functions, initRedSquare() and initBlueSquare(). They have different buffers and seperate vao's which I just added before posting the question here.
Individually bothe get drawn. But I want the blue to show up over the red. When the blue square is made it removes the red square completely.
And I have to draw many more shapes after these two also.
Code :
void initRedSquare( GLfloat val )
{
GLfloat vertices[] =
{
+0.0f, +0.0f,
+1.0f, +0.0f, +0.0f,
(+0.8f - val), (+0.8f - val),
+1.0f, +0.0f, +0.0f,
(-0.8f + val), (+0.8f - val),
+1.0f, +0.0f, +0.0f,
(-0.8f + val), (-0.8f + val),
+1.0f, +0.0f, +0.0f,
(+0.8f - val), (-0.8f + val),
+1.0f, +0.0f, +0.0f,
};
// // Specifiy the vertices for a triangle
// vec2 vertices[3] = {
// vec2( -1, 0 ), vec2( -0.8, 1 ), vec2( -0.6, 0 )
// };
// Create a vertex array object
GLuint vao[1];
glGenVertexArrays( 1, vao );
glBindVertexArray( vao[0] );
// Create and initialize a buffer object
GLuint vertexbuffer;
glGenBuffers( 1, &vertexbuffer );
glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW );
// Load shaders and use the resulting shader program
GLuint program = InitShader( "vshader21.glsl", "fshader21.glsl" );
glUseProgram( program );
// Initialize the vertex position attribute from the vertex shader
GLuint vPosition_location = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition_location );
glVertexAttribPointer( vPosition_location, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5,
BUFFER_OFFSET(0) );
GLuint vColor_location = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor_location );
glVertexAttribPointer( vColor_location, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5,
BUFFER_OFFSET(sizeof(float) * 2) );
GLushort indices[] =
{
0, 1, 2,
0, 3, 4,
0, 2, 3,
0, 4, 1
};
GLuint indexBuffer;
glGenBuffers( 1, &indexBuffer );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW );
//glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background
}
void initBlueSquare( GLfloat val )
{
GLfloat vertices[] =
{
+0.0f, +0.0f,
+0.0f, +0.0f, +1.0f,
(+0.8f - val), (+0.8f - val),
+0.0f, +0.0f, +1.0f,
(-0.8f + val), (+0.8f - val),
+0.0f, +0.0f, +1.0f,
(-0.8f + val), (-0.8f + val),
+0.0f, +0.0f, +1.0f,
(+0.8f - val), (-0.8f + val),
+0.0f, +0.0f, +1.0f,
};
// // Specifiy the vertices for a triangle
// vec2 vertices[3] = {
// vec2( -1, 0 ), vec2( -0.8, 1 ), vec2( -0.6, 0 )
// };
// Create a vertex array object
GLuint vao[2];
glGenVertexArrays( 1, vao );
glBindVertexArray( vao[1] );
// Create and initialize a buffer object
GLuint vertexbuffer2;
glGenBuffers( 1, &vertexbuffer2 );
glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer2 );
glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW );
// Load shaders and use the resulting shader program
GLuint program = InitShader( "vshader21.glsl", "fshader21.glsl" );
glUseProgram( program );
// Initialize the vertex position attribute from the vertex shader
GLuint vPosition_location = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition_location );
glVertexAttribPointer( vPosition_location, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5,
BUFFER_OFFSET(0) );
GLuint vColor_location = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor_location );
glVertexAttribPointer( vColor_location, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5,
BUFFER_OFFSET(sizeof(float) * 2) );
GLushort indices[] =
{
0, 1, 2,
0, 3, 4,
0, 2, 3,
0, 4, 1
};
GLuint indexBuffer2;
glGenBuffers( 1, &indexBuffer2 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer2 );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW );
//glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background
}
void
display( void )
{
//glClear( GL_COLOR_BUFFER_BIT ); // clear the window
//glDrawArrays( GL_TRIANGLES, 0, 6 ); // draw the points
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, 0);
glFlush();
}
void
keyboard( unsigned char key, int x, int y )
{
switch ( key ) {
case 033:
exit( EXIT_SUCCESS );
break;
}
}
int
main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA );
glutInitWindowSize( 500, 500 );
glutCreateWindow( "Assignment 2" );
glewExperimental=GL_TRUE;
glewInit();
initRedSquare(0.2f);
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
initBlueSquare(0.3f);
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutMainLoop();
return 0;
}
Vertex Shader :
attribute vec4 vPosition;
attribute vec3 vColor;
varying vec3 finalColor;
void
main()
{
gl_Position = vPosition;
finalColor = vColor;
}
Fragment Shader :
varying vec3 finalColor;
void
main()
{
gl_FragColor = vec4( finalColor, 1.0 );
}

The way you're program is structured will not work out.
First, and most important, glutDisplayFunc( display ); does not call the draw function directly, it just tells glut which function should be called whenever something should be drawn. So this function has to be able to draw ALL the content at once, in your case it will require two draw-calls with the correct state set.
To do this you'll have to store the buffers/vaos that are generated in your init functions somewhere outside of these functions and draw both objects:
void display( void )
{
glClear( GL_COLOR_BUFFER_BIT );
glBindVertexArray(red_vao);
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, 0);
glBindVertexArray(blue_vao);
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, 0);
glFlush();
}
, where red_vao and blue_vao are the vao handles generated in the corresponding init function.

Related

vertex buffer object and data buffers [opengl]

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);
}

Drawing an inverted triangle on top of a rectangle with OpenGL

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();
}

openGL draw circle triangle and square in different display mode

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.

Weird behavior of OpenGL / glGetUniformLocation()

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.

C++ OpenGL wireframe cube rendering blank

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 );
}