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);
};
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);
I am stuck trying to get this code to work in Visual Studio 2012 using glut. It renders a 10/10 3D grid but it will not respond to my input from the keyboard. I am trying to get the camera to rotate around the origin when i hit the left arrow key.
// This example shows how to create a camera for 3D graphics.
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int g_winWidth = 1024;
int g_winHeight = 512;
bool keyStatus[256];
float angle = 0.0f; //angle for rotating camera
float beginning_angle = 0.0f;
float cx = 10.0, cy = 10.0, cz = -10.0;
void initialGL()
{
glEnable(GL_DEPTH_TEST);
glClearColor (1.0f, 1.0f, 1.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
//initialize the keyboard keys
void initialization()
{
for(int i =0; i<256; i++)
keyStatus[i] = false;
}
//function to draw the colored x,y, and z axis
void drawCS()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(10.0f, 10.0f, 10.0f);
glLineWidth(2.5f);
glBegin(GL_LINES);
//axis x
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.3f, 0.0f, 0.0f);
//text x
glVertex3f(0.4f, 0.05f, 0.0f);
glVertex3f(0.5f, -0.05f, 0.0f);
glVertex3f(0.4f, -0.05f, 0.0f);
glVertex3f(0.5f, 0.05f, 0.0f);
//axis y
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.3f, 0.0f);
//text y
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(0.0f, 0.4f, 0.0f);
glVertex3f(-0.05f, 0.55f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(0.05f, 0.55f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
//axis z
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.3f);
//text z
glVertex3f(-0.025f, 0.025f, 0.4f);
glVertex3f(0.025f, 0.025f, 0.4f);
glVertex3f(0.025f, 0.025f, 0.4f);
glVertex3f(-0.025f, -0.025f, 0.4f);
glVertex3f(-0.025f, -0.025f, 0.4f);
glVertex3f(0.025f, -0.025f, 0.4f);
glEnd();
glLineWidth(1.0f);
glPopMatrix();
}
//function to draw the grid
void drawGrid()
{
int size = 10; // determining the grid size and the numbers of cells
if(size%2 != 0) ++size;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//glScalef(30.0f, 30.0f, 30.0f);
glBegin(GL_LINES);
for (int i =0; i<size+1; i++) {
if((float)i == size/2.0f) {
glColor3f(0.0f, 0.0f, 0.0f);
} else {
glColor3f(0.8f, 0.8f, 0.8f);
}
glVertex3f(-size/2.0f, 0.0f, -size/2.0f+i);
glVertex3f(size/2.0f, 0.0f, -size/2.0f+i);
glVertex3f(-size/2.0f+i, 0.0f, -size/2.0f);
glVertex3f(-size/2.0f+i, 0.0f, size/2.0f);
}
glEnd();
glPopMatrix();
}
//function to display everything that is happening in window
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawGrid();// call to function to draw the grid
drawCS();//call to function to draw the x,y,z axis
glutSwapBuffers();
}
void reshape(int w, int h)
{
g_winWidth = w;
g_winHeight = h;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//this function sets the initial position of the camera in 3D space
/*
Need to find a way to rotate around the origin from left to right
*/
gluLookAt( cx, cy, cz, //camera position
0.0f, 0.0f, 0.0f, //what camera looks at
0.0f, 1.0f, 0.0f); //
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, g_winWidth/g_winHeight, 0.1, 100);//specifies the view for the scene
glViewport(0, 0, w, h);
//angle += 0.1f;
}
//keyboard function for the exit key
void keyboard(unsigned char key, int x, int y)
{
keyStatus[key] = true;
switch (key) {
case 27:
exit(0);
break;
default:
break;
}
}
//sets the keyboard callback to the current window
void keyboardUp(unsigned char key, int x, int y)
{
keyStatus[key] = false;
}
//function for arrow keys output
void processSpecialKeys(int key, int xx, int yy) {
switch(key) {
case GLUT_KEY_LEFT :
//What the left arrow key does
angle -= 0.01f;
cx = sin(angle);
cz = -cos(angle);
break;
case GLUT_KEY_RIGHT :
//What the right arrow key does
break;
case GLUT_KEY_UP :
//What the up arrow key does
break;
case GLUT_KEY_DOWN :
//What the down arrow key does
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(g_winWidth, g_winHeight);
glutInitWindowPosition(0, 0);
glutCreateWindow("Camera");
initialGL();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardUp);
glutSpecialFunc(processSpecialKeys);
glEnable(GL_DEPTH_TEST);
initialization();
glutMainLoop();
return 1;//changed from EXIT_SUCCESS
}