I want to show a green cube, in a directory there are .cpp, .h, and .glsl files:
- main.cpp
- Utils.h
- vertShader.glsl
- fragShader.glsl
I want to compile it using CMakeLists.txt:
cmake_minimum_required(VERSION 3.17)
project(test LANGUAGES CXX)
add_executable(test main.cpp)
target_link_libraries(test GLEW GL glfw )
target_include_directories(test PUBLIC /root/SourceCodes/CPP/include/)
(I put the Utils.h in the /root/SourceCodes/CPP/include/ as well)
But, the problem is I get error:
Undefined Reference Utils::createShaderProgram
the codes / MWE for the files above:
main.cpp
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <string>
#include <iostream>
#include <fstream>
#include <cmath>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "Utils.h"
using namespace std;
#define numVAOs 1
#define numVBOs 2
float cameraX, cameraY, cameraZ;
float cubeLocX, cubeLocY, cubeLocZ;
GLuint renderingProgram;
GLuint vao[numVAOs];
GLuint vbo[numVBOs];
GLuint mvLoc, projLoc;
int width, height;
float aspect;
glm::mat4 pMat, vMat, mMat, mvMat;
void setupVertices(void) { // 36 vertices, 12 triangles, makes 2x2x2 cube placed at origin
float vertexPositions[108] = {
-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f,
};
glGenVertexArrays(1,vao);
glBindVertexArray(vao[0]);
glGenBuffers(numVBOs, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
}
void init(GLFWwindow* window){
// Utils
renderingProgram = Utils::createShaderProgram(
"vertShader.glsl",
"fragShader.glsl");
cubeLocX = 0.0f; cubeLocY = -2.0f; cubeLocZ = 0.0f;
setupVertices();
}
void display(GLFWwindow* window, double currentTime) {
glClear(GL_DEPTH_BUFFER_BIT);
glUseProgram(renderingProgram);
// get the uniform variables for the MV and projection matrices
mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");
projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");
// build perspective matrix
glfwGetFramebufferSize(window, &width, &height);
aspect = (float)width / (float)height;
pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f); // 1.0472 radians = 60 degrees
// build view matrix, model matrix, and model-view matrix
vMat = glm::translate(glm::mat4(1.0f), glm::vec3(-cameraX, -cameraY, -cameraZ));
mMat = glm::translate(glm::mat4(1.0f), glm::vec3(cubeLocX, cubeLocY, -cubeLocZ));
mvMat = vMat * mMat;
// copy perspective and MV matrices to corresponding uniform variables
glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));
// associate VBO with the corresponding vertex attribute in the vertex shader
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
// adjust OpenGL settings and draw model
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDrawArrays(GL_TRIANGLES,0,36);
}
int main(void)
{
glfwInit(); //initialize GLFW and GLEW libraries
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(600, 600, " Learn Open GL with GLFW: Green Cube", NULL, NULL);
glfwMakeContextCurrent(window);
if(glewInit() != GLEW_OK) {
exit(EXIT_FAILURE);
}
glfwSwapInterval(1);
init(window);
while(!glfwWindowShouldClose(window)) {
display(window, glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
//return 0;
}
Utils.h
#include <GL/glew.h>
#include <GLFW/glfw3.h>
//#include <SOIL2/SOIL2.h>
#include <string>
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
class Utils
{
private:
static std::string readShaderFile(const char *filePath);
static void printShaderLog(GLuint shader);
static void printProgramLog(int prog);
static GLuint prepareShader(int shaderTYPE, const char *shaderPath);
static int finalizeShaderProgram(GLuint sprogram);
public:
Utils();
static bool checkOpenGLError();
static GLuint createShaderProgram(const char *vp, const char *fp);
static GLuint createShaderProgram(const char *vp, const char *gp, const char *fp);
static GLuint createShaderProgram(const char *vp, const char *tCS, const char* tES, const char *fp);
static GLuint createShaderProgram(const char *vp, const char *tCS, const char* tES, char *gp, const char *fp);
static GLuint loadTexture(const char *texImagePath);
static GLuint loadCubeMap(const char *mapDir);
static float* goldAmbient();
static float* goldDiffuse();
static float* goldSpecular();
static float goldShininess();
static float* silverAmbient();
static float* silverDiffuse();
static float* silverSpecular();
static float silverShininess();
static float* bronzeAmbient();
static float* bronzeDiffuse();
static float* bronzeSpecular();
static float bronzeShininess();
};
fragShader.glsl
#version 330
out vec4 color;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
void main(void) {
color = vec4(0.0, 1.0, 0.0, 1.0);
}
vertShader.glsl
#version 330
layout (location=0) in vec3 position;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
void main(void) {
gl_position = proj_matrix * mv_matrix * vec4(position, 1.0);
}