22#define GLFW_INCLUDE_NONE
33#include < GLFW/glfw3.h>
44#include < cglm/cglm.h>
5+ #include < vector>
56#include < iostream>
67
78const char * vertexShaderSource = R"glsl(
@@ -29,72 +30,47 @@ struct Camera {
2930 float sensitivity;
3031};
3132
32- Camera camera = {
33- {0 .0f , 0 .0f , 3 .0f },
34- -90 .0f ,
35- 0 .0f ,
36- 2 .5f ,
37- 0 .1f
38- };
39-
33+ Camera camera = {{0 .0f , 0 .0f , 50 .0f }, -90 .0f , 0 .0f , 10 .0f , 0 .1f };
4034float lastX = 400 , lastY = 300 ;
4135bool firstMouse = true ;
42- float deltaTime = 0 .0f ;
43- float lastFrame = 0 .0f ;
44-
45- void framebuffer_size_callback (GLFWwindow* window, int width, int height) {
46- glViewport (0 , 0 , width, height);
47- }
36+ float deltaTime = 0 .0f , lastFrame = 0 .0f ;
37+ bool wireframe = false ;
38+ bool ePressedLastFrame = false ;
4839
40+ void framebuffer_size_callback (GLFWwindow* window, int width, int height) { glViewport (0 , 0 , width, height); }
4941void mouse_callback (GLFWwindow* window, double xpos, double ypos) {
50- if (firstMouse) {
51- lastX = (float )xpos;
52- lastY = (float )ypos;
53- firstMouse = false ;
54- }
55- float xoffset = (float )(xpos - lastX);
56- float yoffset = (float )(lastY - ypos);
57- lastX = (float )xpos;
58- lastY = (float )ypos;
59- xoffset *= camera.sensitivity ;
60- yoffset *= camera.sensitivity ;
61- camera.yaw += xoffset;
62- camera.pitch += yoffset;
42+ if (firstMouse) { lastX = (float )xpos; lastY = (float )ypos; firstMouse = false ; }
43+ float xoffset = (float )(xpos - lastX), yoffset = (float )(lastY - ypos);
44+ lastX = (float )xpos; lastY = (float )ypos;
45+ xoffset *= camera.sensitivity ; yoffset *= camera.sensitivity ;
46+ camera.yaw += xoffset; camera.pitch += yoffset;
6347 if (camera.pitch > 89 .0f ) camera.pitch = 89 .0f ;
6448 if (camera.pitch < -89 .0f ) camera.pitch = -89 .0f ;
6549}
6650
6751void processInput (GLFWwindow* window) {
6852 float velocity = camera.speed * deltaTime;
69- vec3 front;
70- front[0 ] = cos (glm_rad (camera.yaw )) * cos (glm_rad (camera.pitch ));
71- front[1 ] = sin (glm_rad (camera.pitch ));
72- front[2 ] = sin (glm_rad (camera.yaw )) * cos (glm_rad (camera.pitch ));
53+ vec3 front = {cos (glm_rad (camera.yaw )) * cos (glm_rad (camera.pitch )),
54+ sin (glm_rad (camera.pitch )),
55+ sin (glm_rad (camera.yaw )) * cos (glm_rad (camera.pitch ))};
7356 glm_vec3_normalize (front);
74- vec3 right;
75- vec3 worldUp = {0 .0f , 1 .0f , 0 .0f };
76- glm_vec3_cross (front, worldUp, right);
77- glm_vec3_normalize (right);
78- vec3 up;
79- glm_vec3_cross (right, front, up);
80- if (glfwGetKey (window, GLFW_KEY_W) == GLFW_PRESS) {
81- vec3 tmp; glm_vec3_scale (front, velocity, tmp); glm_vec3_add (camera.position , tmp, camera.position );
82- }
83- if (glfwGetKey (window, GLFW_KEY_S) == GLFW_PRESS) {
84- vec3 tmp; glm_vec3_scale (front, velocity, tmp); glm_vec3_sub (camera.position , tmp, camera.position );
85- }
86- if (glfwGetKey (window, GLFW_KEY_A) == GLFW_PRESS) {
87- vec3 tmp; glm_vec3_scale (right, velocity, tmp); glm_vec3_sub (camera.position , tmp, camera.position );
88- }
89- if (glfwGetKey (window, GLFW_KEY_D) == GLFW_PRESS) {
90- vec3 tmp; glm_vec3_scale (right, velocity, tmp); glm_vec3_add (camera.position , tmp, camera.position );
91- }
92- if (glfwGetKey (window, GLFW_KEY_SPACE) == GLFW_PRESS) {
93- vec3 tmp; glm_vec3_scale (up, velocity, tmp); glm_vec3_add (camera.position , tmp, camera.position );
94- }
95- if (glfwGetKey (window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) {
96- vec3 tmp; glm_vec3_scale (up, velocity, tmp); glm_vec3_sub (camera.position , tmp, camera.position );
57+ vec3 right; vec3 worldUp = {0 .0f , 1 .0f , 0 .0f };
58+ glm_vec3_cross (front, worldUp, right); glm_vec3_normalize (right);
59+ vec3 up; glm_vec3_cross (right, front, up);
60+
61+ if (glfwGetKey (window, GLFW_KEY_W) == GLFW_PRESS) { vec3 tmp; glm_vec3_scale (front, velocity, tmp); glm_vec3_add (camera.position , tmp, camera.position ); }
62+ if (glfwGetKey (window, GLFW_KEY_S) == GLFW_PRESS) { vec3 tmp; glm_vec3_scale (front, velocity, tmp); glm_vec3_sub (camera.position , tmp, camera.position ); }
63+ if (glfwGetKey (window, GLFW_KEY_A) == GLFW_PRESS) { vec3 tmp; glm_vec3_scale (right, velocity, tmp); glm_vec3_sub (camera.position , tmp, camera.position ); }
64+ if (glfwGetKey (window, GLFW_KEY_D) == GLFW_PRESS) { vec3 tmp; glm_vec3_scale (right, velocity, tmp); glm_vec3_add (camera.position , tmp, camera.position ); }
65+ if (glfwGetKey (window, GLFW_KEY_SPACE) == GLFW_PRESS) { vec3 tmp; glm_vec3_scale (up, velocity, tmp); glm_vec3_add (camera.position , tmp, camera.position ); }
66+ if (glfwGetKey (window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) { vec3 tmp; glm_vec3_scale (up, velocity, tmp); glm_vec3_sub (camera.position , tmp, camera.position ); }
67+
68+ bool ePressedNow = glfwGetKey (window, GLFW_KEY_E) == GLFW_PRESS;
69+ if (ePressedNow && !ePressedLastFrame) {
70+ wireframe = !wireframe;
71+ glPolygonMode (GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_FILL);
9772 }
73+ ePressedLastFrame = ePressedNow;
9874}
9975
10076GLuint compileShader (GLenum type, const char * source) {
@@ -103,87 +79,81 @@ GLuint compileShader(GLenum type, const char* source) {
10379 glCompileShader (shader);
10480 GLint success;
10581 glGetShaderiv (shader, GL_COMPILE_STATUS, &success);
106- if (!success) {
107- char infoLog[512 ];
108- glGetShaderInfoLog (shader, 512 , nullptr , infoLog);
109- std::cerr << " Shader compilation failed:\n " << infoLog << std::endl;
110- }
82+ if (!success) { char info[512 ]; glGetShaderInfoLog (shader, 512 , nullptr , info); std::cerr << info << std::endl; }
11183 return shader;
11284}
11385
86+ // Cube face vertices
87+ float faceVertices[6 ][18 ] = {
88+ // +X
89+ {0 .5f , -0 .5f , -0 .5f , 0 .5f , 0 .5f , -0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , -0 .5f , 0 .5f , 0 .5f , -0 .5f , -0 .5f },
90+ // -X
91+ {-0 .5f , -0 .5f , 0 .5f , -0 .5f , 0 .5f , 0 .5f , -0 .5f , 0 .5f , -0 .5f , -0 .5f , 0 .5f , -0 .5f , -0 .5f , -0 .5f , -0 .5f , -0 .5f , -0 .5f , 0 .5f },
92+ // +Y
93+ {-0 .5f , 0 .5f , -0 .5f , -0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , -0 .5f , -0 .5f , 0 .5f , -0 .5f },
94+ // -Y
95+ {-0 .5f , -0 .5f , 0 .5f , -0 .5f , -0 .5f , -0 .5f , 0 .5f , -0 .5f , -0 .5f , 0 .5f , -0 .5f , -0 .5f , 0 .5f , -0 .5f , 0 .5f , -0 .5f , -0 .5f , 0 .5f },
96+ // +Z
97+ {-0 .5f , -0 .5f , 0 .5f , 0 .5f , -0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , 0 .5f , -0 .5f , 0 .5f , 0 .5f , -0 .5f , -0 .5f , 0 .5f },
98+ // -Z
99+ {0 .5f , -0 .5f , -0 .5f , -0 .5f , -0 .5f , -0 .5f , -0 .5f , 0 .5f , -0 .5f , -0 .5f , 0 .5f , -0 .5f , 0 .5f , 0 .5f , -0 .5f , 0 .5f , -0 .5f , -0 .5f }
100+ };
101+
114102int main () {
115103 if (!glfwInit ()) return -1 ;
116104 glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3 );
117105 glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 3 );
118106 glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
119- GLFWwindow* window = glfwCreateWindow (800 , 600 , " Red Cube with Camera " , nullptr , nullptr );
107+ GLFWwindow* window = glfwCreateWindow (800 , 600 , " Optimized 16x16x16 Cube " , nullptr , nullptr );
120108 if (!window) { glfwTerminate (); return -1 ; }
121109 glfwMakeContextCurrent (window);
122110 glfwSetFramebufferSizeCallback (window, framebuffer_size_callback);
123111 glfwSetInputMode (window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
124112 glfwSetCursorPosCallback (window, mouse_callback);
125113 if (!gladLoadGLLoader ((GLADloadproc)glfwGetProcAddress)) return -1 ;
126- int width, height;
127- glfwGetFramebufferSize (window, &width, &height);
128- glViewport (0 , 0 , width, height);
129-
130- float vertices[] = {
131- -0 .5f , -0 .5f , -0 .5f ,
132- 0 .5f , -0 .5f , -0 .5f ,
133- 0 .5f , 0 .5f , -0 .5f ,
134- 0 .5f , 0 .5f , -0 .5f ,
135- -0 .5f , 0 .5f , -0 .5f ,
136- -0 .5f , -0 .5f , -0 .5f ,
137-
138- -0 .5f , -0 .5f , 0 .5f ,
139- 0 .5f , -0 .5f , 0 .5f ,
140- 0 .5f , 0 .5f , 0 .5f ,
141- 0 .5f , 0 .5f , 0 .5f ,
142- -0 .5f , 0 .5f , 0 .5f ,
143- -0 .5f , -0 .5f , 0 .5f ,
144-
145- -0 .5f , 0 .5f , 0 .5f ,
146- -0 .5f , 0 .5f , -0 .5f ,
147- -0 .5f , -0 .5f , -0 .5f ,
148- -0 .5f , -0 .5f , -0 .5f ,
149- -0 .5f , -0 .5f , 0 .5f ,
150- -0 .5f , 0 .5f , 0 .5f ,
151-
152- 0 .5f , 0 .5f , 0 .5f ,
153- 0 .5f , 0 .5f , -0 .5f ,
154- 0 .5f , -0 .5f , -0 .5f ,
155- 0 .5f , -0 .5f , -0 .5f ,
156- 0 .5f , -0 .5f , 0 .5f ,
157- 0 .5f , 0 .5f , 0 .5f ,
158-
159- -0 .5f , -0 .5f , -0 .5f ,
160- 0 .5f , -0 .5f , -0 .5f ,
161- 0 .5f , -0 .5f , 0 .5f ,
162- 0 .5f , -0 .5f , 0 .5f ,
163- -0 .5f , -0 .5f , 0 .5f ,
164- -0 .5f , -0 .5f , -0 .5f ,
165-
166- -0 .5f , 0 .5f , -0 .5f ,
167- 0 .5f , 0 .5f , -0 .5f ,
168- 0 .5f , 0 .5f , 0 .5f ,
169- 0 .5f , 0 .5f , 0 .5f ,
170- -0 .5f , 0 .5f , 0 .5f ,
171- -0 .5f , 0 .5f , -0 .5f
172- };
114+
115+ // Cube presence map
116+ const int SIZE = 16 ;
117+ bool cube[SIZE][SIZE][SIZE];
118+ for (int x=0 ;x<SIZE;x++) for (int y=0 ;y<SIZE;y++) for (int z=0 ;z<SIZE;z++) cube[x][y][z]=true ;
119+
120+ std::vector<float > vertices;
121+
122+ // Build vertices for only visible faces
123+ for (int x=0 ;x<SIZE;x++){
124+ for (int y=0 ;y<SIZE;y++){
125+ for (int z=0 ;z<SIZE;z++){
126+ if (!cube[x][y][z]) continue ;
127+ // Check neighbors: +X, -X, +Y, -Y, +Z, -Z
128+ int neighbor[6 ][3 ]={{1 ,0 ,0 },{-1 ,0 ,0 },{0 ,1 ,0 },{0 ,-1 ,0 },{0 ,0 ,1 },{0 ,0 ,-1 }};
129+ for (int f=0 ;f<6 ;f++){
130+ int nx=x+neighbor[f][0 ], ny=y+neighbor[f][1 ], nz=z+neighbor[f][2 ];
131+ if (nx<0 ||nx>=SIZE||ny<0 ||ny>=SIZE||nz<0 ||nz>=SIZE||!cube[nx][ny][nz]){
132+ // Add this face
133+ for (int v=0 ;v<18 ;v+=3 ){
134+ vertices.push_back (faceVertices[f][v]+x-SIZE/2 .0f );
135+ vertices.push_back (faceVertices[f][v+1 ]+y-SIZE/2 .0f );
136+ vertices.push_back (faceVertices[f][v+2 ]+z-SIZE/2 .0f );
137+ }
138+ }
139+ }
140+ }
141+ }
142+ }
173143
174144 GLuint VBO, VAO;
175- glGenVertexArrays (1 , &VAO);
176- glGenBuffers (1 , &VBO);
145+ glGenVertexArrays (1 ,&VAO);
146+ glGenBuffers (1 ,&VBO);
177147 glBindVertexArray (VAO);
178- glBindBuffer (GL_ARRAY_BUFFER, VBO);
179- glBufferData (GL_ARRAY_BUFFER, sizeof (vertices ), vertices, GL_STATIC_DRAW);
180- glVertexAttribPointer (0 , 3 , GL_FLOAT, GL_FALSE, 3 * sizeof (float ), (void *)0 );
148+ glBindBuffer (GL_ARRAY_BUFFER,VBO);
149+ glBufferData (GL_ARRAY_BUFFER, vertices. size ()* sizeof (float ), vertices. data () , GL_STATIC_DRAW);
150+ glVertexAttribPointer (0 ,3 , GL_FLOAT,GL_FALSE,3 * sizeof (float ),(void *)0 );
181151 glEnableVertexAttribArray (0 );
182152 glBindVertexArray (0 );
183153
154+ GLuint shaderProgram = glCreateProgram ();
184155 GLuint vertexShader = compileShader (GL_VERTEX_SHADER, vertexShaderSource);
185156 GLuint fragmentShader = compileShader (GL_FRAGMENT_SHADER, fragmentShaderSource);
186- GLuint shaderProgram = glCreateProgram ();
187157 glAttachShader (shaderProgram, vertexShader);
188158 glAttachShader (shaderProgram, fragmentShader);
189159 glLinkProgram (shaderProgram);
@@ -192,50 +162,41 @@ int main() {
192162
193163 glEnable (GL_DEPTH_TEST);
194164
195- while (!glfwWindowShouldClose (window)) {
196- float currentFrame = (float )glfwGetTime ();
197- deltaTime = currentFrame - lastFrame;
198- lastFrame = currentFrame;
165+ while (!glfwWindowShouldClose (window)){
166+ float currentFrame= (float )glfwGetTime ();
167+ deltaTime= currentFrame- lastFrame;
168+ lastFrame= currentFrame;
199169 processInput (window);
200170
201- glClearColor (0 .1f , 0 .2f , 0 .3f , 1 .0f );
202- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
171+ glClearColor (0 .1f ,0 .2f ,0 .3f ,1 .0f );
172+ glClear (GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
203173
204- vec3 front;
205- front[0 ] = cos (glm_rad (camera.yaw )) * cos (glm_rad (camera.pitch ));
206- front[1 ] = sin (glm_rad (camera.pitch ));
207- front[2 ] = sin (glm_rad (camera.yaw )) * cos (glm_rad (camera.pitch ));
174+ vec3 front={cos (glm_rad (camera.yaw ))*cos (glm_rad (camera.pitch )),
175+ sin (glm_rad (camera.pitch )),
176+ sin (glm_rad (camera.yaw ))*cos (glm_rad (camera.pitch ))};
208177 glm_vec3_normalize (front);
209- vec3 center;
210- glm_vec3_add (camera.position , front, center);
211- mat4 view;
212- vec3 up = {0 .0f , 1 .0f , 0 .0f };
213- glm_lookat (camera.position , center, up, view);
214- int width, height;
215- glfwGetFramebufferSize (window, &width, &height);
216- float aspect = (float )width / (float )height;
217- mat4 proj;
218- glm_perspective (glm_rad (45 .0f ), aspect, 0 .1f , 100 .0f , proj);
219- mat4 model;
220- glm_mat4_identity (model);
221- mat4 vp, mvp;
222- glm_mat4_mul (proj, view, vp);
223- glm_mat4_mul (vp, model, mvp);
178+ vec3 center; glm_vec3_add (camera.position , front, center);
179+ mat4 view; vec3 upVec={0 .0f ,1 .0f ,0 .0f };
180+ glm_lookat (camera.position , center, upVec, view);
181+ int width,height; glfwGetFramebufferSize (window,&width,&height);
182+ float aspect=(float )width/(float )height;
183+ mat4 proj; glm_perspective (glm_rad (45 .0f ), aspect, 0 .1f , 500 .0f , proj);
184+ mat4 mvp; glm_mat4_mul (proj, view, mvp);
224185
225186 glUseProgram (shaderProgram);
226- GLint mvpLoc = glGetUniformLocation (shaderProgram, " uMVP" );
227- glUniformMatrix4fv (mvpLoc, 1 , GL_FALSE, (const GLfloat*)mvp);
187+ GLint mvpLoc= glGetUniformLocation (shaderProgram," uMVP" );
188+ glUniformMatrix4fv (mvpLoc,1 , GL_FALSE,(const GLfloat*)mvp);
228189
229190 glBindVertexArray (VAO);
230- glDrawArrays (GL_TRIANGLES, 0 , 36 );
191+ glDrawArrays (GL_TRIANGLES,0 ,(GLsizei)vertices. size ()/ 3 );
231192 glBindVertexArray (0 );
232193
233194 glfwSwapBuffers (window);
234195 glfwPollEvents ();
235196 }
236197
237- glDeleteVertexArrays (1 , &VAO);
238- glDeleteBuffers (1 , &VBO);
198+ glDeleteVertexArrays (1 ,&VAO);
199+ glDeleteBuffers (1 ,&VBO);
239200 glDeleteProgram (shaderProgram);
240201 glfwDestroyWindow (window);
241202 glfwTerminate ();
0 commit comments