#include <gl/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
const int n = 40;//分割的精确度
const GLfloat R = 0.5f;
const GLfloat Pi = 3.1415926f;
const GLfloat factor = 0.1f;
void MyDisplay(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(6.0f);
glBegin(GL_POINTS);
for (i=0;i<n;++i)
{
glVertex2f(R*cos(2*Pi/n*i),R*sin(2*Pi/n*i));
}
glEnd();
//glRectf(-0.5f,-0.5f,0.5f,0.5f);
glFlush();
}
void DisXing(void)
{
GLfloat x;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2f(-1.0f,0.0f);
glVertex2f(1.0f,0.0f);
glVertex2f(0.0f,-1.0f);
glVertex2f(0.0f,1.0f);
glEnd();
glBegin(GL_LINE_STRIP);
for (x=-1.0f/factor;x<1.0f/factor;x+=0.01f)
{
glVertex2f(x*factor,sin(x)*factor);
}
glEnd();
glFlush();
}
void DisXian(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_LINE_STIPPLE);//启动虚线模式
//glDisable(GL_LINE_STIPPLE);//关闭虚线模式
glLineStipple(4,0xAAAA);
glLineWidth(10.0f);
glBegin(GL_LINES);
glVertex2f(0.0f,0.0f);
glVertex2f(0.5f,0.5f);
glEnd();
glFlush();
}
void DisPolygon(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPolygonMode(GL_FRONT,GL_FILL);//设置正面为填充方式
glPolygonMode(GL_BACK,GL_LINE);//设置反面为线性方式
//glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);//设置两面均为顶点绘制方式
glFrontFace(GL_CCW);//设置逆时针为正面
glEnable(GL_CULL_FACE); //启动剔除模式
glCullFace(GL_FRONT); //剔除正面
//glDisable(GL_CULL_FACE); //关闭剔除模式
glBegin(GL_POLYGON);//逆时针绘制一个正边形,原点左下方
glVertex2f(-0.5f,-0.5f);
glVertex2f(0.0f,-0.5f);
glVertex2f(0.0f,0.0f);
glVertex2f(-0.5f,0.0f);
glEnd();
glBegin(GL_POLYGON);//顺时针绘制一个正边形,原点右上方
glVertex2f(0.0f,0.0f);
glVertex2f(0.0f,0.5f);
glVertex2f(0.5f,0.5f);
glVertex2f(0.5f,0.0f);
glEnd();
glFlush();
}
void LouPolygon(void)
{
static GLubyte Mask[128];
FILE*fp;
fp = fopen("mask.bmp","rb");
if(!fp)
exit(0);
if (fseek(fp,-(int)sizeof(Mask),SEEK_END))
exit(0);
if(! fread(Mask,sizeof(Mask),1,fp))
exit(0);
fclose(fp);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(Mask);
glRectf(-0.5f,-0.5f,0.0f,0.0f);
glDisable(GL_POLYGON_STIPPLE);
glRectf(0.0f,0.0f,0.5f,0.5f);
glFlush();
}
void DisColor(void)
{
//glClearColor(1.0f,0.0f,0.0f,0.0f);//涮屏
//glClear(GL_COLOR_BUFFER_BIT);
//glColor3f(0.0f,1.0f,0.0f);//r,g,b,
//glRectf(0.0f,0.0f,0.5f,0.5f);
int i;
glShadeModel(GL_FLAT);//单色方式
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0f,1.0f,1.0f);
glVertex2f(0.0f,0.0f);
for (i=0;i<=8;i++)
{
glColor3f(i&0x04,i&0x02,i&0x01);
glVertex2f(cos(i*Pi/4),sin(i*Pi/4));
}
glEnd();
glFlush();
}
#include <time.h>
double CalFrequency()
{
static int count;
static double save;
static clock_t last,curent;
double timegap;
++count;
if (count<=50)
return save;
count=0;
last = curent;
curent = clock();
timegap = (curent - last)/(double)CLK_TCK;
save = 50.0/timegap;
return save;
}
static int day = 0;
void DrawNorth(void)
{
double FPS = CalFrequency();
printf("FPS=%f\n",FPS);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);//为了指定当前操作的是何种矩阵
glLoadIdentity();
gluPerspective(75,1,1,400000000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,-200000000,200000000,0,0,0,0,0,1);
//红太阳
glColor3f(1.0f,0.0f,0.0f);
glutSolidSphere(69600000,20,20);
//蓝地球
glColor3f(0.0f,0.0f,1.0f);
glRotatef(day/360.0*360,0.0f,0.0f,-1.0f);
glTranslatef(150000000,0.0f,0.0f);
glutSolidSphere(15945000,20,20);
//黄月亮
glColor3f(1.0f,1.0f,0.0f);
glRotatef(day/30.0*360.0-day/360.0*360.0,0.0f,0.0f,-1.0f);
glTranslatef(38000000,0.0f,0.0f);
glutSolidSphere(4345000,20,20);
//glOrtho();
//gluOrtho2D(100,300,200,500); //正投影
//glFrustum();
//gluPerspective();//透视投影
//glViewport(100,100,400,800);//绘制到窗口的范围
//glPushMatrix();
//glPopMatrix();//保存,恢复矩阵。
glFlush();
glutSwapBuffers();//双缓冲,交换画板
}
void MyIdle(void)
{
++day;
if (day>=360)
{
day=0;
}
DrawNorth();
}
int main(int argc,char*argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);//双缓冲
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("宇宙,go !");
//glutDisplayFunc(&MyDisplay);
//glutDisplayFunc(&DisXing);
//glutDisplayFunc(&DisXian);
//glutDisplayFunc(&DisPolygon);
//glutDisplayFunc(&LouPolygon);
//glutDisplayFunc(&DisColor);
glutDisplayFunc(&DrawNorth);
glutIdleFunc(*MyIdle);
glutMainLoop();
return 0;
}
==============================================
/*
main
Copyright 2012 Thomas Dalling - http://tomdalling.com/
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "platform.hpp"
#include "SOIL.h"
// third-party libraries
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
// standard C++ libraries
#include <cassert>
#include <iostream>
#include <stdexcept>
#include <cmath>
// Shaders
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"layout (location = 1) in vec3 color;\n"
"layout (location = 2) in vec2 texCoord;\n"
"out vec3 ourColor;\n" // 向片段着色器输出一个颜色
"out vec2 TexCoord;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
"gl_Position = transform * vec4(position, 1.0f);\n"
"ourColor = color;\n"
"// TexCoord = texCoord;\n"
"TexCoord = vec2(1.0f - texCoord.x, 1.0f - texCoord.y);\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"in vec3 ourColor;\n"
"in vec2 TexCoord;\n"
"uniform sampler2D ourTexture1;\n" // 片段着色器也应该能访问纹理对象,但是我们怎样能把纹理对象传给片段着色器呢?GLSL有一个供纹理对象使用的内建数据类型,叫做采样器(Sampler),它以纹理类型作为后缀,比如sampler1D、sampler3D,或在我们的例子中的sampler2D。我们可以简单声明一个uniform sampler2D把一个纹理添加到片段着色器中,稍后我们会把纹理赋值给这个uniform。
"uniform sampler2D ourTexture2;\n"
"void main()\n"
"{\n"
"// color = vec4(ourColor, 1.0f);\n"
"// color = texture(ourTexture, TexCoord);\n"
"// color = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0f);\n"
"color = mix(texture(ourTexture1, TexCoord), texture(ourTexture2, TexCoord),0.2f);\n"
"}\n\0";
// constants
const glm::vec2 SCREEN_SIZE(500, 400);
// globals
GLFWwindow* gWindow = NULL;
// draws a single frame
static void Render() {
glClearColor(1, 0, 0, 1); // 设置清空屏幕所用的颜色。
glClear(GL_COLOR_BUFFER_BIT);// 清空屏幕的颜色缓冲
glfwSwapBuffers(gWindow);// 双缓冲
}
void OnError(int errorCode, const char* msg) {
throw std::runtime_error(msg);
}
// the program starts here
void AppMain() {
// initialise GLFW
glfwSetErrorCallback(OnError);
if(!glfwInit())
throw std::runtime_error("glfwInit failed");
// open a window with GLFW
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
gWindow = glfwCreateWindow((int)SCREEN_SIZE.x, (int)SCREEN_SIZE.y, "baseWindows", NULL, NULL);
if(!gWindow)
throw std::runtime_error("glfwCreateWindow failed. Can your hardware handle OpenGL 3.2?");
// GLFW settings
glfwMakeContextCurrent(gWindow);
// initialise GLEW
glewExperimental = GL_TRUE; //stops glew crashing on OSX :-/
if(glewInit() != GLEW_OK)
throw std::runtime_error("glewInit failed");
// print out some info about the graphics drivers
std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl;
std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;
// make sure OpenGL version 3.2 API is available
if(!GLEW_VERSION_3_2)
throw std::runtime_error("OpenGL 3.2 API is not available.");
// load vertex and fragment shaders into opengl
// LoadShaders();
// Build and compile our shader program
// Vertex shader
// =============SHARE ============
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// Check for compile time errors
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Check for compile time errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Link shaders
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// Check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// =============VAO===============
GLfloat vertices[] = {
// 0.5f, 0.5f, 0.0f, // Top Right
// 0.5f, -0.5f, 0.0f, // Bottom Right
// -0.5f, -0.5f, 0.0f, // Bottom Left
// -0.5f, 0.5f, 0.0f // Top Left
// ---- 位置 ---- ---- 颜色 ---- - 纹理坐标 -
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // 右上
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 左下
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上
};
GLuint indices[] = { // Note that we start from 0!
0, 1, 3, // First Triangle
1, 2, 3 // Second Triangle
};
// OpenGL抛弃glEnable(),glColor(),glVertex(),glEnable()这一套流程的函数和管线以后,
// 就需要一种新的方法来传递数据到Graphics Card来渲染几何体,我们可以用VBO,
// 在3+版本我们可以使用Vertex Array Object-VAO,VAO是一个对象,其中包含一个或者更多的Vertex Buffer Objects。
// 而VBO是Graphics Card中的一个内存缓冲区,用来保存顶点信息,颜色信息,法线信息,纹理坐标信息和索引信息等等。
// VAO在Graphics Card线性的存储几个对象信息,替代了以前发送我们需要的数据到Graphics Card上,
// 这也是Direct3D没有立即模式情况下工作的方法,这就意味着应用程序不需要传输数据到Graphics Card上而得到较高的性能。
GLuint VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);// 产生VAO
glGenBuffers(1, &VBO);// 产生VBOs
glGenBuffers(1, &EBO);// 产生EBOs
// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
glBindVertexArray(VAO);// 绑定VAO
glBindBuffer(GL_ARRAY_BUFFER, VBO);// 绑定VBOs
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 给VBO分配数据:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 位置属性
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);// 给对应的顶点属性数组指定数据:
glEnableVertexAttribArray(0);// 定义存放顶点属性数据的数组:
// 颜色属性
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3* sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT,GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind
glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO
// Load and create a texture
GLuint texture1;
GLuint texture2;
// ====================
// Texture 1
// ====================
// 和之前生成的OpenGL对象一样,纹理也是使用ID引用的。让我们来创建一个:
glGenTextures(1, &texture1); // 生成纹理的数量 1,然后把它们储存在第二个参数的GLuint数组中
glBindTexture(GL_TEXTURE_2D, texture1);
// 纹理坐标的范围通常是从(0, 0)到(1, 1),那如果我们把纹理坐标设置在范围之外会发生什么?
// OpenGL默认的行为是重复这个纹理图像(我们基本上忽略浮点纹理坐标的整数部分),但OpenGL提供了更多的选择:
// 环绕方式(Wrapping) 描述
// GL_REPEAT 对纹理的默认行为。重复纹理图像。
// GL_MIRRORED_REPEAT 和GL_REPEAT一样,但每次重复图片是镜像放置的。
// GL_CLAMP_TO_EDGE 纹理坐标会被约束在0到1之间,超出的部分会重复纹理坐标的边缘,产生一种边缘被拉伸的效果。
// GL_CLAMP_TO_BORDER 超出的坐标为用户指定的边缘颜色。
// 设置环绕方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Load, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture.
// ===================
// Texture 2
// ===================
// glGenTextures(1, &texture2);
// glBindTexture(GL_TEXTURE_2D, texture2);
// // Set our texture parameters
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// // Set texture filtering
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// // Load, create texture and generate mipmaps
// image = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
// glGenerateMipmap(GL_TEXTURE_2D);
// SOIL_free_image_data(image);
// glBindTexture(GL_TEXTURE_2D, 0);
// glm::mat4 trans;
// trans = glm::rotate(trans, 90.0f, glm::vec3(1.0, 0.0, 0.0));
// trans = glm::scale(trans, glm::vec3(1,2, 1));
// create buffer and fill it with the points of the triangle
// LoadTriangle();
// run while the window is open
GLfloat s = 0.1f;bool b2 = false;
while(!glfwWindowShouldClose(gWindow)){
// process pending events
glfwPollEvents();
// Render
// Clear the colorbuffer
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// glBindTexture(GL_TEXTURE_2D, texture);
// Draw our first triangle
glUseProgram(shaderProgram);
// Bind Textures using texture units
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glUniform1i(glGetUniformLocation(shaderProgram, "ourTexture1"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUniform1i(glGetUniformLocation(shaderProgram, "ourTexture2"), 1);
glm::mat4 trans;
GLint time = (GLint)(glfwGetTime()*100);
std::cout<< "rotate: "<<time<<std::endl;
time = (time %200+1)/100;
// trans = glm::rotate(trans,(GLfloat)glfwGetTime() * 5.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// trans = glm::translate(trans, glm::vec3(0.5f, -0.0f, 0.0f));
s += 0.01f;
if (s >= 2.0f) {
b2 = true;
}
if (b2) {
s-= 0.02f;
}
if (s<=0.01) {
b2 = false;
}
trans = glm::scale(trans, glm::vec3(s,s,1));
GLuint transformLoc = glGetUniformLocation(shaderProgram, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
glBindVertexArray(VAO);
// glDrawArrays(GL_TRIANGLES, 0, 6);
// glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glDrawElements(GL_TRIANGLES, 8, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
// 2
// glUseProgram(shaderProgram);
// GLfloat timeValue = glfwGetTime();
// GLfloat greenValue = (sin(timeValue) / 2) + 0.5;
// GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
// glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
// glBindVertexArray(VAO);
// glDrawArrays(GL_TRIANGLES, 0, 3);
// glBindVertexArray(0);
// Swap the screen buffers
glfwSwapBuffers(gWindow);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
// clean up and exit
glfwTerminate();
}
int main(int argc, char *argv[]) {
try {
glm::vec4 vec(1.0f, 0.0f, 0.0f, 1.0f);
glm::mat4 trans;
trans = glm::translate(trans, glm::vec3(1.0f, 1.0f, 0.0f));
vec = trans * vec;
std::cout << vec.x << vec.y << vec.z << std::endl;
AppMain();
} catch (const std::exception& e){
std::cerr << "ERROR: " << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}