吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2228|回复: 3
收起左侧

[C&C++ 原创] GL着色器实现自己的64kb编程

  [复制链接]
mochifz 发表于 2025-1-8 03:58
本帖最后由 mochifz 于 2025-1-10 00:20 编辑

更新日记
1、修改ENABLE_FILE宏启用读取着色器
2、修改ENABLE_MESSAGEBOX宏启用消息框显示错误
3、修改DISABLE_VERTICAL_SYNC宏禁用垂直同步
4、添加ENABLE_PRINT_FPS宏启用控制台打印
[Patch] 纯文本查看 复制代码
--- screen.c
+++ screen1.c
@@ -1,5 +1,10 @@
-//tcc screen.c -lGDI32 -lOPENGL32 -lUSER32 -run
-#define UNICODE 1
+//tcc -DUNICODE -DENABLE_FILE -DENABLE_MESSAGEBOX -DDISABLE_VERTICAL_SYNC -DENABLE_PRINT_FPS screen.c -lGDI32 -lOPENGL32 -lUSER32
+/*
+	1、修改ENABLE_FILE宏启用读取着色器
+	2、修改ENABLE_MESSAGEBOX宏启用消息框显示错误
+	3、修改DISABLE_VERTICAL_SYNC宏禁用垂直同步
+	4、添加ENABLE_PRINT_FPS宏启用控制台打印
+*/
 #include <windows.h>
 #include <GL/gl.h>
 #include <stdio.h>
@@ -44,12 +49,14 @@
 		PFNGLSHADERSOURCEPROC ShaderSource;
 		PFNGLCOMPILESHADERPROC CompileShader;
 		PFNGLGETSHADERIVPROC GetShaderiv;
+#ifdef ENABLE_MESSAGEBOX
 		PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
+		PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
+#endif
 		PFNGLCREATEPROGRAMPROC CreateProgram;
 		PFNGLATTACHSHADERPROC AttachShader;
 		PFNGLLINKPROGRAMPROC LinkProgram;
 		PFNGLGETPROGRAMIVPROC GetProgramiv;
-		PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
 		PFNGLUSEPROGRAMPROC UseProgram;
 		PFNGLDELETESHADERPROC DeleteShader;
 		PFNGLGENVERTEXARRAYSPROC GenVertexArrays;
@@ -60,19 +67,23 @@
 		PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
 		PFNGLUNIFORM2FVPROC Uniform2fv;
 		PFNGLUNIFORM1FPROC Uniform1f;
+#ifdef DISABLE_VERTICAL_SYNC
 		PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+#endif
 	};
 } gl;
 #define glCreateShader gl.CreateShader
 #define glShaderSource gl.ShaderSource
 #define glCompileShader gl.CompileShader
 #define glGetShaderiv gl.GetShaderiv
-#define glGetShaderInfoLog gl.GetShaderInfoLog
+#ifdef ENABLE_MESSAGEBOX
+	#define glGetShaderInfoLog gl.GetShaderInfoLog
+	#define glGetProgramInfoLog gl.GetProgramInfoLog
+#endif
 #define glCreateProgram gl.CreateProgram
 #define glAttachShader gl.AttachShader
 #define glLinkProgram gl.LinkProgram
 #define glGetProgramiv gl.GetProgramiv
-#define glGetProgramInfoLog gl.GetProgramInfoLog
 #define glUseProgram gl.UseProgram
 #define glDeleteShader gl.DeleteShader
 #define glGenVertexArrays gl.GenVertexArrays
@@ -83,13 +94,24 @@
 #define glGetUniformLocation gl.GetUniformLocation
 #define glUniform2fv gl.Uniform2fv
 #define glUniform1f gl.Uniform1f
-char* names[] = {"glCreateShader", "glShaderSource", "glCompileShader", "glGetShaderiv", "glGetShaderInfoLog", "glCreateProgram", "glAttachShader", "glLinkProgram", "glGetProgramiv", "glGetProgramInfoLog", "glUseProgram", "glDeleteShader", "glGenVertexArrays", "glBindVertexArray", "glDeleteProgram", "glDeleteVertexArrays", "glDeleteBuffers", "glGetUniformLocation", "glUniform2fv", "glUniform1f", "wglSwapIntervalEXT"};
+char* names[] = {"glCreateShader", "glShaderSource", "glCompileShader", "glGetShaderiv",
+#ifdef ENABLE_MESSAGEBOX
+				 "glGetShaderInfoLog",
+				 "glGetProgramInfoLog",
+#endif
+				 "glCreateProgram", "glAttachShader", "glLinkProgram", "glGetProgramiv", "glUseProgram", "glDeleteShader", "glGenVertexArrays", "glBindVertexArray", "glDeleteProgram", "glDeleteVertexArrays", "glDeleteBuffers", "glGetUniformLocation", "glUniform2fv", "glUniform1f",
+#ifdef DISABLE_VERTICAL_SYNC
+				 "wglSwapIntervalEXT"
+#endif
+				};
 GLuint shaderProgram;
 GLint iFrame, iFrameRate, iTime, iResolution, iMouse;
 GLuint vertexArray;
-GLfloat Time = 0, Resolution[2], Mouse[2];
+GLfloat Resolution[2], Mouse[2];
 const char* vertexShaderSource = "vec2 positions[4] = vec2[4] (vec2 (-1.0, 1.0),vec2 (-1.0, -1.0),vec2 (1.0, 1.0),vec2 (1.0, -1.0));void main() {gl_Position = vec4 (positions[gl_VertexID % 4], 0.0, 1.0);}";
-char* buffer = NULL;
+#ifdef ENABLE_FILE
+	char* buffer = NULL;
+#endif
 char* fragmentShaderSource = "uniform float iTime;uniform vec2 iResolution;uniform vec2 iMouse;void mainImage( out vec4 fragColor, in vec2 fragCoord ){vec2 uv = fragCoord.xy / iResolution;vec2 mousePos = iMouse.xy / iResolution.xy;if (length(uv - mousePos) < 0.01){fragColor = vec4(sin(iTime + uv.x * 10.0) * 0.5 + 0.5, 0.0, 0.0, 1.0);}else{fragColor = vec4(uv.x, uv.y, 0.0, 1.0);}}void main() {mainImage(gl_FragColor, gl_FragCoord.xy);}";
 void CompileShader (const char* source, GLenum shaderType, GLuint* shader) {
 	*shader = glCreateShader (shaderType);
@@ -97,29 +119,32 @@
 	glCompileShader (*shader);
 	GLint success;
 	glGetShaderiv (*shader, GL_COMPILE_STATUS, &success);
+#ifdef ENABLE_MESSAGEBOX
 	if (!success) {
 		char infoLog[512];
 		glGetShaderInfoLog (*shader, 512, NULL, infoLog);
 		MessageBoxA (NULL, infoLog, "Shader Compilation Error", MB_OK | MB_ICONERROR);
 	}
+#endif
 }
 int quit = 0;
-LARGE_INTEGER frequency;
-LARGE_INTEGER lastTime;
-LARGE_INTEGER currentTime;
 void InitOpenGL() {
 	for (int i = 0; i < ARRAY_SIZE (names); i++) {
 		gl.ptr[i] = wglGetProcAddress (names[i]);
 		if (!gl.ptr[i]) {
 			quit = 1;
+#ifdef ENABLE_MESSAGEBOX
 			MessageBoxA (NULL, "Failed to get OpenGL function pointers!", "Error", MB_OK | MB_ICONERROR);
+#endif
 			return;
 		}
 	}
-	//gl.wglSwapIntervalEXT(0);
-	glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
+#ifdef DISABLE_VERTICAL_SYNC
+	gl.wglSwapIntervalEXT (0);
+#endif
 	GLuint vertexShader, fragmentShader;
 	CompileShader (vertexShaderSource, GL_VERTEX_SHADER, &vertexShader);
+#ifdef ENABLE_FILE
 	LPSTR cmdLine = GetCommandLineA();
 	char* firstArgument = NULL;
 	char* spacePos = strchr (cmdLine, ' ');
@@ -134,7 +159,9 @@
 		FILE* file = fopen (firstArgument, "r");
 		if (file == NULL) {
 			quit = 1;
+#ifdef ENABLE_MESSAGEBOX
 			MessageBoxA (NULL, "Can't open the file!", "Error", MB_OK | MB_ICONERROR);
+#endif
 			return;
 		}
 		fseek (file, 0, SEEK_END);
@@ -146,6 +173,7 @@
 		fclose (file);
 		fragmentShaderSource = buffer;
 	}
+#endif
 	CompileShader (fragmentShaderSource, GL_FRAGMENT_SHADER, &fragmentShader);
 	shaderProgram = glCreateProgram();
 	glAttachShader (shaderProgram, vertexShader);
@@ -154,9 +182,11 @@
 	GLint success;
 	glGetProgramiv (shaderProgram, GL_LINK_STATUS, &success);
 	if (!success) {
+#ifdef ENABLE_MESSAGEBOX
 		char infoLog[512];
 		glGetProgramInfoLog (shaderProgram, 512, NULL, infoLog);
 		MessageBoxA (NULL, infoLog, "Shader Linking Error", MB_OK | MB_ICONERROR);
+#endif
 		quit = 1;
 		return;
 	}
@@ -170,34 +200,46 @@
 	glDeleteShader (fragmentShader);
 	glGenVertexArrays (1, &vertexArray);
 	glBindVertexArray (vertexArray);
-	QueryPerformanceFrequency (&frequency);
-	QueryPerformanceCounter (&lastTime);
 }
 void RenderScene() {
-	QueryPerformanceCounter (&currentTime);
-	static int FrameRate = 0, Frame = 0;
-	static float elapsedTime = 0.0f;
-	QueryPerformanceCounter (&currentTime);
-	elapsedTime += (float) (currentTime.QuadPart - lastTime.QuadPart) / (float) frequency.QuadPart;
-	FrameRate++;
+	static int Frame = 0;
+	static float FrameRate = 0;
+	static float maxFPS = 0.0f;
+	static float minFPS = 9999999999999.0f;
 	Frame++;
-	glUniform1f (iFrame, (float) Frame);
-	if (elapsedTime >= 1.0f) {
-		glUniform1f (iFrameRate, (float) FrameRate);
-		FrameRate = 0;
-		elapsedTime = 0.0f;
-		Time++;
+	static int initNow = 0;
+	static int lastNow = 0;
+	LARGE_INTEGER counter;
+	QueryPerformanceCounter (&counter);
+	int now = counter.QuadPart;
+	if (initNow == 0)
+		initNow = now;
+	now -= initNow;
+	if (lastNow == 0)
+		lastNow = now;
+	if (now - lastNow > 10000000) {
+		FrameRate = (float) Frame / ( (float) now / 10000000.0f);
+		glUniform1f (iFrameRate, FrameRate);
+		lastNow = now;
+#ifdef ENABLE_PRINT_FPS
+		if (FrameRate > maxFPS)
+			maxFPS = FrameRate;
+		if (FrameRate < minFPS)
+			minFPS = FrameRate;
+		printf ("Time: %.2f, Frame: %ld, FPS: %.2f, Max FPS: %.2f, Min FPS: %.2f\n", now / 10000000.0f, Frame, FrameRate, maxFPS, minFPS);
+#endif
 	}
-	lastTime = currentTime;
-	glUniform1f (iTime, Time + elapsedTime);
+	glUniform1f (iFrame, (float) Frame);
+	glUniform1f (iTime, (float) now / 10000000.0f);
 	glUniform2fv (iResolution, 1, &Resolution[0]);
 	glUniform2fv (iMouse, 1, &Mouse[0]);
-	glClear (GL_COLOR_BUFFER_BIT);
 	glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
 }
 void QuitOpenGL() {
+#ifdef ENABLE_FILE
 	if (buffer)
 		free (buffer);
+#endif
 	glDeleteProgram (shaderProgram);
 	glDeleteVertexArrays (1, &vertexArray);
 }
@@ -228,11 +270,16 @@
 	return 0;
 }
 #define ClassName TEXT("GL")
+#if ENABLE_PRINT_FPS
+int main() {
+	HINSTANCE hInstance = NULL;
+#else
 #ifdef UNICODE
 int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
 #else
 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) {
 #endif
+#endif
 	int screenWidth = GetSystemMetrics (SM_CXSCREEN);
 	int screenHeight = GetSystemMetrics (SM_CYSCREEN);
 	WNDCLASS wc = {0};
@@ -241,12 +288,16 @@
 	wc.lpszClassName = ClassName;
 	wc.hCursor = LoadCursor (NULL, IDC_ARROW);
 	if (!RegisterClass (&wc)) {
+#ifdef ENABLE_MESSAGEBOX
 		MessageBoxA (NULL, "Window Registration Failed!", "Error", MB_ICONEXCLAMATION | MB_OK);
+#endif
 		return 0;
 	}
 	HWND hwnd = CreateWindowEx (WS_EX_APPWINDOW, ClassName, ClassName, WS_POPUP, 0, 0, screenWidth, screenHeight, NULL, NULL, wc.hInstance, NULL);
 	if (!hwnd) {
+#ifdef ENABLE_MESSAGEBOX
 		MessageBoxA (NULL, "Window Creation Failed!", "Error", MB_ICONEXCLAMATION | MB_OK);
+#endif
 		return 0;
 	}
 	PIXELFORMATDESCRIPTOR pfd = {
@@ -278,7 +329,6 @@
 	wglMakeCurrent (hdc, NULL);
 	wglDeleteContext (hglrc);
 	ReleaseDC (hwnd, hdc);
-	PostQuitMessage (0);
 	UnregisterClass (ClassName, wc.hInstance);
 	return 0;
 }

[C] 纯文本查看 复制代码
#define UNICODE 1
#include <windows.h>
#include <GL/gl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
GLuint shaderProgram;
GLint iFrame, iFrameRate, iTime, iResolution, iMouse;
GLuint vertexArray;
GLfloat Time = 0, Resolution[2], Mouse[2];
const char* vertexShaderSource = "vec2 positions[4] = vec2[4] (vec2 (-1.0, 1.0),vec2 (-1.0, -1.0),vec2 (1.0, 1.0),vec2 (1.0, -1.0));void main() {gl_Position = vec4 (positions[gl_VertexID % 4], 0.0, 1.0);}";
char* buffer = NULL;
char* fragmentShaderSource = "uniform float iTime;uniform vec2 iResolution;uniform vec2 iMouse;void mainImage( out vec4 fragColor, in vec2 fragCoord ){vec2 uv = fragCoord.xy / iResolution;vec2 mousePos = iMouse.xy / iResolution.xy;if (length(uv - mousePos) < 0.01){fragColor = vec4(sin(iTime + uv.x * 10.0) * 0.5 + 0.5, 0.0, 0.0, 1.0);}else{fragColor = vec4(uv.x, uv.y, 0.0, 1.0);}}void main() {mainImage(gl_FragColor, gl_FragCoord.xy);}";
void CompileShader (const char* source, GLenum shaderType, GLuint* shader) {
	*shader = glCreateShader (shaderType);
	glShaderSource (*shader, 1, &source, NULL);
	glCompileShader (*shader);
	GLint success;
	glGetShaderiv (*shader, GL_COMPILE_STATUS, &success);
	if (!success) {
		char infoLog[512];
		glGetShaderInfoLog (*shader, 512, NULL, infoLog);
		MessageBoxA (NULL, infoLog, "Shader Compilation Error", MB_OK | MB_ICONERROR);
	}
}
int quit = 0;
void InitOpenGL() {
	GLuint vertexShader, fragmentShader;
	CompileShader (vertexShaderSource, GL_VERTEX_SHADER, &vertexShader);
	LPSTR cmdLine = GetCommandLineA();
	char* firstArgument = NULL;
	char* spacePos = strchr (cmdLine, ' ');
	if (spacePos != NULL && *spacePos != '\0') {
		*spacePos = '\0';
		firstArgument = spacePos + 1;
		spacePos = strchr (firstArgument, ' ');
		if (spacePos != NULL)
			*spacePos = '\0';
	}
	if (firstArgument != NULL && *firstArgument != '\0') {
		FILE* file = fopen (firstArgument, "r");
		if (file == NULL) {
			quit = 1;
			MessageBoxA (NULL, "Can't open the file!", "Error", MB_OK | MB_ICONERROR);
			return;
		}
		fseek (file, 0, SEEK_END);
		size_t fileSize = ftell (file);
		fseek (file, 0, SEEK_SET);
		buffer = (char*) malloc (fileSize + 1);
		fread (buffer, fileSize, 1, file);
		buffer[fileSize] = '\0';
		fclose (file);
		fragmentShaderSource = buffer;
	}
	CompileShader (fragmentShaderSource, GL_FRAGMENT_SHADER, &fragmentShader);
	shaderProgram = glCreateProgram();
	glAttachShader (shaderProgram, vertexShader);
	glAttachShader (shaderProgram, fragmentShader);
	glLinkProgram (shaderProgram);
	GLint success;
	glGetProgramiv (shaderProgram, GL_LINK_STATUS, &success);
	if (!success) {
		char infoLog[512];
		glGetProgramInfoLog (shaderProgram, 512, NULL, infoLog);
		MessageBoxA (NULL, infoLog, "Shader Linking Error", MB_OK | MB_ICONERROR);
		quit = 1;
		return;
	}
	glUseProgram (shaderProgram);
	iFrame = glGetUniformLocation (shaderProgram, "iFrame");
	iFrameRate = glGetUniformLocation (shaderProgram, "iFrameRate");
	iTime = glGetUniformLocation (shaderProgram, "iTime");
	iResolution = glGetUniformLocation (shaderProgram, "iResolution");
	iMouse = glGetUniformLocation (shaderProgram, "iMouse");
	glDeleteShader (vertexShader);
	glDeleteShader (fragmentShader);
	glGenVertexArrays (1, &vertexArray);
	glBindVertexArray (vertexArray);
}
void RenderScene() {
	static int Frame = 0;
	static float FrameRate = 0;
	Frame++;
	static int initNow = 0;
	static int lastNow = 0;
	LARGE_INTEGER counter;
	QueryPerformanceCounter (&counter);
	int now = counter.QuadPart;
	if (initNow == 0)
		initNow = now;
	now -= initNow;
	if (lastNow == 0)
		lastNow = now;
	if (now - lastNow > 10000000) {
		FrameRate = (float) Frame / ( (float) now / 10000000.0f);
		glUniform1f (iFrameRate, FrameRate);
		lastNow = now;
	}
	glUniform1f (iFrame, (float) Frame);
	glUniform1f (iTime, (float) now / 10000000.0f);
	glUniform2fv (iResolution, 1, &Resolution[0]);
	glUniform2fv (iMouse, 1, &Mouse[0]);
	glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
void QuitOpenGL() {
	if (buffer)
		free (buffer);
	glDeleteProgram (shaderProgram);
	glDeleteVertexArrays (1, &vertexArray);
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	switch (msg) {
		case WM_SIZE:
			GLint w = LOWORD (lParam), h = HIWORD (lParam);
			glViewport (0, 0, w, h);
			Resolution[0] = w;
			Resolution[1] = h;
			break;
		case WM_MOUSEMOVE:
			Mouse[0] = LOWORD (lParam);
			Mouse[1] = Resolution[1] - HIWORD (lParam);
			break;
		case WM_CLOSE:
			quit = 1;
			break;
		case WM_KEYDOWN:
			switch (wParam) {
				case VK_ESCAPE:
					quit = 1;
					break;
			}
		default:
			return DefWindowProc (hwnd, msg, wParam, lParam);
	}
	return 0;
}
#define ClassName TEXT("GL")
#ifdef UNICODE
int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
#else
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) {
#endif
	int screenWidth = GetSystemMetrics (SM_CXSCREEN);
	int screenHeight = GetSystemMetrics (SM_CYSCREEN);
	WNDCLASS wc = {0};
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = ClassName;
	wc.hCursor = LoadCursor (NULL, IDC_ARROW);
	if (!RegisterClass (&wc)) {
		MessageBoxA (NULL, "Window Registration Failed!", "Error", MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}
	HWND hwnd = CreateWindowEx (WS_EX_APPWINDOW, ClassName, ClassName, WS_POPUP, 0, 0, screenWidth, screenHeight, NULL, NULL, wc.hInstance, NULL);
	if (!hwnd) {
		MessageBoxA (NULL, "Window Creation Failed!", "Error", MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}
	PIXELFORMATDESCRIPTOR pfd = {
		sizeof (PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
		PFD_TYPE_RGBA,
		32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0
	};
	HDC hdc = GetDC (hwnd);
	int pf = ChoosePixelFormat (hdc, &pfd);
	SetPixelFormat (hdc, pf, &pfd);
	HGLRC hglrc = wglCreateContext (hdc);
	wglMakeCurrent (hdc, hglrc);
	InitOpenGL();
	MSG msg;
	ShowWindow (hwnd, SW_SHOWDEFAULT);
	while (!quit) {
		while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
			if (msg.message == WM_QUIT)
				quit = 1;
			TranslateMessage (&msg);
			DispatchMessage (&msg);
		}
		RenderScene();
		SwapBuffers (hdc);
	}
	QuitOpenGL();
	wglMakeCurrent (hdc, NULL);
	wglDeleteContext (hglrc);
	ReleaseDC (hwnd, hdc);
	UnregisterClass (ClassName, wc.hInstance);
	PostQuitMessage (0);
	return 0;
}

着色器源代码可以到www.shadertoy.com寻找移植

src.zip

20.48 KB, 下载次数: 7, 下载积分: 吾爱币 -1 CB

完整源代码与实例

免费评分

参与人数 2威望 +1 吾爱币 +21 热心值 +1 收起 理由
苏紫方璇 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ma4907758 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

sksun1983 发表于 2025-1-8 11:25
感谢楼主分享
mood100 发表于 2025-1-8 15:42
BrutusScipio 发表于 2025-1-8 15:58
OpenGL吗?不用引擎的话可以用win32API绘制,但应该是做不到着色器效果
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-10-22 18:45

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表