opengl

Sample code from LearnOpenGL.com
Log | Files | Refs

main.c (7264B)


      1 #include <math.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 
      6 #include <glad/glad.h>
      7 #include <GLFW/glfw3.h>
      8 
      9 #include "main.h"
     10 #include "glm.h"
     11 #include "err.h"
     12 #define STB_IMAGE_IMPLEMENTATION
     13 #define STBI_NO_SIMD // TODO: confirm this workaround.
     14 #include "stb_image.h"
     15 
     16 int rotating = 0;
     17 float alpha = 0.2;
     18 
     19 void
     20 framebuffer_size_callback(GLFWwindow *window, int width, int height)
     21 {
     22 	glViewport(0, 0, width, height);
     23 }
     24 
     25 void
     26 processInput(GLFWwindow *window)
     27 {
     28 	static int spacePressing = 0;
     29 	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
     30 		glfwSetWindowShouldClose(window, 1);
     31 	else if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
     32 		if (!spacePressing) {
     33 			spacePressing = 1;
     34 			rotating = !rotating;
     35 		}
     36 	} else if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_RELEASE &&
     37 		spacePressing == 1) {
     38 		spacePressing = 0;
     39 	} else if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
     40 		alpha += 0.01;
     41 		if (alpha > 1.0)
     42 			alpha = 1.0;
     43 	} else if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
     44 		alpha -= 0.01;
     45 		if (alpha < 0)
     46 			alpha = 0;
     47 	}
     48 }
     49 
     50 int
     51 main(void)
     52 {
     53 	int width = 600;
     54 	int height = 600;
     55 	
     56 	float vertices[] = {
     57 		-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
     58 		0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
     59 		0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     60 		0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     61 		-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
     62 		-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
     63 		
     64 		-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     65 		0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
     66 		0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
     67 		0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
     68 		-0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
     69 		-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     70 		
     71 		-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     72 		-0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     73 		-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     74 		-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     75 		-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     76 		-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     77 		
     78 		0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     79 		0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     80 		0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     81 		0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     82 		0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     83 		0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     84 		
     85 		-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     86 		0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
     87 		0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
     88 		0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
     89 		-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     90 		-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     91 		
     92 		-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
     93 		0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     94 		0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     95 		0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     96 		-0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
     97 		-0.5f,  0.5f, -0.5f,  0.0f, 1.0f
     98 	};
     99 	
    100 	int numCube = 3;
    101 	vec *cubePositions[numCube];
    102 	cubePositions[0] = vecMake((float []){-2.0, 0.0, -2.0}, 3);
    103 	cubePositions[1] = vecMake((float []){0.0, 0.0, 0.0}, 3);
    104 	cubePositions[2] = vecMake((float []){1.0, 1.0, -1.0}, 3);
    105 	mat *modelMat[numCube];
    106 	for (int i = 0; i < numCube; i++) {
    107 		modelMat[i] = scale(matMakeIdent(4), 0.1);
    108 		translate(modelMat[i], cubePositions[i]);
    109 	}
    110 	mat *projMat = matMakePers((float)M_PI/4, (float)width/(float)height,
    111 		0.1, 100.0);
    112 	vec *cameraPos = vecMake((float[]){4.0, 1.0, 4.0}, 3);
    113 	vec *cameraTarget = vecMake((float[]){0.0, 0.0, 0.0}, 3);
    114 	vec *cameraUp = vecMake((float[]){0.0, 1.0, 0.0}, 3);
    115 	mat *viewMat = matMakeLookAt(cameraPos, cameraTarget, cameraUp);
    116 	vec *axis0 = vecMake((float[]){1.41421356/2, 1.41421356/2, 0.0}, 3);
    117 	vec *axis1 = vecMake((float[]){0.0, 1.0, 0.0}, 3);
    118 	
    119 	// initialize glfw
    120 	glfwInit();
    121 	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    122 	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    123 	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    124 	
    125 	// create glfw window
    126 	GLFWwindow *window = glfwCreateWindow(width, height, "opengl",
    127 		NULL, NULL);
    128 	if (window == NULL) {
    129 		fprintf(stderr, "main: failed to open window\n");
    130 		glfwTerminate();
    131 		exit(1);
    132 	}
    133 	glfwMakeContextCurrent(window);
    134 	
    135 	// load function pointers
    136 	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
    137 		fprintf(stderr, "main: failed to initialize glad\n");
    138 		exit(1);
    139 	}
    140 	
    141 	// register callback functions
    142 	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    143 	
    144 	// setup shaders
    145 	Shader *shader = ShaderInit("shaders/vertex.sl", "shaders/fragment.sl");
    146 	if (shader == NULL) {
    147 		fprintf(stderr, "init shader: %s\n", errstr);
    148 		exit(1);
    149 	}
    150 	ShaderUse(shader);
    151 	
    152 	// setup vbo
    153 	unsigned int VAO, VBO;
    154 	glGenVertexArrays(1, &VAO);
    155 	glGenBuffers(1, &VBO);
    156 	glBindVertexArray(VAO);
    157 	glBindBuffer(GL_ARRAY_BUFFER, VBO);
    158 	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    159 	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float),
    160 		(void *)0);
    161 	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float),
    162 		(void *)(3*sizeof(float)));
    163 	glEnableVertexAttribArray(0);
    164 	glEnableVertexAttribArray(1);
    165 	
    166 	// setup texture
    167 	int nTex = 2;
    168 	unsigned int textures[nTex];
    169 	char *texfiles[nTex];
    170 	texfiles[0] = "img/wall.jpg";
    171 	texfiles[1] = "img/awesomeface.jpg";
    172 	glGenTextures(nTex, textures);
    173 	for (int i = 0; i < nTex; i++) {
    174 		glActiveTexture(GL_TEXTURE0 + i);
    175 		glBindTexture(GL_TEXTURE_2D, textures[i]);
    176 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
    177 			GL_REPEAT);
    178 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
    179 			GL_REPEAT);
    180 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
    181 			GL_LINEAR_MIPMAP_LINEAR);
    182 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    183 		int width, height;
    184 		unsigned char *data = stbi_load(texfiles[i], &width, &height,
    185 			NULL, 0);
    186 		if (data == NULL) {
    187 			fprintf(stderr, "can't load texture: %s\n", texfiles[i]);
    188 			exit(1);
    189 		}
    190 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
    191 			GL_UNSIGNED_BYTE, data);
    192 		glGenerateMipmap(GL_TEXTURE_2D);
    193 		stbi_image_free(data);
    194 	}
    195 	
    196 	glEnable(GL_DEPTH_TEST);
    197 
    198 	float lastTime = (float) glfwGetTime();
    199 	float rotation = 0;
    200 
    201 	while (!glfwWindowShouldClose(window)) {
    202 		processInput(window);
    203 		
    204 		glClearColor(1.0, 1.0, 0.8, 1.0);
    205 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    206 		
    207 		ShaderSetFloat(shader, "alpha", alpha);
    208 		glUniform1i(glGetUniformLocation(shader->ID, "texture0"), 0);
    209 		glUniform1i(glGetUniformLocation(shader->ID, "texture1"), 1);
    210 		unsigned int tloc = glGetUniformLocation(shader->ID, "transform");
    211 		float now = (float) glfwGetTime();
    212 		if (rotating) {
    213 			rotation += now-lastTime;
    214 		}
    215 		mat *view = matCopy(viewMat);
    216 		rotate(view, rotation, axis1);
    217 		for (int i = 0; i < numCube; i++) {
    218 			mat *transform = matCopy(modelMat[i]);
    219 			rotate(transform, rotation, axis0);
    220 			ShaderSetMat4(shader, "model", matDataPtr(transform));
    221 			ShaderSetMat4(shader, "view", matDataPtr(view));
    222 			ShaderSetMat4(shader, "proj", matDataPtr(projMat));
    223 			glDrawArrays(GL_TRIANGLES, 0, 36);
    224 			matFree(transform);
    225 		}
    226 		matFree(view);
    227 
    228 		lastTime = now;
    229 
    230 		glfwPollEvents();
    231 		glfwSwapBuffers(window);
    232 	}
    233 
    234 
    235 	vecFree(cameraPos);
    236 	vecFree(cameraTarget);
    237 	vecFree(cameraUp);
    238 		
    239 	vecFree(axis0);
    240 	vecFree(axis1);
    241 	for (int i = 0; i < sizeof(cubePositions)/sizeof(cubePositions[0]); i++) {
    242 		vecFree(cubePositions[i]);
    243 		matFree(modelMat[i]);
    244 	}
    245 	matFree(viewMat);
    246 	matFree(projMat);
    247 	
    248 	glDeleteVertexArrays(1, &VAO);
    249 	glDeleteBuffers(1, &VBO);
    250 	ShaderDelete(shader);	
    251 	glfwTerminate();
    252 	
    253 	if (matCount() != 0) {
    254 		fprintf(stderr, "%d mats not freed\n", matCount());
    255 		assert(0);
    256 	}
    257 	if (vecCount() != 0) {
    258 		fprintf(stderr, "%d vecs not freed\n", vecCount());
    259 		assert(0);
    260 	}
    261 	return 0;
    262 }