Skip to content

Instantly share code, notes, and snippets.

@amoshyc
Last active November 25, 2018 10:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amoshyc/5b9b465163323c3c240aab13f8867c03 to your computer and use it in GitHub Desktop.
Save amoshyc/5b9b465163323c3c240aab13f8867c03 to your computer and use it in GitHub Desktop.
#version 410
layout(location = 0) out vec4 fragColor;
uniform mat4 um4mv;
uniform mat4 um4p;
in VertexData
{
vec3 N; // eye space normal
vec3 L; // eye space light vector
vec3 H; // eye space halfway vector
vec2 texcoord;
} vertexData;
uniform sampler2D tex;
void main()
{
vec3 texColor = texture(tex,vertexData.texcoord).rgb;
fragColor = vec4(texColor, 1.0);
}
#include "../Externals/Include/Include.h"
#define MENU_TIMER_START 1
#define MENU_TIMER_STOP 2
#define MENU_EXIT 3
GLubyte timer_cnt = 0;
bool timer_enabled = true;
unsigned int timer_speed = 16;
using namespace glm;
using namespace std;
mat4 view;
mat4 projection;
mat4 model;
GLint um4p;
GLint um4mv;
GLint um4tex;
GLuint program;
char** loadShaderSource(const char* file)
{
FILE* fp = fopen(file, "rb");
fseek(fp, 0, SEEK_END);
long sz = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *src = new char[sz + 1];
fread(src, sizeof(char), sz, fp);
src[sz] = '\0';
char **srcp = new char*[1];
srcp[0] = src;
return srcp;
}
void freeShaderSource(char** srcp)
{
delete srcp[0];
delete srcp;
}
struct Shape {
GLuint vao;
GLuint vbo_xyz;
GLuint vbo_nml;
GLuint vbo_uv;
GLuint ibo;
int materialId;
int indexCount;
};
vector<Shape> m;
vector<GLuint> vbo_texs;
void My_LoadModel() {
const aiScene *scene = aiImportFile("sponza.obj", aiProcessPreset_TargetRealtime_MaxQuality);
for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
aiMaterial *material = scene->mMaterials[i];
aiString texturePath;
texture_data tex;
if (material->GetTexture(aiTextureType_DIFFUSE, 0, &texturePath) == aiReturn_SUCCESS) {
// load width, height and data from texturePath.C_Str();
tex = load_png(texturePath.C_Str());
cout << "Load " << texturePath.C_Str() << ":" << tex.width << ", " << tex.height << endl;
}
else {
// load some default image as default_diffuse_tex
tex = load_png("me.png");
cout << "Load me.png" << ":" << tex.width << ", " << tex.height << endl;
}
GLuint vbo_tex;
glGenTextures(1, &vbo_tex);
glBindTexture(GL_TEXTURE_2D, vbo_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex.width, tex.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.data);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// save material…
vbo_texs.push_back(vbo_tex);
}
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
aiMesh *mesh = scene->mMeshes[i];
Shape shape;
glGenVertexArrays(1, &shape.vao);
glBindVertexArray(shape.vao);
vector<float> vertices;
vector<float> normals;
vector<float> uvs;
vector<unsigned int> indices;
for (unsigned int v = 0; v < mesh->mNumVertices; v++) {
vertices.push_back(mesh->mVertices[v][0]);
vertices.push_back(mesh->mVertices[v][1]);
vertices.push_back(mesh->mVertices[v][2]);
normals.push_back(mesh->mNormals[v][0]);
normals.push_back(mesh->mNormals[v][1]);
normals.push_back(mesh->mNormals[v][2]);
uvs.push_back(mesh->mTextureCoords[0][v][0]);
uvs.push_back(mesh->mTextureCoords[0][v][1]);
}
for (unsigned int f = 0; f < mesh->mNumFaces; f++) {
indices.push_back(mesh->mFaces[f].mIndices[0]);
indices.push_back(mesh->mFaces[f].mIndices[1]);
indices.push_back(mesh->mFaces[f].mIndices[2]);
}
glGenBuffers(1, &shape.vbo_xyz);
glBindBuffer(GL_ARRAY_BUFFER, shape.vbo_xyz);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glGenBuffers(1, &shape.vbo_nml);
glBindBuffer(GL_ARRAY_BUFFER, shape.vbo_nml);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(float), &normals[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glGenBuffers(1, &shape.vbo_uv);
glBindBuffer(GL_ARRAY_BUFFER, shape.vbo_uv);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(float), &uvs[0], GL_STATIC_DRAW);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);
glGenBuffers(1, &shape.ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape.ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
shape.materialId = mesh->mMaterialIndex;
shape.indexCount = mesh->mNumFaces * 3;
// save shape…
m.push_back(shape);
}
aiReleaseImport(scene);
}
void My_Init()
{
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glEnable(GL_DEPTH_TEST);
// glEnable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);
program = glCreateProgram();
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
char** vertexShaderSource = loadShaderSource("vertex.vs.glsl");
char** fragmentShaderSource = loadShaderSource("fragment.fs.glsl");
glShaderSource(vertexShader, 1, vertexShaderSource, NULL);
glShaderSource(fragmentShader, 1, fragmentShaderSource, NULL);
freeShaderSource(vertexShaderSource);
freeShaderSource(fragmentShaderSource);
glCompileShader(vertexShader);
glCompileShader(fragmentShader);
shaderLog(vertexShader);
shaderLog(fragmentShader);
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
um4p = glGetUniformLocation(program, "um4p");
um4mv = glGetUniformLocation(program, "um4mv");
um4tex = glGetUniformLocation(program, "tex");
glUseProgram(program);
My_LoadModel();
}
// GLUT callback. Called to draw the scene.
void My_Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glUniformMatrix4fv(um4mv, 1, GL_FALSE, value_ptr(view * model));
glUniformMatrix4fv(um4p, 1, GL_FALSE, value_ptr(projection));
glActiveTexture(GL_TEXTURE0);
glUniform1i(um4tex, 0);
for (const Shape& s: m) {
auto vbo_tex = vbo_texs[s.materialId];
glBindVertexArray(s.vao);
glBindTexture(GL_TEXTURE_2D, vbo_tex);
glDrawElements(GL_TRIANGLES, s.indexCount, GL_UNSIGNED_INT, 0);
}
glutSwapBuffers();
}
void My_Reshape(int width, int height)
{
glViewport(0, 0, width, height);
float viewportAspect = (float)width / (float)height;
projection = perspective(radians(60.0f), viewportAspect, 0.1f, 1000.0f);
view = lookAt(vec3(-10.0f, 0.0f, 0.0f), vec3(1.0f, 1.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
}
void My_Timer(int val)
{
timer_cnt++;
glutPostRedisplay();
if(timer_enabled)
{
glutTimerFunc(timer_speed, My_Timer, val);
}
}
void My_Keyboard(unsigned char key, int x, int y)
{
printf("Key %c is pressed at (%d, %d)\n", key, x, y);
if (key == 'q') {
exit(0);
}
// if (key == 'd')
// {
// temp = temp + vec3(0, 0, 1);
// }
// else if (key == 'a')
// {
// temp = temp - vec3(0, 0, 1);
// }
// else if (key == 'w')
// {
// temp = temp + vec3(1, 0, 0);
// }
// else if (key == 's')
// {
// temp = temp - vec3(1, 0, 0);
// }
}
void My_SpecialKeys(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_F1:
printf("F1 is pressed at (%d, %d)\n", x, y);
break;
case GLUT_KEY_PAGE_UP:
printf("Page up is pressed at (%d, %d)\n", x, y);
break;
case GLUT_KEY_LEFT:
printf("Left arrow is pressed at (%d, %d)\n", x, y);
break;
default:
printf("Other special key is pressed at (%d, %d)\n", x, y);
break;
}
}
void My_Menu(int id)
{
switch(id)
{
case MENU_TIMER_START:
if(!timer_enabled)
{
timer_enabled = true;
glutTimerFunc(timer_speed, My_Timer, 0);
}
break;
case MENU_TIMER_STOP:
timer_enabled = false;
break;
case MENU_EXIT:
exit(0);
break;
default:
break;
}
}
int main(int argc, char *argv[])
{
#ifdef __APPLE__
// Change working directory to source code path
chdir(__FILEPATH__("/../Assets/"));
#endif
// Initialize GLUT and GLEW, then create a window.
////////////////////
glutInit(&argc, argv);
#ifdef _MSC_VER
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
#else
glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
#endif
glutInitWindowPosition(100, 100);
glutInitWindowSize(600, 600);
glutCreateWindow("Practice"); // You cannot use OpenGL functions before this line; The OpenGL context must be created first by glutCreateWindow()!
#ifdef _MSC_VER
glewInit();
#endif
dumpInfo();
My_Init();
// Create a menu and bind it to mouse right button.
int menu_main = glutCreateMenu(My_Menu);
int menu_timer = glutCreateMenu(My_Menu);
int menu_new = glutCreateMenu(My_Menu);
glutSetMenu(menu_main);
glutAddSubMenu("Timer", menu_timer);
glutAddMenuEntry("Exit", MENU_EXIT);
glutSetMenu(menu_timer);
glutAddMenuEntry("Start", MENU_TIMER_START);
glutAddMenuEntry("Stop", MENU_TIMER_STOP);
glutSetMenu(menu_main);
glutAttachMenu(GLUT_RIGHT_BUTTON);
// Register GLUT callback functions.
glutDisplayFunc(My_Display);
glutReshapeFunc(My_Reshape);
glutKeyboardFunc(My_Keyboard);
glutSpecialFunc(My_SpecialKeys);
glutTimerFunc(timer_speed, My_Timer, 0);
// Enter main event loop.
glutMainLoop();
return 0;
}
#version 410
layout(location = 0) in vec3 iv3vertex;
layout(location = 1) in vec3 iv3normal;
layout(location = 2) in vec2 iv2tex_coord;
uniform mat4 um4mv;
uniform mat4 um4p;
out VertexData
{
vec3 N; // eye space normal
vec3 L; // eye space light vector
vec3 H; // eye space halfway vector
vec2 texcoord;
} vertexData;
void main()
{
gl_Position = um4p * um4mv * vec4(iv3vertex, 1.0);
vertexData.texcoord = iv2tex_coord;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment