Skip to content

Instantly share code, notes, and snippets.

@juriad
Created October 17, 2014 09:21
Show Gist options
  • Save juriad/ba66f7184d12c5a29e84 to your computer and use it in GitHub Desktop.
Save juriad/ba66f7184d12c5a29e84 to your computer and use it in GitHub Desktop.
Torus rendering
// Include standard headers
#include <stdio.h>
#include <stdlib.h>
// Include GLEW
#include <GL/glew.h>
// Include GLFW
#include <GLFW/glfw3.h>
GLFWwindow* window;
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
#include "shader.hpp"
#include "texture.hpp"
int initWindow() {
// Initialise GLFW
if (!glfwInit()) {
fprintf( stderr, "Failed to initialize GLFW\n");
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Open a window and create its OpenGL context
window = glfwCreateWindow(1024, 768, "Tutorial 05 - Textured Cube", NULL,
NULL);
if (window == NULL) {
fprintf( stderr,
"Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
return 0;
}
void setCoords(double r, double c, int rSeg, int cSeg, int i, int j,
GLfloat * vertices, GLfloat * uv) {
const double PI = 3.1415926535897932384626433832795;
const double TAU = 2 * PI;
double x = (c + r * cos(i * TAU / rSeg)) * cos(j * TAU / cSeg);
double y = (c + r * cos(i * TAU / rSeg)) * sin(j * TAU / cSeg);
double z = r * sin(i * TAU / rSeg);
vertices[0] = 2 * x;
vertices[1] = 2 * y;
vertices[2] = 2 * z;
uv[0] = i / (double) rSeg;
uv[1] = j / (double) cSeg;
}
int createObject(double r, double c, int rSeg, int cSeg, GLfloat ** vertices,
GLfloat ** uv) {
int count = rSeg * cSeg * 6;
*vertices = (GLfloat *) malloc(count * 3 * sizeof(GLfloat));
*uv = (GLfloat *) malloc(count * 2 * sizeof(GLfloat));
for (int x = 0; x < cSeg; x++) { // through stripes
for (int y = 0; y < rSeg; y++) { // through squares on stripe
GLfloat * vertexPtr = *vertices + ((x * rSeg) + y) * 18;
GLfloat * uvPtr = *uv + ((x * rSeg) + y) * 12;
setCoords(r, c, rSeg, cSeg, x, y, vertexPtr + 0, uvPtr + 0);
setCoords(r, c, rSeg, cSeg, x + 1, y, vertexPtr + 3, uvPtr + 2);
setCoords(r, c, rSeg, cSeg, x, y + 1, vertexPtr + 6, uvPtr + 4);
setCoords(r, c, rSeg, cSeg, x, y + 1, vertexPtr + 9, uvPtr + 6);
setCoords(r, c, rSeg, cSeg, x + 1, y, vertexPtr + 12, uvPtr + 8);
setCoords(r, c, rSeg, cSeg, x + 1, y + 1, vertexPtr + 15,
uvPtr + 10);
}
}
return count;
}
int main(void) {
if (initWindow() != 0) {
return -1;
}
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
glDisable(GL_CULL_FACE);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders("TransformVertexShader.vertexshader",
"TextureFragmentShader.fragmentshader");
// Get a handle for our "MVP" uniform
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
// Projection matrix : 45� Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
// Camera matrix
glm::mat4 View = glm::lookAt(glm::vec3(0, -15, 12), // Camera is at (4,3,3), in World Space
glm::vec3(0, 0, 0), // and looks at the origin
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
);
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 Model = glm::mat4(1.0f);
// Our ModelViewProjection : multiplication of our 3 matrices
glm::mat4 MVP = Projection * View * Model; // Remember, matrix multiplication is the other way around
// Load the texture using any two methods
GLuint Texture = loadBMP_custom("uvtemplate1.bmp");
//GLuint Texture = loadDDS("uvtemplate.DDS");
// Get a handle for our "myTextureSampler" uniform
GLuint TextureID = glGetUniformLocation(programID, "myTextureSampler");
GLfloat * g_vertex_buffer_data;
GLfloat * g_uv_buffer_data;
int vertices = createObject(1, 2, 360, 360, &g_vertex_buffer_data,
&g_uv_buffer_data);
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices * 3 * sizeof(GLfloat),
g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices * 2 * sizeof(GLfloat),
g_uv_buffer_data, GL_STATIC_DRAW);
do {
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glDepthRange(0.0f, 1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(programID);
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);
// Set our "myTextureSampler" sampler to user Texture Unit 0
glUniform1i(TextureID, 0);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*) 0 // array buffer offset
);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(1, // attribute. No particular reason for 1, but must match the layout in the shader.
2, // size : U+V => 2
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*) 0 // array buffer offset
);
glFrontFace(GL_CW);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, vertices * 3); // 12*3 indices starting at 0 -> 12 triangles
glFrontFace(GL_CCW);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS
&& glfwWindowShouldClose(window) == 0);
// Cleanup VBO and shader
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &uvbuffer);
glDeleteProgram(programID);
glDeleteTextures(1, &TextureID);
glDeleteVertexArrays(1, &VertexArrayID);
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment