I have the following code to try to draw a rectangle using vertex arrays:
glEnableClientState( GL_NORMAL_ARRAY );
glNormalPointer( GL_FLOAT, 0, &mNorms[ 0 ] );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, 0, &mTexCrds[ 0 ] );
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, &mVtxs[ 0 ] );
glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
The intent is to draw a simple rectangle via triangle strip using the corner pattern Far Left, Near Left, Far Right, Near Right. The variable values are as follows:
/* far left near left far right near right */
mNorms { 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0 }
mTexCrds { 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 }
mVtxs { -25.0, 0.0, -100.0, -25.0, 0.0, -50.0, 25.0, 0.0, -100.0, 25.0, 0.0, -50.0 }
My texture is a black tile with a thin blue border around all edges. When the rectangle is drawn using the above instructions, it is completely blue:
bad.jpg http://www.graemecentralstation.com/img/bad.jpg
Obviously, given the above texture coordinates I am expecting my 2D texture to be completely visible.
If I replace glDrawArrays() with a manually invocation using the same array data like this...
glBegin( GL_TRIANGLE_STRIP );
{
for( int i = 0; i < 4; ++i )
{
glNormal3fv( &mNorms[ i * 3 ] );
glTexCoord2fv( &mTexCrds[ i * 2 ] );
glVertex3fv( &mVtxs[ i * 3 ] );
}
}
glEnd();
... then the rectangle is drawn with the full texture map image visible as I expect:
good.jpg http://www.graemecentralstation.com/img/good.jpg
Any idea why glDrawArrays() would skew my texture so badly?
You can try to debug with using texture coordinates as colors in the fragment shader, so then you can see whether texture coordinates are correct.gl_FragColor = vec4( vec2( texCoord),0,1);
You perhaps need to add
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,texID);
just before glEnableClientState( GL_TEXTURE_COORD_ARRAY );
Related
I have a code below in C++ OpenGL. It has six triangles that form hexagonal.
However, I need to be able to rotate it in vertically.
Can someone help? TNX
Details: I have six independent triangles with vertices. In addition, there is two-dimensional array that is used for colors.
There is a loop starts at line [here] two keep windows rendering until it is exited. Another line at line [here-two] that is used to show all the triangles with their color.
//coordinates of triangle
float triangle[6][9] = {
{
0.0, 0.0, 0.0,
-0.5, 0.87, 0.0,
0.5, 0.87, 0.0
},
{
0.0, 0.0, 0.0,
-0.5, -0.87, 0.0,
0.5, -0.87, 0.0
},
{
0.0, 0.0, 0.0,
0.5, 0.87, 0.0,
1.0, 0.0, 0.0
},
{
0.0, 0.0, 0.0,
0.5, -0.87, 0.0,
1.0, 0.0, 0.0
},
{
0.0, 0.0, 0.0,
-0.5, 0.87, 0.0,
-1.0, 0.0, 0.0
},
{
0.0, 0.0, 0.0,
-0.5, -0.87, 0.0,
-1.0, 0.0, 0.0
}
};
float color[][9]{
{
255, 0, 0,
255, 0, 0,
255, 0, 0
},
{
0, 255, 0,
0, 255, 0,
0, 255, 0
},
{
0, 0, 255,
0, 0, 255,
0, 0, 255
}
};
int count = 0;
/* Loop until the user closes the window */ [here] while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
[here-two] for (int i = 0; i < 6; i++)
{
//Render OpenGL here
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, triangle[i]);
glColorPointer(3, GL_FLOAT, 0, color[count]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
count++;
if (count > 2) count = 0;
}
//Swap front and back buffers
glfwSwapBuffers(window);
//Poll for and process events
glfwPollEvents();
// Poll for and process events
glfwPollEvents();
}
Read up on the use of matrices. What most games do in this case is they apply a matrix in the shader (as a uniform variable) that will rotate the object. In this case, you would create a rotation matrix of angle x, pass it to the shader, and then every new frame increment x and pass it to the shader again.
For more information on the specifics of the implementation read these:
https://www.opengl.org/wiki/Uniform_(GLSL) - Creating uniform
variables in a shader and updating them
http://inside.mines.edu/fs_home/gmurray/ArbitraryAxisRotation/ -
Creating a matrix that will rotate a vertex.
And a tip with matrix operations: remember to apply them in the right order. If you want to get the object to rotate around it's centre, make sure the rotation matrix is applied first and that the origin of your mesh is it's centre.
I'm trying to draw a two patches of rectangle (for tessellation) and I want to draw them from 0,0 to 1,1 and other from 1,0 to 2,1
I'm using GL_PATCHES to send a quad to my graphics pipeline
My vertex data in homogeneous coordinates is
float vertices[32] = {
0.0, 0.0, 0.0, 1.0, //1st rec
1.0, 0.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
1.0, 0.0, 0.0, 1.0, //2nd rec
2.0, 0.0, 0.0, 1.0,
2.0, 1.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0
};
And in C++ code
glPatchParameteri(GL_PATCH_VERTICES, 4);
glDrawArraysInstanced(GL_PATCHES, 0, 4, 2);
But I'm only getting one rectangle patch from 0,0 to 1,1 on my screen. I don't understand why it it doesn't draw the second rectangle
My tessellation evaluation shader is
vec4 vert= vec4(0.0, 0.0, 0.0, 1.0);
vert.x = gl_in[0].gl_Position.x + gl_TessCoord.x;
vert.y = gl_in[0].gl_Position.y + gl_TessCoord.y;
I convert this vert to vec4 and pass it to gl_Position
glDrawArraysInstanced draws several instances of the data specified. In your case, it draws two times the vertices 0 to 4, which gives you two quads lying on the same position.
I would suggest you simply use glDrawArrays(GL_PATCHES, 0, 8) instead, but you could also keep your draw call and translate in the vertex shader according to the gl_InstanceID.
I'm trying to make the solar system in OpenGL.
Everytime I add a planet I need to pop the transformationmatrix so I can start over with the next one. This is working for only 2 planets. I am able to add a first planet (earth) and let is spin around the sun. Then I use glPopMatrix() and add a second planet spinning around the sun, this again works fine. But when I try to add a 3rd planet and do the exact same thing (pop the stack first and make it spin around the sun), it looks like the transformationMatrix isn't being reseted and the 3rd planet spins around the 2nd one like the 1st and 2nd planet spin around the sun.
Here is the code of my paintGL():
void PlanetsView::paintGL ()
{
this->dayOfYear = (this->dayOfYear+1);
this->hourOfDay = (this->hourOfDay+1) % 24;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
gluLookAt(camPosx ,camPosy ,camPosz,
camViewx,camViewy,camViewz,
camUpx, camUpy, camUpz );
//Draw Axes
glDisable( GL_LIGHTING );
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
glEnable( GL_LIGHTING );
glPushMatrix();
// rotate the plane of the elliptic
glRotated ( 5.0, 1.0, 0.0, 0.0 );
// draw the sun
GLfloat diff [] = { 0.7f , 0.5f , 0.0f };
glMaterialfv ( GL_FRONT, GL_DIFFUSE, diff );
//glutSolidSphere( 3.0, 25, 25 );
solidSphere(3.0, 25, 25);
// rotate the earth around the sun
glRotated( (GLdouble)(360.0 * dayOfYear /365.0), 0.0, 1.0, 0.0 );
glTranslated ( 4.0, 0.0, 0.0 );
// rotate the earth around its axis
glRotated( (GLdouble)(360.0 * hourOfDay/24.0), 0.0, 1.0, 0.0 );
// draw the earth
GLfloat diff2 [] = { 0.2f , 0.2f , 0.8f };
glMaterialfv ( GL_FRONT, GL_DIFFUSE, diff2 );
solidSphere(0.3, 25, 25);
glPopMatrix();
// rotate the new planet around the sun
glRotated( (GLdouble)(360.0 * dayOfYear /150.0), 0.0, 1.0, 0.0 );
glTranslated ( 6.0, 0.0, 0.0 );
// rotate the new planet around its axis
glRotated( (GLdouble)(360.0 * hourOfDay/36.0), 0.0, 1.0, 0.0 );
// draw the new planet
GLfloat diff3 [] = { 1.0f , 0.0f , 0.0f }; // red color
glMaterialfv ( GL_FRONT, GL_DIFFUSE, diff3 );
solidSphere(0.4, 25, 25);
glPopMatrix(); // looks like this pop doesn't do anything
/* From here, when adding a 3rd planet, it fails */
// rotate a 3rd planet around the sun
glRotated( (GLdouble)(360.0 * dayOfYear /800.0), 0.0, 1.0, 0.0 );
glTranslated ( 6.0, 0.0, 0.0 );
// rotate a 3rd planet around its axis
glRotated( (GLdouble)(360.0 * hourOfDay/12.0), 0.0, 1.0, 0.0 );
// draw the 3rd planet
GLfloat diff4 [] = { 1.0f , 1.0f , 0.0f }; // red color
glMaterialfv ( GL_FRONT, GL_DIFFUSE, diff4 );
solidSphere(0.3, 25, 25);
glPopMatrix();
}
And here is the code of solidSphere:
void solidSphere(GLdouble radius, GLint slices, GLint stacks)
{
glBegin(GL_LINE_LOOP);
GLUquadricObj* quadric = gluNewQuadric();
gluQuadricDrawStyle(quadric, GLU_FILL);
gluSphere(quadric, radius, slices, stacks);
gluDeleteQuadric(quadric);
glEnd();
}
glPopMatrix(); // looks like this pop doesn't do anything
Correct, this does not do anything (meaningful), you are underflowing the matrix stack.
You already popped the last thing off the stack a few lines prior to that.
If your intention was to have the second call to glPopMatrix () restore the matrix as it existed after calling glEnable( GL_LIGHTING ), then you need to add a call to glPushMatrix () immediately after your first glPopMatrix (). And you need to repeat that process one more time so that your third call to glPopMatrix () does not also underflow the stack.
I get the impression you are not quite clear how stacks work.
I'm just starting out using visual studios and C++ and I've been following along the examples in Ed Angel's Interactive Computer Graphics book. I've seem to come into a snag with the rotating RGB cube example. I followed along exactly and I have got it to run and display a cube but the cube is all black instead of colored. To my understanding everything is correct and I have haven't been able to find any suggestions or hints as to what went wrong from google searches. I was wondering if anyone here with much more experience than I have could help me figure out what happened or point me in the direction.
// Display a rotating color cube
#include "Angel.h"
typedef Angel::vec4 color4;
typedef Angel::vec4 point4;
const int NumVertices = 36;
point4 points[NumVertices];
color4 colors[NumVertices];
//Vertices of a unit cube centered at origin, sides aligned with axes
point4 vertices[8] = {
point4( -0.5, -0.5, 0.5, 1.0),
point4( -0.5, 0.5, 0.5, 1.0),
point4( 0.5, 0.5, 0.5, 1.0),
point4( 0.5, -0.5, 0.5, 1.0),
point4( -0.5, -0.5, -0.5, 1.0),
point4( -0.5, 0.5, -0.5, 1.0),
point4( 0.5, 0.5, -0.5, 1.0),
point4( 0.5, -0.5, -0.5, 1.0)
};
//RGBA colors
color4 vertex_colors[8] = {
color4( 0.0, 0.0, 0.0, 1.0), //black
color4( 1.0, 0.0, 0.0, 1.0), //red
color4( 1.0, 1.0, 0.0, 1.0), //yellow
color4( 0.0, 1.0, 0.0, 1.0), //blue
color4( 0.0, 0.0, 1.0, 1.0), //green
color4( 1.0, 0.0, 1.0, 1.0), //magenta
color4( 1.0, 1.0, 1.0, 1.0), //white
color4( 0.0, 1.0, 1.0, 1.0) //cyan
};
//Array of rotation angles (in degrees) for each coordinate axis
enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
int Axis = Xaxis;
GLfloat Theta[NumAxes] = { 0.0, 0.0, 0.0};
GLuint theta; //The location of the "theta" shader uniform variable
//----------------------------------------------------------------------------
//quad generates two triangles for each face and assigns colors to the vertices
int Index = 0;
void
quad( int a, int b, int c, int d)
{
colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
colors[Index] = vertex_colors[b]; points[Index] = vertices[b]; Index++;
colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
colors[Index] = vertex_colors[d]; points[Index] = vertices[d]; Index++;
}
//----------------------------------------------------------------------------
//generate 12 triangles: 36 vertices and 36 colors
void
colorcube( void )
{
quad( 1, 0, 3, 2);
quad( 2, 3, 7, 6);
quad( 3, 0, 4, 7);
quad( 6, 5, 1, 2);
quad( 4, 5, 6, 7);
quad( 5, 4, 0, 1);
}
//----------------------------------------------------------------------------
//OpenGL initialization
void
init( void )
{
colorcube();
//Create a vertex array object
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
//Create and initialize a buffer object
GLuint buffer;
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors), NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(points), points );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors );
//Load shaders and use the resulting shader program
GLuint program = InitShader( "vshader36.glsl", "fshader36.glsl" );
std::cout << "Program ID:" <<program;
glUseProgram ( program );
//set up vertex arrays
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points)) );
theta = glGetUniformLocation( program, "theta" );
glEnable( GL_DEPTH_TEST );
glClearColor( 1.0, 1.0, 1.0, 1.0 );
}
//----------------------------------------------------------------------------
void
display( void )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glUniform3fv( theta, 1, Theta );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
glutSwapBuffers();
}
//----------------------------------------------------------------------------
void
keyboard( unsigned char key, int x, int y )
{
switch ( key ) {
case 033:
case 'q': case 'Q':
exit( EXIT_SUCCESS );
break;
}
}
//----------------------------------------------------------------------------
void
mouse( int button, int state, int x, int y )
{
if ( state == GLUT_DOWN ) {
switch( button ) {
case GLUT_LEFT_BUTTON: Axis = Xaxis; break;
case GLUT_MIDDLE_BUTTON: Axis = Yaxis; break;
case GLUT_RIGHT_BUTTON: Axis = Zaxis; break;
}
}
}
//----------------------------------------------------------------------------
void
idle( void )
{
Theta[Axis] += 0.01;
if ( Theta[Axis] > 360.0 ) {
Theta[Axis] -= 360.0;
}
glutPostRedisplay();
}
//----------------------------------------------------------------------------
int
main( int argc, char **argv )
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowSize( 512, 512 );
glutCreateWindow( "Color Cube" );
glewInit();
init();
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutMouseFunc( mouse );
glutIdleFunc( idle );
glutMainLoop();
return 0;
}
fshader36.glsl
#version 150
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
vshader36.glsl
#version 150
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
uniform vec3 theta;
void main()
{
vec3 angles = radians( theta );
vec3 c = cos( angles );
vec3 s = sin( angles );
mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
0.0, c.x, -s.x, 0.0,
0.0, s.x, c.x, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 ry = mat4( c.y, 0.0, s.y, 0.0,
0.0, 1.0, 0.0, 0.0,
-s.y, 0.0, c.y, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
s.z, c.z, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 );
color = vColor;
gl_Position = rz * ry * rx * vPosition;
}
You have to actually set vColor for it to have a valid value. Do the same thing that you did to set vPosition:
GLuint vColor= glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor);
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(colors)) );
You don't actually pass any colour information to your shader.
I have some transparent decals rendered into a separate framebuffer. Now I'm trying to blend this buffer with the back buffer (active target).
I'm assuming that I have to load the color buffer of the fbo as a texture in a fragment shader and output the texture color to the active target. How can I tell the graphics card to do this operation for every pixel?
Draw a quad or two triangles that cover the whole screen.
my code for the fullscreen rectangle/quad
this is old method - from OpenGL 1.1, but works :) For new OpenGL 3.* you have to use VBO/Arrays
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f( 0,0 );
glVertex3d( -1.0,-1.0, 0 );
glTexCoord2f( 1,0 );
glVertex3d( 1.0,-1.0, 0 );
glTexCoord2f( 1,1 );
glVertex3d( 1.0, 1.0, 0 );
glTexCoord2f( 0,1 );
glVertex3d( -1.0, 1.0, 0 );
glEnd();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
of course you have to setup textures before