I try create example of rotating pyramid with four sides: every side is a simple triangle and has own color and here the schema of my pyramid is
Triangle points #1
-0.8 0 0
0.8 0 0
0 0 0.8
Triangle points #2
-0.8 0 0
0.8 0 0
0 0.8 0.5
Triangle points #3
-0.8 0 0
0 0 0.8
0 0.8 0.5
Triangle points #4
0.8 0 0
0 0 0.8
0 0.8 0.5
Triangle colors #1
0.5 0.5 0.5
0.5 0.5 0.5
0.5 0.5 0.5
Triangle colors #2
1 0 0
1 0 0
1 0 0
Triangle colors #3
0 1 0
0 1 0
0 1 0
Triangle colors #4
0 0 1
0 0 1
0 0 1
Code of rotating pyramid:
// Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() );
return -1;
}
SDL_Window *window = SDL_CreateWindow(
"SDL2/OpenGL Demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1028, 768,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
// Check that the window was successfully created
if (window == NULL) {
// In the case that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return -1;
}
SDL_GLContext context = SDL_GL_CreateContext(window);
initGLEWandShowOpenGLVersion();
GLShader vertShader("./shaders/basic.vert", GL_VERTEX_SHADER);
GLShader fragShader("./shaders/basic.frag", GL_FRAGMENT_SHADER);
vertShader.compile();
fragShader.compile();
GLuint program = glCreateProgram();
if( 0 == program ) {
fprintf(stderr, "Error creating program object.\n");
exit(1);
}
glAttachShader( program, vertShader.shader );
glAttachShader( program, fragShader.shader );
// Bind index 0 to the shader input variable "VertexPosition"
glBindAttribLocation(program, 0, "VertexPosition");
// Bind index 1 to the shader input variable "VertexColor"
glBindAttribLocation(program, 1, "VertexColor");
glLinkProgram( program );
glUseProgram( program );
auto [positionData, colorData, indicesData, n] = Triangle::join(
std::initializer_list<Triangle>({
Triangle(new float[9] {-0.8f, 0.0f, 0.0f, // 0
0.8f, 0.0f, 0.0f, // 1
0.0f, 0.0f, 0.8f}, // 2
new float[9] {0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f}),
Triangle(new float[9] {-0.8f, 0.0f, 0.0f, // 0
0.8f, 0.0f, 0.0f, // 1
0.0f, 0.8f, 0.5f}, // 3
new float[9] {1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f}),
Triangle(new float[9] {-0.8f, 0.0f, 0.0f, // 0
0.0f, 0.0f, 0.8f, // 2
0.0f, 0.8f, 0.5f}, // 3
new float[9] {0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f}),
Triangle(new float[9] {0.8f, 0.0f, 0.0f, // 1
0.0f, 0.0f, 0.8f, // 2
0.0f, 0.8f, 0.5f}, // 3
new float[9] {0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f})
})
);
for(int k=0; k<n; ++k) {
std::cout << "Triangle points #" << k+1 << "\n";
for(int i=0; i<3; ++i) {
for(int j=0; j<3; ++j) {
std::cout << "\t" << positionData[k*9+3*i+j] << " ";
}
std::cout << "\n";
}
std::cout << "\n";
}
for(int k=0; k<n; ++k) {
std::cout << "Triangle colors #" << k+1 << "\n";
for(int i=0; i<3; ++i) {
for(int j=0; j<3; ++j) {
std::cout << "\t" << colorData[k*9+3*i+j] << " ";
}
std::cout << "\n";
}
std::cout << "\n";
}
// Create the buffer objects
GLuint vboHandles[3];
glGenBuffers(3, vboHandles);
GLuint positionBufferHandle = vboHandles[0];
GLuint colorBufferHandle = vboHandles[1];
GLuint indexBufferHandle = vboHandles[2];
// Populate the position buffer
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glBufferData(GL_ARRAY_BUFFER, n * 9* sizeof(float), positionData, GL_STATIC_DRAW);
// Populate the color buffer
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glBufferData(GL_ARRAY_BUFFER, n * 9* sizeof(float), colorData, GL_STATIC_DRAW);
// Populate the indices buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferHandle);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, n * 9* sizeof(float), indicesData, GL_STATIC_DRAW);
// Create and set-up the vertex array object
GLuint vaoHandle;
glGenVertexArrays( 1, &vaoHandle );
glBindVertexArray(vaoHandle);
// Enable the vertex attribute arrays
glEnableVertexAttribArray(0); // Vertex position
glEnableVertexAttribArray(1); // Vertex color
// Map index 0 to the position buffer
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
// Map index 1 to the color buffer
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
float angle = 0;
float time = 8.0f;
float N = 300;
long pause = (long)(time/N/1e-6);
float speed = 360/N;
size_t i = 0;
while(1) {
mat4 matRotate = glm::rotate(mat4(1.0f), glm::radians(angle) , vec3(0.2f, 1.0f, 0.2f));
angle = angle + speed;
GLint location = glGetUniformLocation(program, "RotationMatrix");
if( location >= 0 )
{
glUniformMatrix4fv(location, 1, GL_FALSE, &matRotate[0][0]);
}
i = (i + 1) % ((size_t) N);
std::cout << "i = " << i << "\n";
glBindVertexArray( vaoHandle );
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays( GL_TRIANGLES, 0, n*9 );
// glDrawElements(GL_TRIANGLES, n*9, GL_UNSIGNED_INT, indicesData);
SDL_GL_SwapWindow( window );
std::this_thread::sleep_for(std::chrono::microseconds(pause));
}
return 0;
}
My shaders are here, vertex shader:
#version 130
in vec3 VertexPosition;
in vec3 VertexColor;
out vec3 Color;
uniform mat4 RotationMatrix;
void main()
{
Color = VertexColor;
gl_Position = RotationMatrix * vec4(VertexPosition,1.0);
//gl_Position = vec4(VertexPosition, 1.0);
}
and fragment shader:
#version 130
in vec3 Color;
out vec4 FragColor;
void main() {
FragColor = vec4(Color, 1.0);
}
But rotation works strangely: I don’t see every side during movement… What I do wrong?