-OPENGL 2-
Read OIIO->Qt QImage
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import sys,os import OpenImageIO as oiio from PySide2 import QtWidgets,QtCore,QtGui import numpy as np if __name__ == "__main__": img_input = oiio.ImageInput.open('timg.jpg') img_spec = img_input.spec() nchans = img_spec.nchannels # JPG is 3 / PNG is 4 width = img_spec.width height = img_spec.height print("img width:%s,height:%s"%(width,height)) #pixels = [] pixels = img_input.read_image(oiio.UINT8) pixels = pixels.flatten() print(len(pixels) ) print(width*height*nchans) app = QtWidgets.QApplication(sys.argv) qtimg = QtGui.QImage(pixels,width,height,QtGui.QImage.Format_RGB888) # CREATGE QT IMAGE #qtimg.save('test.jpg') print('Create Pixmap') qtimg = QtGui.QPixmap.fromImage(qtimg) label = QtWidgets.QLabel() label.resize(500,500) label.setPixmap(qtimg) label.show() app.exec_()
GL测试全部由CMakeLists负责构建:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
cmake_minimum_required(VERSION 3.5) project(Triangle) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # OPENGL find_package(OpenGL REQUIRED) include_directories(${OpenGL_INCLUDE_DIRS}) link_directories(${OpenGL_LIBRARY_DIRS}) add_definitions(${OpenGL_DEFINITIONS}) if(NOT OPENGL_FOUND) message(ERROR " OPENGL not found!") endif(NOT OPENGL_FOUND) # GLEW set(GLEW_HOME D:/plugin_dev/libs/glew-2.1.0) include_directories(${GLEW_HOME}/include) link_directories(${GLEW_HOME}/lib/Release/x64) # GLFW set(GLFW_HOME D:/plugin_dev/libs/glfw-3.3.1.bin.WIN64) include_directories(${GLFW_HOME}/include/) link_directories(${GLFW_HOME}/lib-vc2019) # output excutable dir set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) add_executable(Triangle main.cpp LoadShader.h) target_link_libraries(Triangle glew32s glfw3 opengl32)
CP01:
MODERN OGL Triangle
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> using namespace std; const int NPTS = 3; GLuint VBO,VAO; // Shaders const GLchar* vertexShaderSource = "#version 450 core\n" "layout (location = 0) in vec4 vPosition;\n" "void main()\n" "{\n" "gl_Position = vPosition;\n" "}\0"; const GLchar* fragmentShaderSource = "#version 450 core\n" "out vec4 fColor;\n" "void main()\n" "{\n" "fColor = vec4(0.6,0,0.3,1);\n" "}\n\0"; void init(){ static const GLfloat verticles[NPTS][3] = { {-0.5f, -0.5f, 0.0f}, {0.5f, -0.5f, 0.0f}, {0.0f, 0.5f, 0.0f} }; // Vertex shader GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER ); glShaderSource( vertexShader, 1, &vertexShaderSource, NULL ); glCompileShader( vertexShader ); 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 ); 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; } glUseProgram(shaderProgram); glDeleteShader( vertexShader ); glDeleteShader( fragmentShader ); glCreateBuffers(1,&VBO); glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 ); glBindBuffer(GL_ARRAY_BUFFER,VBO); glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,0, 0 ); glEnableVertexAttribArray(0); cout << "VAO:" << VAO << endl; cout << "VBO:" << VBO << endl; } void display(){ static const float black[] = {0.0f,0.0f,0.0f,0.0f}; glClearBufferfv(GL_COLOR,0,black); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES,0 ,NPTS); } int main() { glfwInit(); GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL); glfwMakeContextCurrent(window); glewInit(); init(); while(!glfwWindowShouldClose(window)){ display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; }
CP02:
>>使用P位置着色
Attrib不变,点位置也不变
// position Attrib glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,0, 0 ); glEnableVertexAttribArray(0);
.vert .frag的source变化:
// Shaders const GLchar* vertexShaderSource = "#version 450 core\n" "layout (location = 0) in vec4 vPosition;\n" "layout (location = 0) in vec4 vColor;\n" "out vec4 ourColor;\n" "void main()\n" "{\n" "gl_Position = vPosition;\n" "ourColor = vColor;\n" "}\0"; const GLchar* fragmentShaderSource = "#version 450 core\n" "in vec4 ourColor;\n" "out vec4 fColor;\n" "void main()\n" "{\n" "fColor = ourColor;\n" "}\n\0";
CP03:
>>属性创建1:
创建Position属性:
// position Attrib glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,0, 0 ); glEnableVertexAttribArray(0);
函数原型是这个:
glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr)
第一个参数:着色器需要这个变量的location值
第二个参数:每个顶点的元素数目,如果是上面的,则是3
第三个参数:数据类型,GL_FLOAT
第四个参数:是不是要normalize,这里是position类型的数据,则是GL_FALSE
第五个参数:stride,等于0,则是数据“紧密链接”
第六个参数:偏移bytes,这里数据不许用指定offset。 所以写(void*)0
---------------------------------------------------------------------------------------------------------------------
>>属性创建2:
创建2个location,一个是为了gl_Position,一个为了自定义颜色
// position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // color attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float))); glEnableVertexAttribArray(1);
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> using namespace std; const int NPTS = 3; GLuint VBO,VAO; // Shaders const GLchar* vertexShaderSource = "#version 450 core\n" "layout (location = 0) in vec4 vPosition;\n" "layout (location = 1) in vec4 vColor;\n" "out vec4 ourColor;\n" "void main()\n" "{\n" "gl_Position = vPosition;\n" "ourColor = vColor;\n" "}\0"; const GLchar* fragmentShaderSource = "#version 450 core\n" "in vec4 ourColor;\n" "out vec4 fColor;\n" "void main()\n" "{\n" "fColor = ourColor;\n" "}\n\0"; void init(){ static const GLfloat verticles[NPTS][6] = { { 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f }, { -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f } }; // Vertex shader GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER ); glShaderSource( vertexShader, 1, &vertexShaderSource, NULL ); glCompileShader( vertexShader ); 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 ); 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; } // Use shader program glUseProgram(shaderProgram); glDeleteShader( vertexShader ); glDeleteShader( fragmentShader ); glCreateBuffers(1,&VBO); glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 ); glBindBuffer(GL_ARRAY_BUFFER,VBO); glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // position Attrib glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)0 ); glEnableVertexAttribArray(0); // color Attrib glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)(3* sizeof(float)) ); glEnableVertexAttribArray(1); cout << "VAO:" << VAO << endl; cout << "VBO:" << VBO << endl; } void display(){ static const float black[] = {0.0f,0.0f,0.0f,0.0f}; glClearBufferfv(GL_COLOR,0,black); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES,0 ,NPTS); } int main() { glfwInit(); GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL); glfwMakeContextCurrent(window); glewInit(); init(); while(!glfwWindowShouldClose(window)){ display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; }
CP04:
将读取材质加载到另外一个头文件中。
将材质vert和frag分离
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#version 450 core layout ( location = 0 ) in vec4 vPosition; layout ( location = 1 ) in vec4 vColor; out vec4 ourColor; void main(){ gl_Position = vPosition; ourColor = vColor; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#version 450 core out vec4 fColor; in vec4 ourColor; void main(){ fColor = ourColor; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#ifndef LOADSHADER_H #define LOADSHADER_H #include <GL/glew.h> #include <iostream> #include <fstream> #include <string> #include <sstream> using namespace std; struct LoadShader { LoadShader(const char*vertPath, const char* fragPath){ load(vertPath,fragPath); } string _readFile(const char *path){ ifstream stream; stringstream ss; stream.exceptions(ifstream::badbit); try { stream.open(path); // open file ss << stream.rdbuf(); // get strings from file } catch (ifstream::failure e) { cout << "ERROR::OPEN FILE:" << path << endl; } // close file handle stream.close(); // get str() from stringstream string shaderCode = ss.str(); return shaderCode; } void _loadVertexShader(const char *path){ // read shader code auto handle = _readFile(path); const char * shaderCode = handle.c_str(); // Vertex shader vertexShader = glCreateShader( GL_VERTEX_SHADER ); glShaderSource( vertexShader, 1, &shaderCode, NULL ); glCompileShader( vertexShader ); 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; } } void _loadFragmentShader(const char *path){ // read shader code auto handle = _readFile(path); const char * shaderCode = handle.c_str(); // Vertex shader fragmentShader = glCreateShader( GL_FRAGMENT_SHADER ); glShaderSource( fragmentShader, 1, &shaderCode, NULL ); glCompileShader( fragmentShader ); GLint success; GLchar infoLog[512]; glGetShaderiv( fragmentShader, GL_COMPILE_STATUS, &success ); // Get Compile status if ( !success ) { glGetShaderInfoLog( fragmentShader, 512, NULL, infoLog ); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } } void load(const char* vertShaderPath, const char* fragShaderPath){ _loadVertexShader(vertShaderPath); _loadFragmentShader(fragShaderPath); // create shader program and check it GLint success; GLchar infoLog[512]; shaderProgram = glCreateProgram(); glAttachShader(shaderProgram,vertexShader); glAttachShader(shaderProgram,fragmentShader); glLinkProgram(shaderProgram ); glGetProgramiv( shaderProgram, GL_LINK_STATUS, &success ); // Get Link Status if (!success) { glGetProgramInfoLog( shaderProgram, 512, NULL, infoLog ); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } // Delete the shaders as they're linked into our program now and no longer necessery glDeleteShader( vertexShader ); glDeleteShader( fragmentShader ); } void use(){ glUseProgram(shaderProgram); } GLuint shaderProgram; GLuint vertexShader; GLuint fragmentShader; }; #endif // LOADSHADER_H
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" using namespace std; const int NPTS = 3; static GLuint VBO,VAO; void init(){ static const GLfloat verticles[NPTS][6] = { { 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f }, { -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f } }; LoadShader shader("shader.vert","shader.frag"); shader.use(); glCreateBuffers(1,&VBO); glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 ); glBindBuffer(GL_ARRAY_BUFFER,VBO); glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // position Attrib glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)0 ); glEnableVertexAttribArray(0); // color Attrib glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)(3* sizeof(float)) ); glEnableVertexAttribArray(1); cout << "VAO:" << VAO << endl; cout << "VBO:" << VBO << endl; } void display(){ static const float black[] = {0.0f,0.0f,0.0f,0.0f}; glClearBufferfv(GL_COLOR,0,black); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES,0 ,NPTS); } int main() { glfwInit(); GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL); glfwMakeContextCurrent(window); glewInit(); init(); while(!glfwWindowShouldClose(window)){ display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; }
CP05:
Uniform的作用。当前感觉是可以直接在UI->C++->GLSL
在C++中设置frag的uniform 变量值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#version 450 core out vec4 fColor; // out to our fragment shader color in vec4 ourColor; // from the vertex shader src uniform vec4 cpp_color; // from c++ src void main(){ fColor = cpp_color; }
Now that we know how to set the values of uniform variables, we can use them for rendering. If we want the color to gradually change, we want to update this uniform every frame, otherwise the triangle would maintain a single solid color if we only set it once. So we calculate the greenValue and update the uniform each render iteration:
接下来就是在每帧刷新:
void display(){ static const float black[] = {0.0f,0.0f,0.0f,0.0f}; glClearBufferfv(GL_COLOR,0,black); // get the location of uniform color in shader.frag int cpp_color_location = glGetUniformLocation(shader.shaderProgram,"cpp_color"); float timeValue = glfwGetTime(); float greenValue = sin(timeValue*2) / 2.0f + 0.5f; // set uniform value glUniform4f(cpp_color_location, 0.0f, greenValue, 0.0f, 1.0f); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES,0 ,NPTS); }
如果在shader.vert里这样写,可以看到三角形上下飞。
#version 450 core layout ( location = 0 ) in vec4 vPosition; layout ( location = 1 ) in vec4 vColor; uniform vec4 cpp_color; // from c++ src out vec4 ourColor; void main(){ gl_Position = vPosition + cpp_color; ourColor = vColor; }
CP06:
uniform 块的使用
相关过程:
1,通过glGetUniformBlockIndex()获取uniform块的索引值
2,获取uniform块的大小glGetActiveUniformBlockiv(),目的是为了C++客户端的要修改的 (GLvoid *buffer)开辟正确的内存。
3,通过glGetUniformIndices()根据所有的glsl中uniform中的每个变量名称(在C++可能要const char * name[num_uniforms])的索引值
4,根据这些索引值可以得到uniform块中每个变量所占用的内存大小,类型,内存偏移值
5,把准备好的数据复制到(GLvoid *buffer)中
6,建立uniform缓存对象,初始化内容,与着色器关联。通过glCreateBuffers(),glBindBuffer(),glBufferData(),glBindBufferBase()函数完成。
我按照书中的示例做了个简单的测试,结果发现根本TM的就在现代C++编译器无法跑过去,尼玛的void* + int? 用来偏移内存这么玩的吗?VS2019 表示完全无法通过。
但是如果前期的编译器要是能编译这个,我觉得void*请牛逼的,可以指向任意各种内存”区域“,带上正确的offset完全可以实现正确的访问。
先看书中的示例:
最后一幅图里的代码根本无法编译,可能C语言编译器能编译?memcpy不带这么玩的。
针对这个问题,我想了下由于是内存不带offset的,我直接用个透明的结构体不就解决了,果然:
Fragment:
#version 450 core out vec4 fColor; // out to our fragment shader color in vec4 ourColor; // from the vertex shader src uniform Block{ vec4 cpp_color; float cpp_ypos; }; void main(){ fColor = cpp_color; }
Vertex:
#version 450 core layout ( location = 0 ) in vec4 vPosition; //layout ( location = 1 ) in vec4 vColor; // from c++ attribute transfer // out vec4 ourColor; No longer used,just for test uniform Block{ vec4 cpp_color; float cpp_ypos; }; void main(){ gl_Position = vPosition + vec4(0.0f,cpp_ypos, 0.0f,0.0f); }
main.cpp:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" using namespace std; const int NPTS = 3; static GLuint VBO,VAO; // load shader static LoadShader shader; struct UData{ float color[4]; float inc_ypos; }; void init(){ static const GLfloat verticles[NPTS][6] = { { 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f }, { -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f } }; shader.load("shader.vert","shader.frag"); shader.use(); glCreateBuffers(1,&VBO); glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 ); glBindBuffer(GL_ARRAY_BUFFER,VBO); glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // position Attrib glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)0 ); glEnableVertexAttribArray(0); // color Attrib glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)(3* sizeof(float)) ); glEnableVertexAttribArray(1); cout << "VAO:" << VAO << endl; cout << "VBO:" << VBO << endl; } void display(){ static const float black[] = {0.0f,0.0f,0.0f,0.0f}; glClearBufferfv(GL_COLOR,0,black); glUseProgram(shader.shaderProgram); // Get Uniform Block index GLuint uniform_block_index; uniform_block_index = glGetUniformBlockIndex(shader.shaderProgram, "Block"); //cout << "shader program:" << shader.shaderProgram <<endl; //cout <<"Block id x:" <<uniform_block_index <<endl; // Get Uniform Block Mem Size GLint uniform_block_size; glGetActiveUniformBlockiv(shader.shaderProgram, uniform_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &uniform_block_size); //cout << "Block Size:" << uniform_block_size <<endl; // We Just have two variable in our "vars" uniform block const GLuint var_count = 2; // static write our per variable name const char *var_names[var_count] = {"cpp_color","cpp_ypos"}; // Get uniform per variable index GLuint indices[var_count]; glGetUniformIndices(shader.shaderProgram, var_count, var_names,indices); // Get Block per var index // Get Uniform per variable data size GLint var_sizes[var_count]; glGetActiveUniformsiv(shader.shaderProgram, var_count, indices, GL_UNIFORM_SIZE, var_sizes); // Get uniform per variable data offset GLint var_offsets[var_count]; glGetActiveUniformsiv(shader.shaderProgram, var_count, indices, GL_UNIFORM_OFFSET, var_offsets); // Get uniform per variable data type GLint var_types[var_count]; glGetActiveUniformsiv(shader.shaderProgram, var_count, indices, GL_UNIFORM_TYPE, var_types); // Create buffer object GLuint uniform_buffers_index; glCreateBuffers(1, &uniform_buffers_index); glBindBuffer(GL_UNIFORM_BUFFER, uniform_buffers_index); // this value for y pos offset float timeValue = glfwGetTime(); float greenValue = sin(timeValue*2) / 2.0f + 0.5f; UData data; data.inc_ypos = greenValue; data.color[0] = 0.0f; data.color[1] = 0.0f; data.color[2] = 1.0f; data.color[3] = 1.0f; //cout << "sizeof data:" << sizeof(data) <<endl; glNamedBufferStorage(uniform_buffers_index, sizeof(data), &data, 0); //glBufferStorage(GL_UNIFORM_BUFFER,sizeof(data), &data, 0); // SAME AS ABOVE //glBufferData(GL_UNIFORM_BUFFER,sizeof(data), &data, GL_STATIC_DRAW); // SAME AS ABOVE //glNamedBufferData(uniform_buffers_index, sizeof(data), &data, GL_STATIC_DRAW); // SAME AS ABOVE // bind to our block glBindBufferBase(GL_UNIFORM_BUFFER, uniform_block_index, uniform_buffers_index); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES,0 ,NPTS); } int main() { cout << sizeof(float) <<endl; glfwInit(); GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL); glfwMakeContextCurrent(window); glewInit(); init(); while(!glfwWindowShouldClose(window)){ display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; }
结果发现用结构体是最简单访问形式。前提主要内存是要对齐:
如图三角形按照y偏移,颜色为蓝色。都是C++预先设置好的。
>>1,顺便到这里发现了一点,这俩函数完全一个东西。
glNamedBufferStorage(uniform_buffers_index, sizeof(data), &data, 0); glBufferStorage(GL_UNIFORM_BUFFER,sizeof(data), &data, 0);
glBufferStorage, glNamedBufferStorage — creates and initializes a buffer object's immutable data store
>>2,顺便到这里发现了一点,这俩函数完全一个东西。
glBufferData(GL_UNIFORM_BUFFER,sizeof(data), &data, GL_STATIC_DRAW); glNamedBufferData(uniform_buffers_index, sizeof(data), &data, GL_STATIC_DRAW);
CP07:
贴图部分,看了整篇文章,第一个案例讲解一个贴图,在fragment shader里有个uniform sampler2d类型的。
#version 330 core out vec4 FragColor; in vec3 ourColor; in vec2 TexCoord; uniform sampler2D ourTexture; void main() { FragColor = texture(ourTexture, TexCoord); }
但是在他的源码里没见用glUniform*设置这个值。
作者介绍了这个原因是由于Texture Unit,默认的一个贴图location 永远是=0
------------------------------------------------------------
参考原文:
https://learnopengl.com/Getting-started/Textures
一个贴图时候的源代码:
https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.1.textures/textures.cpp
有多个贴图时候的源代码:
--------------------------------------------------------------
>> 一个贴图物体如何创建,还有没按照官方的方法绘制,同样是个正方形,我用的 glDrawArrays(GL_QUADS,0 ,NPTS); 直接绘制了。
这个是一个贴图物体创建的源代码:
进入正篇,在这里我测试了两种shader方法都是可以的(opengl编程指南第二章介绍的);
先来看材质:
shader.vert:
#version 450 core layout ( location = 0 ) in vec4 vPosition; // c++ pos layout ( location = 1 ) in vec4 vColor; // c++ attribute color layout ( location = 2 ) in vec2 vTexCoord; // c++ attribute st //out vec4 ourColor; // OUT TO OUR ->fragment //out vec2 ourTexCoord; // OUT TO OUR ->fragment out block{ vec4 ourColor; vec2 ourTexCoord; }; void main(){ gl_Position = vPosition; ourColor = vColor; ourTexCoord = vTexCoord; }
shader.frag:
#version 450 core out vec4 fColor; // out to our fragment shader color //in vec4 ourColor; // from the vertex shader src //in vec2 ourTexCoord; in block{ vec4 ourColor; vec2 ourTexCoord; }; uniform sampler2D texture1; void main(){ fColor = texture(texture1, ourTexCoord); }
可以看到使用in/out块的方法制作材质。
C++ SRC:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "LoadShader.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> using namespace std; const int NPTS = 4; static GLuint VBO,VAO; // load shader static LoadShader shader; // Texture static GLuint texture; void init(){ static const GLfloat verticles[NPTS][8] = { // positions // colors // texture coords {0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f}, // top right {0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f}, // bottom right {-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, // bottom left {-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f} // top left }; shader.load("shader.vert","shader.frag"); shader.use(); glCreateBuffers(1,&VBO); glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 ); glBindBuffer(GL_ARRAY_BUFFER,VBO); glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // position Attrib glVertexAttribPointer(0, // LOCATION 3, // vector is 3 length GL_FLOAT, // float type GL_FALSE, // not normalized 8 * sizeof(float), // stride (void*)0 ); // offset glEnableVertexAttribArray(0); // color Attrib glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(3* sizeof(float)) ); glEnableVertexAttribArray(1); // st Attrib glVertexAttribPointer(2,2, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(6* sizeof(float)) ); glEnableVertexAttribArray(2); //glGenTextures(1,&texture); glCreateTextures(GL_TEXTURE_2D, 1, &texture); // same as above method glBindTexture(GL_TEXTURE_2D, texture); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // same as above methods glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_REPEAT); glTextureParameteri(texture, GL_TEXTURE_WRAP_T, GL_REPEAT); glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // load imag int width,height,nchans; unsigned char *data = stbi_load("texture_02.jpg",&width, &height, &nchans, 0); cout << "WIDTH:" << width << "HEIGHT:" <<height <<endl; if(data){ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width,height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateTextureMipmap(texture); } else{ cout << "Load texture error" <<endl; } stbi_image_free(data); } void display(){ static const float black[] = {0.2f, 0.3f, 0.3f, 1.0f}; glClearBufferfv(GL_COLOR,0,black); //glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //glClear(GL_COLOR_BUFFER_BIT); //glBindTexture(GL_TEXTURE_2D, texture); glBindVertexArray(VAO); glDrawArrays(GL_QUADS,0 ,NPTS); } int main() { cout << sizeof(float) <<endl; glfwInit(); GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL); glfwMakeContextCurrent(window); glewInit(); init(); while(!glfwWindowShouldClose(window)){ display(); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); return 0; }
一个贴图的套路就是:
glCreateTextures()-> glBindTexture() -> glTexParameteri() -> glTexImage2D() -> glGenerateTextureMipmap()
参考:
https://learnopengl.com/Getting-started/Shaders
https://github.com/SonarSystems/Modern-OpenGL-Tutorials
https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.1.textures/textures.cpp