// LearnOpengl.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <gl/glew.h>
#include <GL/freeglut.h>
#include "ShaderProgram.h"
#include "ShaderInfo.h"
ShaderProgram shader;
enum VAO_IDS { Trangles, Polygons, NumVAOs };
enum Buffer_IDs {VertexBuffer, InterpolationCoordBuffer, NumBuffers};
enum Attrib_IDs {
vPosition = 0,
vInterpolationCoords,
};
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
GLuint NumVertexs = 0;
float lineWidth = 0.5f;
float lineLength = 2.0f;
void init() {
glGenVertexArrays(NumVAOs, VAOs);
glBindVertexArray(VAOs[Trangles]);
ShaderInfo shaders[] = {
{GL_VERTEX_SHADER, "D:/opengl/learn/LearnOpengl/Debug/trangles.vert"},
{GL_FRAGMENT_SHADER, "D:/opengl/learn/LearnOpengl/Debug/fragment.frag"},
{GL_NONE, ""}
};
shader.loadShader(shaders);
float halfLineWidth = lineWidth * 0.5f;
float halfLineLength = lineLength * 0.5f;
GLfloat vertices[] = {
-halfLineLength, -halfLineWidth,
halfLineLength, -halfLineWidth,
halfLineLength, halfLineWidth,
-halfLineLength, -halfLineWidth,
halfLineLength, halfLineWidth,
-halfLineLength, halfLineWidth
};
GLfloat interpolationCoords[] = {
0.0, 0.0,
lineLength, 0.0,
lineLength, lineWidth,
0.0, 0.0,
lineLength, lineWidth,
0.0, lineWidth,
};
NumVertexs = sizeof(vertices) / sizeof(GLfloat) / 2;
glGenBuffers(NumBuffers, Buffers);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[VertexBuffer]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(vPosition);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[InterpolationCoordBuffer]);
glBufferData(GL_ARRAY_BUFFER, sizeof(interpolationCoords), interpolationCoords, GL_STATIC_DRAW);
glVertexAttribPointer(vInterpolationCoords, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(vInterpolationCoords);
}
void display() {
glClearColor(1.0f, 0.0f, 0.0f, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glUseProgram(shader.getShaderProgram());
glUniform1f(glGetUniformLocation(shader.getShaderProgram(), "lineWidth"), lineWidth);
glUniform1f(glGetUniformLocation(shader.getShaderProgram(),"lineLength"), lineLength);
glBindVertexArray(VAOs[Trangles]);
glDrawArraysInstanced(GL_TRIANGLES, 0, NumVertexs, 3);
glBindVertexArray(0);
glUseProgram(0);
glDisable(GL_BLEND);
glFlush();
}
int main(int argc, char *argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(512, 512);
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow(argv[0]);
if (glewInit() != GLEW_OK){
cerr << "Unable to initialize glew ... exiting"<<endl;
exit(EXIT_FAILURE);
}
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
//-------顶点shader---------------
#version 330 core
//#error __LINE_ "1234455";
layout(location = 0) in vec2 vPosition;
layout(location = 1) in vec2 vInterpolationCoord;
out vec2 interpolationCoord;
void main(){
float angle = 45.0f / 180.0f * 3.1415926;
mat2 mat = mat2(cos(angle), sin(angle), -sin(angle), cos(angle));
gl_Position = vec4(mat * vPosition, 0.0f, 1.0f);
interpolationCoord = vInterpolationCoord;
}
//-----------片元shader--------
#version 330 core
in vec2 interpolationCoord;
uniform float lineWidth;
uniform float lineLength;
//interpolationCoord中插值范围是【x:0~linewidth】【y:0~linelength】
void main(){
float halfLineWidth = lineWidth * 0.5f;
float fuzz = 0.005f;
//在前半宽范围之内
if(interpolationCoord.x < halfLineWidth){
float flen = halfLineWidth - interpolationCoord.x;
float f = sqrt(pow(flen, 2) + pow((interpolationCoord.y - halfLineWidth), 2));
if(f < halfLineWidth){
float alpha = clamp((f - (halfLineWidth - fuzz)) / fuzz, 0.0f, 1.0f);
gl_FragColor = vec4(0, 0, 0, 1.0f - alpha);
}
else
{
discard;
}
}
//后半宽范围之内
else if(interpolationCoord.x > (lineLength - halfLineWidth))
{
float flen = interpolationCoord.x - (lineLength - halfLineWidth);
float f = sqrt(pow(flen, 2) + pow((interpolationCoord.y - halfLineWidth), 2));
if(f < halfLineWidth){
float alpha = clamp((f - (halfLineWidth - fuzz)) / fuzz, 0.0f, 1.0f);
gl_FragColor = vec4(0, 0, 0, 1.0 - alpha);
}
else
{
discard;
}
}
//中间范围
else{
if(interpolationCoord.y > (lineWidth - fuzz)){
//上半部分
float alpha = clamp((interpolationCoord.y - (lineWidth - fuzz)) / fuzz, 0.0f, 1.0f);
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0-alpha);
}
else{
//下半部分
float alpha = clamp((fuzz - interpolationCoord.y) / fuzz, 0.0f, 1.0f);
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0-alpha);
}
}
}