ASSISTANT
Here is an example of a full OpenGL program that includes shader code for a basic rendering setup using vertex and fragment shaders. This code demonstrates loading a texture and rotating it around the Z-axis using shaders. Make sure to have the required libraries and shader files present in your project directory.
```cpp
#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <fstream>
#include <string>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
GLuint VBO, VAO, EBO, textureID;
GLuint shaderProgram;
GLfloat angle = 0.0f;
std::string vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec2 aTexCoord;\n"
"out vec2 TexCoord;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
" gl_Position = projection * view * model * vec4(aPos, 1.0);\n"
" TexCoord = aTexCoord;\n"
"}\0";
std::string fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"in vec2 TexCoord;\n"
"uniform sampler2D texture1;\n"
"void main()\n"
"{\n"
" FragColor = texture(texture1, TexCoord);\n"
"}\0";
void loadTexture(const char* filename) {
int width, height, channels;
stbi_set_flip_vertically_on_load(true);
unsigned char* image = stbi_load(filename, &width, &height, &channels, 0);
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(image);
}
void setShaders() {
GLint success;
char infoLog[512];
// Vertex Shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
const char* vShaderCode = vertexShaderSource.c_str();
glShaderSource(vertexShader, 1, &vShaderCode, NULL);
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "Vertex Shader Compilation Error: " << infoLog << std::endl;
}
// Fragment Shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* fShaderCode = fragmentShaderSource.c_str();
glShaderSource(fragmentShader, 1, &fShaderCode, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "Fragment Shader Compilation Error: " << infoLog << std::endl;
}
// Shader Program
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "Shader Program Linking Error: " << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
void render() {
glClear(GL_COLOR_BUFFER_BIT);
glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(0.0f, 0.0f, 1.0f));
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
glUseProgram(shaderProgram);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glBindTexture(GL_TEXTURE_2D, textureID);
// Render the quad with texture coordinates, using the VAO/VBO/EBO setup
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glutSwapBuffers();
}
void update(int value) {
angle += 1.0f;
if (angle > 360.0f) {
angle -= 360.0f;
}
glutPostRedisplay();
glutTimerFunc(16, update, 0);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL Program");
if (glewInit() != GLEW_OK) {
std::cout << "Error initializing GLEW." << std::endl;
return -1;
}
loadTexture("texture.jpg");
setShaders();
// Texture coordinates, VAO/VBO/EBO setup for quad
glutDisplayFunc(render);
glutTimerFunc(0, update, 0);
glutMainLoop();
return 0;
}
```
In this code snippet:
- The program includes the vertex and fragment shader source code as strings, shader compilation and linking functions, texture loading using STB image library, rendering function to apply transformation matrices, and texture rendering with shaders.
- Make sure to adjust the code according to your specific requirements, including the shader code, texture file path, and the setup for rendering objects with OpenGL. You may also need to set up the vertex array object (VAO), vertex buffer object (VBO), element buffer object (EBO), and the quad's texture coordinates for rendering a textured quad.