Coord texture array does not works on a cube - arrays

the purpose of my program is to load and display a simple cube with the same texture on each face. the problem is the 2 first faces (front, rear) are good. I tried several combinations of vertices in the textures array but it doesn't work. I don't know if I need to add more vertices in the textures array or change the order or change the indices array.
#define OFFSET_BUFFER(bytes) ((GLfloat *)NULL + bytes)
float vertices[] =
{
-1.0f, -1.0f, 1.0f, // 0
1.0f, -1.0f, 1.0f, // 1
-1.0f, 1.0f, 1.0f, // 2
1.0f, 1.0f, 1.0f, // 3
-1.0f, -1.0f, -1.0f,// 4
1.0f, -1.0f, -1.0f, // 5
-1.0f, 1.0f, -1.0f, // 6
1.0f, 1.0f, -1.0f, // 7
};
GLubyte indices[] =
{
0,1,2, 1,3,2, //front face
6,7,5, 6,5,4, //rear face
1,5,3, 5,7,3, //problem on the right face
//2,3,6, 3,6,7,
//2,4,0, 2,4,6
0,5,1, 5,4,0
};
float textures[] =
{
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
};
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Texture Mapping",NULL);
SDL_SetVideoMode(500, 500, 32, SDL_OPENGL);
bool continuer = true;
SDL_Event event;
GLuint texCube;
glClearDepth(1.0f);
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0f, (float)500.0f / (float)500.0f, 1.0f, 3000.0f);
glewInit();
texCube = loadTexture("caisse.jpg");
glBindTexture(GL_TEXTURE_2D, texCube);
glEnable(GL_TEXTURE_2D);
while (continuer)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = false;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
//Draw Cube ---------------------------------------
glPushMatrix();
glRotatef(90.0f, 1.0f, 1.0f, 0.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, textures);
glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_BYTE, indices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//-------------------------------------------------
glPopMatrix();
glFlush();
SDL_GL_SwapBuffers();
}
glDisable(GL_TEXTURE_2D);
SDL_Quit();
return 0;
}

Your corners are sharing texture coordinates, which just isn't going to work.
you should have 4 vertices for each face, as the texture coordinates for each corner will be different depending on the face.

The solution of my problem is the following code :
#define OFFSET_BUFFER(bytes) ((GLfloat *)NULL + bytes)
float angle = 0.0f;
float vertices[72] =
{
-1.0f, -1.0f, 1.0f,//VO - 0
1.0f, -1.0f, 1.0f,//V1 - 1
-1.0f, 1.0f, 1.0f,//V2 - 2
1.0f, 1.0f, 1.0f,//V3 - 3
-1.0f, -1.0f, -1.0f,//V4 - 4
1.0f, -1.0f, -1.0f,//V5 - 5
-1.0f, 1.0f, -1.0f,//V6 - 6
1.0f, 1.0f, -1.0f,//V7 - 7
-1.0f, 1.0f, 1.0f,//V2 - 8
1.0f, 1.0f, 1.0f,//V3 - 9
-1.0f, 1.0f, -1.0f,//V6 - 10
1.0f, 1.0f, -1.0f,//V7 - 11
-1.0f, -1.0f, 1.0f,//VO - 12
1.0f, -1.0f, 1.0f,//V1 - 13
-1.0f, -1.0f, -1.0f,//V4 - 14
1.0f, -1.0f, -1.0f,//V5 - 15
-1.0f, -1.0f, 1.0f,//VO - 16
-1.0f, 1.0f, 1.0f,//V2 - 17
-1.0f, -1.0f, -1.0f,//V4 - 18
-1.0f, 1.0f, -1.0f,//V6 - 19
1.0f, -1.0f, 1.0f,//V1 - 20
1.0f, 1.0f, 1.0f,//V3 - 21
1.0f, -1.0f, -1.0f,//V5 - 22
1.0f, 1.0f, -1.0f,//V7 - 23
};
GLubyte indices[36] =
{
0,1,2, 1,3,2,
6,7,5, 6,5,4,
8,9,10, 9,10,11,
12,13,14, 13,14,15,
17,16,18, 17,18,19,
20,21,22, 21,22,23
};
float textures[48] =
{
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
};
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Texture Mapping",NULL);
SDL_SetVideoMode(500, 500, 32, SDL_OPENGL);
bool continuer = true;
SDL_Event event;
GLuint texCube;
glClearDepth(1.0f);
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0f, (float)500.0f / (float)500.0f, 1.0f, 3000.0f);
glewInit();
texCube = loadTexture("caisse.jpg");
glBindTexture(GL_TEXTURE_2D, texCube);
glEnable(GL_TEXTURE_2D);
while (continuer)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = false;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
//Draw Cube ---------------------------------------
glPushMatrix();
glRotatef(angle, 1.0f, 1.0f, 0.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, textures);
glDrawElements(GL_TRIANGLES, 48, GL_UNSIGNED_BYTE, indices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//-------------------------------------------------
angle += 1.0f;
glPopMatrix();
glFlush();
SDL_GL_SwapBuffers();
}
glDisable(GL_TEXTURE_2D);
SDL_Quit();
return 0;
}

And the solution with VBO :
#define OFFSET_BUFFER(bytes) ((GLfloat *)NULL + bytes)
float angle = 0.0f;
float vertices[72] =
{
-1.0f, -1.0f, 1.0f,//VO - 0
1.0f, -1.0f, 1.0f,//V1 - 1
-1.0f, 1.0f, 1.0f,//V2 - 2
1.0f, 1.0f, 1.0f,//V3 - 3
-1.0f, -1.0f, -1.0f,//V4 - 4
1.0f, -1.0f, -1.0f,//V5 - 5
-1.0f, 1.0f, -1.0f,//V6 - 6
1.0f, 1.0f, -1.0f,//V7 - 7
-1.0f, 1.0f, 1.0f,//V2 - 8
1.0f, 1.0f, 1.0f,//V3 - 9
-1.0f, 1.0f, -1.0f,//V6 - 10
1.0f, 1.0f, -1.0f,//V7 - 11
-1.0f, -1.0f, 1.0f,//VO - 12
1.0f, -1.0f, 1.0f,//V1 - 13
-1.0f, -1.0f, -1.0f,//V4 - 14
1.0f, -1.0f, -1.0f,//V5 - 15
-1.0f, -1.0f, 1.0f,//VO - 16
-1.0f, 1.0f, 1.0f,//V2 - 17
-1.0f, -1.0f, -1.0f,//V4 - 18
-1.0f, 1.0f, -1.0f,//V6 - 19
1.0f, -1.0f, 1.0f,//V1 - 20
1.0f, 1.0f, 1.0f,//V3 - 21
1.0f, -1.0f, -1.0f,//V5 - 22
1.0f, 1.0f, -1.0f,//V7 - 23
};
GLubyte indices[36] =
{
0,1,2, 1,3,2,
6,7,5, 6,5,4,
8,9,10, 9,10,11,
12,13,14, 13,14,15,
17,16,18, 17,18,19,
20,21,22, 21,22,23
};
float textures[48] =
{
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
};
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Texture Mapping",NULL);
SDL_SetVideoMode(500, 500, 32, SDL_OPENGL);
bool continuer = true;
SDL_Event event;
GLuint texCube;
GLuint VBO[3];
glClearDepth(1.0f);
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0f, (float)500.0f / (float)500.0f, 1.0f, 3000.0f);
glewInit();
texCube = loadTexture("caisse.jpg");
glGenBuffers(2, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(textures), textures, GL_STATIC_DRAW);
glEnable(GL_TEXTURE_2D);
while (continuer)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = false;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
//Draw Cube ---------------------------------------
glPushMatrix();
glRotatef(angle, 1.0f, 1.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, texCube);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glVertexPointer(3, GL_FLOAT, 0, OFFSET_BUFFER(0));
glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glTexCoordPointer(2, GL_FLOAT, 0, OFFSET_BUFFER(0));
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawElements(GL_TRIANGLES, 48, GL_UNSIGNED_BYTE, OFFSET_BUFFER(0));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//-------------------------------------------------
angle += 1.0f;
glPopMatrix();
glFlush();
SDL_GL_SwapBuffers();
}
glDisable(GL_TEXTURE_2D);
SDL_Quit();
return 0;
}

If you really want to save a few bytes, you can still factorize a few vertices (16 vertices instead of 24). You consider your cube without two opposite faces and add these two faces separately. Here is an IQM model which does just that:
# Inter-Quake Export
mesh "Cube"
material "cube.tga"
vp 1 1 -1
vn 1 1 -1
vt 0 0
vp 1 -1 -1
vn 1 -1 -1
vt 0 1
vp -1 -1 -1
vn -1 -1 -1
vt 1 1
vp -1 1 -1
vn -1 1 -1
vt 1 0
vp 1 1 1
vn 1 1 1
vt 1 0
vp -1 1 1
vn -1 1 1
vt 0 0
vp -1 -1 1
vn -1 -1 1
vt 0 1
vp 1 -1 1
vn 1 -1 1
vt 1 1
vp 1 1 -1
vn 1 1 -1
vt 0 0
vp -1 1 -1
vn -1 1 -1
vt 1 0
vp -1 1 1
vn -1 1 1
vt 1 1
vp 1 1 1
vn 1 1 1
vt 0 1
vp 1 1 -1
vn 1 1 -1
vt 0 0
vp -1 1 -1
vn -1 1 -1
vt 1 0
vp -1 1 1
vn -1 1 1
vt 1 1
vp 1 1 1
vn 1 1 1
vt 0 1
fm 0 1 2
fm 0 2 3
fm 0 4 7
fm 0 7 1
fm 4 6 7
fm 4 5 6
fm 5 2 6
fm 5 3 2
fm 8 9 10
fm 8 10 11
fm 12 15 14
fm 12 14 13

Related

Can't Get Spinning Cube To Render In OpenGL

I'm trying to get a spinning 3D cube but I can't get it to render. There's no error, but it's just a black screen. Also, there's no checking whether the Fragment shader is working but I can assure you it is I just don't have it included here.
Here's what my code looks like:
#include <glad/glad.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <cglm/cglm.h>
#include <cglm/mat4.h>
#include <cglm/vec3.h>
#include <stdio.h>
#include <stdlib.h>
float vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f};
GLuint elements[] = {
0, 1, 2,
2, 3, 0};
static const char *vertex_shader_text =
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec2 aTexCoord;\n"
"out vec2 TexCoord;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
" gl_Position = projection * view * model * vec4(aPos, 1.0f);\n"
" TexCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
"}";
static const char *fragment_shader_text =
"#version 330 core\n"
"varying vec3 color;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(color, 1.0);\n"
"}\n";
static void error_callback(int error, const char *description) {
fprintf(stderr, "Error: %s\n", description);
}
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
int main(void) {
GLFWwindow *window;
GLuint vbo, vertex_shader, fragment_shader, program;
GLint mvp_location, vpos_location, vcol_location;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
if (!window) {
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSetKeyCallback(window, key_callback);
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
fprintf(stderr, "Could Not Load GLFW\n");
exit(1);
}
glfwSwapInterval(1);
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
glCompileShader(vertex_shader);
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
glCompileShader(fragment_shader);
GLint status;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status);
if(!status){
char buffer[512];
glGetShaderInfoLog(vertex_shader, 512, NULL, buffer);
puts(buffer);
}
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
while (!glfwWindowShouldClose(window)) {
float ratio;
int width, height;
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float)height;
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mat4 model = {{1.f, 1.f, 1.f, 1.f}, {1.f, 1.f, 1.f, 1.f}, {1.f, 1.f, 1.f, 1.f}, {1.f, 1.f, 1.f, 1.f}};
mat4 view = {{1.f, 1.f, 1.f, 1.f}, {1.f, 1.f, 1.f, 1.f}, {1.f, 1.f, 1.f, 1.f}, {1.f, 1.f, 1.f, 1.f}};
mat4 projection = {{1.f, 1.f, 1.f, 1.f}, {1.f, 1.f, 1.f, 1.f}, {1.f, 1.f, 1.f, 1.f}, {1.f, 1.f, 1.f, 1.f}};
vec3 axis = {0.5f, 1.0f, 0.0f};
vec3 dist = {0.0f, 0.0f, -3.0f};
glm_rotate(model, glfwGetTime(), axis);
glm_translate(view, dist);
glm_perspective(0.79, width / height, 0.1f, 100.0f, projection);
unsigned int modelLoc = glGetUniformLocation(program, "model");
unsigned int viewLoc = glGetUniformLocation(program, "view");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, (const GLfloat *)model);
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, (const GLfloat *)view);
unsigned int projectionLoc = glGetUniformLocation(program, "projection");
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
You have to initialize the matrices with the Identity matrix:
mat4 model = {
{1.f, 0.f, 0.f, 0.f},
{0.f, 1.f, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0.f, 0.f, 1.f}};
Also do so for view and projection.
The data types for the arguments of glm_rotate and glm_perspective must be float:
glm_rotate(model, (float)glfwGetTime(), axis);
glm_translate(view, dist);
glm_perspective((float)0.79, (float)width / (float)height, 0.1f, 100.0f, projection);
You also forgot to create the Index buffer:
glBindVertexArray(VAO);
// [...]
unsigned int IBO;
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
to install the program:
glUseProgram(program);
to set the projection matrix uniform.
unsigned int projectionLoc = glGetUniformLocation(program, "projection");
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, (const GLfloat *)projection);
Finally you must change the fragment shader. For example:
#version 330 core
in vec2 TexCoord;
void main()
{
gl_FragColor = vec4(TexCoord.xy, 0.5, 1.0);
};

Vulkan - Debugging A Camera Matrix Problem

The problem I'm having is that I'm exporting a scene from Blender and my scene is rotated 90 about the Y axis. It's clearly a matrix issue and I'm having problems visualizing the solution. Blender is configured to export with 'up' = (0, 1, 0) and 'forward' = (0, 0, 1).
I'm using row major matrices as indicated by the following.
mat4x4 cons_mat4x4_perspective(float fovy, float aspect_ratio, float near, float far)
{
mat4x4 result = cons_mat4x4_zero();
float half_tan_fovy = tan(fovy / 2.0f); /* in radians */
result.as_rows[0] = cons_vec4(1.0f / (aspect_ratio * half_tan_fovy), 0.0f, 0.0f, 0.0f);
result.as_rows[1] = cons_vec4(0.0f, 1.0f / half_tan_fovy, 0.0f, 0.0f);
result.as_rows[2] = cons_vec4(0.0f, 0.0f, -(far + near) / (far - near), -1.0f);
result.as_rows[3] = cons_vec4(0.0f, 0.0f, -(2.0f * far * near) / (far - near), 0.0f);
return result;
}
// Vulkan clip matrix
clip = cons_mat4x4_floats(1.0f, 0.0f, 0.0f, 0.0f,
0.0f,-1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.5f, 1.0f);
mat4x4 cons_mat4x4_lookat(vec3 eye, vec3 center, vec3 up)
{
mat4x4 result = cons_mat4x4_identity();
vec3 f = normalize(vec3_sub(center, eye));
vec3 s = normalize(cross(f, up));
vec3 u = cross(s, f);
result.as_rows[0] = cons_vec4(s.x, u.x, -f.x, 0.0f);
result.as_rows[1] = cons_vec4(s.y, u.y, -f.y, 0.0f);
result.as_rows[2] = cons_vec4(s.z, u.z, -f.z, 0.0f);
result.as_rows[3] = cons_vec4(-vec3_dot(s, eye),
vec3_dot(u, eye),
vec3_dot(f, eye),
1.0f);
return result;
}
My model matrix is the identity matrix and I'm creating a lookat matrix with the following parameters:
vec3 _camera = cons_vec3(0.0f, 5.0f, 0.0f);
vec3 _at = cons_vec3(0.0f, 0.0f, 0.0f);
cons_mat4x4_lookat(_camera, _at, cons_vec3(0.0f, 1.0f, 0.0f));

How to properly initialize a model matrix in C?

I tried to convert the code of the question I asked over here.
But when I try to run it, I run into an exception and it points to the mat4(which is an 2-d array of 4x4 floats) header of this(CGLM, which is use for OpenGL math in C as GLM is C++ only library) library.
The C++ code works fine and runs perfectly but why does it crash in C.
Here is the C snippet of the code where 'CGLM' is used(this is the code that crashes):-
glUseProgram(shaderProgram);
mat4 model =
{
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
};
mat4 projection;
glm_ortho(0.0f, (GLfloat)(WIDTH), (GLfloat)(HEIGHT), 0.0f, -1.0f, 1.0f, projection);
vect2 scale = { 2.0f, 2.0f };
vect2 position = { 50.0f, 0.0f };
vec4 color = { 1.0f, 1.0f, 1.0f, 0.5f };
GLfloat rotation = 0.0f;
glm_translate(model, (vec3){ position[0], position[1], 0.0f });
glm_translate(model, (vec3){ 0.5f * scale[0], 0.5f * scale[1], 0.0f });
glm_rotate(model, rotation, (vec3){ 0.0f, 0.0f, 1.0f }); // Why is this function crashing?
glm_translate(model, (vec3){ -0.5f * scale[0], -0.5f * scale[1], 0.0f });
glm_scale(model, (vec3){ scale[0] * width, scale[1] * height, 1.0f });
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, (GLfloat *)projection);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, (GLfloat *)model);
glUniform4f(glGetUniformLocation(shaderProgram, "spriteColor"), color[0], color[1], color[2], color[3]);
Here is the C++ snippet of the code where GLM is used:-
glUseProgram(shaderProgram);
glm::mat4 model(1.0f);
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(WIDTH), static_cast<GLfloat>(HEIGHT), 0.0f, -1.0f, 1.0f);
glm::vec2 scale = glm::vec2(2.0f, 2.0f);
glm::vec2 position = glm::vec2(50.0f, 0.0f);
glm::vec4 color = glm::vec4(1.0f, 1.0f, 1.0f, 0.5f);
GLfloat rotation = 0.0f;
model = glm::translate(model, glm::vec3(position, 0.0f));
model = glm::translate(model, glm::vec3(0.5f * scale.x, 0.5f * scale.y, 0.0f));
model = glm::rotate(model, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
model = glm::translate(model, glm::vec3(-0.5f * scale.x, -0.5f * scale.y, 0.0f));
model = glm::scale(model, glm::vec3(scale * glm::vec2(width, height), 1.0f));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniform4f(glGetUniformLocation(shaderProgram, "spriteColor"), color.x, color.y, color.z, color.w);
See CGLM documentation
According to the getting started
Aligment is Required: vec4 and mat4 requires 16 byte aligment because
vec4 and mat4 operations are vectorized by SIMD instructions
(SSE/AVX).
So you need to initialize identity matrix like:
mat4 model;
glm_mat4_identity(model);
....
mat4 projection;
glm_mat4_identity(projection);
glm_ortho(0.0f, (GLfloat)(WIDTH), (GLfloat)(HEIGHT), 0.0f, -1.0f, 1.0f, projection);

How to pass a GLfloat array through function in C++?

I'm trying to pass a GLfloat type array through a function but the new variable only take the 1st value of the array (0.5f in this case), what am i doing wrong?
My Code:
void main()
{
// some code
GLfloat vertices[] = {
// Positions // Colors // Texture Coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // Top Left
};
passingArray(vertices);
}
void passingArray(GLfloat anotherVertices[])
{
// this anotherVertices only take 1st value of the vertices array
}

I can't render a cube in OpenGL, in Windows, using MinGW

I tried rendering a cube using OpenGL, in Windows. But the display window is black. I enabled the Z-Buffer, I clear the depth bit in the glClear function, etc. But no luck. And the problem is that every example or documentation I follow, is incomplete, or omit some information, and I'm very, very confused right now. I don't know what am I doing right and what am I doing wrong.
All I want is to display a cube, to know that the renderer is ready for 3D graphics (I can display 2D graphics with no problems). Nothing else.
This is the code of my main program:
#include "demo.h"
#include "renderfunc.c"
HDC hDC;
HGLRC hRC;
void enableGL(HWND hWnd)
{
hDC = GetDC(hWnd);
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,0,
0,0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0 };
if(!hDC)
{
MessageBox(hWnd,L"Can't Create A GL Device Context.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
if(!nPixelFormat)
{
MessageBox(hWnd,L"Can't find a proper Pixel Format.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
SetPixelFormat(hDC, nPixelFormat, &pfd);
/* Those lines has to be here*/
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* UNCOMMENT THIS SECTION FOR 3D */
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_EQUAL); //In some examples this is GL_LESS
glDepthMask(GL_TRUE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Accurate perspective calculations
return;
}
GLvoid ChangeSize(GLsizei width, GLsizei height)
{
if(height==0)
height=1;
glViewport(0,0,width,height);
//glLoadIdentity();
/* THIS SECTION IS FOR 3D GRAPHICS */
/* Comment glLoadIdentity above, and uncomment this section */
/* If you enable Z-buffer */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
enableGL(hWnd);
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
case WM_DESTROY:
ReleaseDC(hWnd,hDC);
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
case WM_PAINT:
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* GL ANIMATION GOES HERE */
//Change this for whatever you want to render
renderCubeTest();
/* -------------------- */
SwapBuffers(hDC);
ValidateRect(hWnd, NULL);
return 0;
case WM_SIZE:
ChangeSize(LOWORD(lParam), HIWORD(lParam));
return 0;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
MSG msg;
//String with the name of the class of our window
LPCTSTR classname = L"OpenGL";
//String with the title of our window
LPCTSTR windowtitle = L"Cubes Demo By Ninjihaku Software";
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
//wc.hIcon = (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);
wc.hIcon = NULL;
wc.hCursor = (HCURSOR) LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = classname;
if(RegisterClass(&wc) == 0)
return false;
//hWnd = CreateWindow(classname, windowtitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 100, 100, 640, 480, NULL, NULL, hInstance, NULL);
hWnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, classname, windowtitle, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 640, 480, NULL, NULL, hInstance, NULL);
if(hWnd == NULL)
return FALSE;
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(hWnd);
return (int) msg.wParam;
}
Then the renderCubeTest() function included in renderfunc.c:
void renderCubeTest()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube
glFlush();
glPopMatrix();
return;
}
I hope someone can help me and tell me what's wrong with this.
glDepthFunc(GL_EQUAL);
I suspect this is the problem - what it basically does is tell OpenGL that pixels should only be rendered to the screen if the new pixel's depth value is equal to the current pixel's depth value. This is most certainly not what you want.
Instead, you should use either GL_LEQUAL (note the "L" before "EQUAL") or GL_LESS, as these are the normal comparison functions.

Resources